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 && !UPRV_INCOMPLETE_CPP11_SUPPORT
7#pragma once
8
9#include "number_stringbuilder.h"
10#include "intltest.h"
11#include "number_affixutils.h"
12
13using namespace icu::number;
14using namespace icu::number::impl;
15
16////////////////////////////////////////////////////////////////////////////////////////
17// INSTRUCTIONS:                                                                      //
18// To add new NumberFormat unit test classes, create a new class like the ones below, //
19// and then add it as a switch statement in NumberTest at the bottom of this file.    /////////
20// To add new methods to existing unit test classes, add the method to the class declaration //
21// below, and also add it to the class's implementation of runIndexedTest().                 //
22///////////////////////////////////////////////////////////////////////////////////////////////
23
24class AffixUtilsTest : public IntlTest {
25  public:
26    void testEscape();
27    void testUnescape();
28    void testContainsReplaceType();
29    void testInvalid();
30    void testUnescapeWithSymbolProvider();
31
32    void runIndexedTest(int32_t index, UBool exec, const char *&name, char *par = 0);
33
34  private:
35    UnicodeString unescapeWithDefaults(const SymbolProvider &defaultProvider, UnicodeString input,
36                                       UErrorCode &status);
37};
38
39class NumberFormatterApiTest : public IntlTest {
40  public:
41    NumberFormatterApiTest();
42    NumberFormatterApiTest(UErrorCode &status);
43
44    void notationSimple();
45    void notationScientific();
46    void notationCompact();
47    void unitMeasure();
48    void unitCurrency();
49    void unitPercent();
50    void roundingFraction();
51    void roundingFigures();
52    void roundingFractionFigures();
53    void roundingOther();
54    void grouping();
55    void padding();
56    void integerWidth();
57    void symbols();
58    // TODO: Add this method if currency symbols override support is added.
59    //void symbolsOverride();
60    void sign();
61    void decimal();
62    void locale();
63    void formatTypes();
64    void errors();
65
66    void runIndexedTest(int32_t index, UBool exec, const char *&name, char *par = 0);
67
68  private:
69    CurrencyUnit USD;
70    CurrencyUnit GBP;
71    CurrencyUnit CZK;
72    CurrencyUnit CAD;
73
74    MeasureUnit METER;
75    MeasureUnit DAY;
76    MeasureUnit SQUARE_METER;
77    MeasureUnit FAHRENHEIT;
78
79    NumberingSystem MATHSANB;
80    NumberingSystem LATN;
81
82    DecimalFormatSymbols FRENCH_SYMBOLS;
83    DecimalFormatSymbols SWISS_SYMBOLS;
84    DecimalFormatSymbols MYANMAR_SYMBOLS;
85
86    void assertFormatDescending(const UnicodeString &message, const UnlocalizedNumberFormatter &f,
87                                Locale locale, ...);
88
89    void assertFormatDescendingBig(const UnicodeString &message, const UnlocalizedNumberFormatter &f,
90                                   Locale locale, ...);
91
92    void assertFormatSingle(const UnicodeString &message, const UnlocalizedNumberFormatter &f,
93                            Locale locale, double input, const UnicodeString &expected);
94};
95
96class DecimalQuantityTest : public IntlTest {
97  public:
98    void testDecimalQuantityBehaviorStandalone();
99    void testSwitchStorage();
100    void testAppend();
101    void testConvertToAccurateDouble();
102    void testUseApproximateDoubleWhenAble();
103
104    void runIndexedTest(int32_t index, UBool exec, const char *&name, char *par = 0);
105
106  private:
107    void assertDoubleEquals(UnicodeString message, double a, double b);
108    void assertHealth(const DecimalQuantity &fq);
109    void assertToStringAndHealth(const DecimalQuantity &fq, const UnicodeString &expected);
110    void checkDoubleBehavior(double d, bool explicitRequired);
111};
112
113class ModifiersTest : public IntlTest {
114  public:
115    void testConstantAffixModifier();
116    void testConstantMultiFieldModifier();
117    void testSimpleModifier();
118    void testCurrencySpacingEnabledModifier();
119
120    void runIndexedTest(int32_t index, UBool exec, const char *&name, char *par = 0);
121
122  private:
123    void assertModifierEquals(const Modifier &mod, int32_t expectedPrefixLength, bool expectedStrong,
124                              UnicodeString expectedChars, UnicodeString expectedFields,
125                              UErrorCode &status);
126
127    void assertModifierEquals(const Modifier &mod, NumberStringBuilder &sb, int32_t expectedPrefixLength,
128                              bool expectedStrong, UnicodeString expectedChars,
129                              UnicodeString expectedFields, UErrorCode &status);
130};
131
132class PatternModifierTest : public IntlTest {
133  public:
134    void testBasic();
135    void testMutableEqualsImmutable();
136
137    void runIndexedTest(int32_t index, UBool exec, const char *&name, char *par = 0);
138
139  private:
140    UnicodeString getPrefix(const MutablePatternModifier &mod, UErrorCode &status);
141    UnicodeString getSuffix(const MutablePatternModifier &mod, UErrorCode &status);
142};
143
144class PatternStringTest : public IntlTest {
145  public:
146    void testToPatternSimple();
147    void testExceptionOnInvalid();
148    void testBug13117();
149
150    void runIndexedTest(int32_t index, UBool exec, const char *&name, char *par = 0);
151
152  private:
153};
154
155class NumberStringBuilderTest : public IntlTest {
156  public:
157    void testInsertAppendUnicodeString();
158    void testInsertAppendCodePoint();
159    void testCopy();
160    void testFields();
161    void testUnlimitedCapacity();
162    void testCodePoints();
163
164    void runIndexedTest(int32_t index, UBool exec, const char *&name, char *par = 0);
165
166  private:
167    void assertEqualsImpl(const UnicodeString &a, const NumberStringBuilder &b);
168};
169
170
171// NOTE: This macro is identical to the one in itformat.cpp
172#define TESTCLASS(id, TestClass)          \
173    case id:                              \
174        name = #TestClass;                \
175        if (exec) {                       \
176            logln(#TestClass " test---"); \
177            logln((UnicodeString)"");     \
178            TestClass test;               \
179            callTest(test, par);          \
180        }                                 \
181        break
182
183class NumberTest : public IntlTest {
184  public:
185    void runIndexedTest(int32_t index, UBool exec, const char *&name, char *par = 0) {
186        if (exec) {
187            logln("TestSuite NumberTest: ");
188        }
189
190        switch (index) {
191        TESTCLASS(0, AffixUtilsTest);
192        TESTCLASS(1, NumberFormatterApiTest);
193        TESTCLASS(2, DecimalQuantityTest);
194        TESTCLASS(3, ModifiersTest);
195        TESTCLASS(4, PatternModifierTest);
196        TESTCLASS(5, PatternStringTest);
197        TESTCLASS(6, NumberStringBuilderTest);
198        default: name = ""; break; // needed to end loop
199        }
200    }
201};
202
203#endif /* #if !UCONFIG_NO_FORMATTING */
204