• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 *******************************************************************************
3 * Copyright (C) 1997-2013, International Business Machines Corporation and    *
4 * others. All Rights Reserved.                                                *
5 *******************************************************************************
6 *
7 * File COMPACTDECIMALFORMATTEST.CPP
8 *
9 ********************************************************************************
10 */
11 #include <stdio.h>
12 #include <stdlib.h>
13 
14 #include "intltest.h"
15 
16 #if !UCONFIG_NO_FORMATTING
17 
18 #include "unicode/compactdecimalformat.h"
19 #include "unicode/unum.h"
20 
21 #define LENGTHOF(array) (int32_t)(sizeof(array) / sizeof((array)[0]))
22 
23 typedef struct ExpectedResult {
24   double value;
25   const char *expected;
26 } ExpectedResult;
27 
28 static const char *kShortStr = "Short";
29 static const char *kLongStr = "Long";
30 
31 static ExpectedResult kEnglishShort[] = {
32   {0.0, "0"},
33   {0.17, "0.17"},
34   {1.0, "1"},
35   {1234.0, "1.2K"},
36   {12345.0, "12K"},
37   {123456.0, "120K"},
38   {1234567.0, "1.2M"},
39   {12345678.0, "12M"},
40   {123456789.0, "120M"},
41   {1.23456789E9, "1.2B"},
42   {1.23456789E10, "12B"},
43   {1.23456789E11, "120B"},
44   {1.23456789E12, "1.2T"},
45   {1.23456789E13, "12T"},
46   {1.23456789E14, "120T"},
47   {1.23456789E15, "1200T"}};
48 
49 static ExpectedResult kSerbianShort[] = {
50   {1234.0, "1200"},
51   {12345.0, "12\\u00a0\\u0445\\u0438\\u0459"},
52   {20789.0, "21\\u00a0\\u0445\\u0438\\u0459"},
53   {123456.0, "120\\u00a0\\u0445\\u0438\\u0459"},
54   {1234567.0, "1,2\\u00A0\\u043C\\u0438\\u043B"},
55   {12345678.0, "12\\u00A0\\u043C\\u0438\\u043B"},
56   {123456789.0, "120\\u00A0\\u043C\\u0438\\u043B"},
57   {1.23456789E9, "1,2\\u00A0\\u043C\\u043B\\u0440\\u0434"},
58   {1.23456789E10, "12\\u00A0\\u043C\\u043B\\u0440\\u0434"},
59   {1.23456789E11, "120\\u00A0\\u043C\\u043B\\u0440\\u0434"},
60   {1.23456789E12, "1,2\\u00A0\\u0431\\u0438\\u043B"},
61   {1.23456789E13, "12\\u00A0\\u0431\\u0438\\u043B"},
62   {1.23456789E14, "120\\u00A0\\u0431\\u0438\\u043B"},
63   {1.23456789E15, "1200\\u00A0\\u0431\\u0438\\u043B"}};
64 
65 static ExpectedResult kSerbianLong[] = {
66   {1234.0, "1,2 \\u0445\\u0438\\u0459\\u0430\\u0434\\u0435"}, // 10^3 few
67   {12345.0, "12 \\u0445\\u0438\\u0459\\u0430\\u0434\\u0430"}, // 10^3 other
68   {21789.0, "22 \\u0445\\u0438\\u0459\\u0430\\u0434\\u0435"}, // 10^3 few
69   {123456.0, "120 \\u0445\\u0438\\u0459\\u0430\\u0434\\u0430"}, // 10^3 other
70   {999999.0, "1 \\u043C\\u0438\\u043B\\u0438\\u043E\\u043D"}, // 10^6 one
71   {1234567.0, "1,2 \\u043C\\u0438\\u043B\\u0438\\u043E\\u043D\\u0430"}, // 10^6 few
72   {12345678.0, "12 \\u043C\\u0438\\u043B\\u0438\\u043E\\u043D\\u0430"}, // 10^6 other
73   {123456789.0, "120 \\u043C\\u0438\\u043B\\u0438\\u043E\\u043D\\u0430"}, // 10^6 other
74   {1.23456789E9, "1,2 \\u043C\\u0438\\u043B\\u0438\\u0458\\u0430\\u0440\\u0434\\u0435"}, // 10^9 few
75   {1.23456789E10, "12 \\u043C\\u0438\\u043B\\u0438\\u0458\\u0430\\u0440\\u0434\\u0438"}, // 10^9 other
76   {2.08901234E10, "21 \\u043C\\u0438\\u043B\\u0438\\u0458\\u0430\\u0440\\u0434\\u0430"}, // 10^9 one
77   {2.18901234E10, "22 \\u043C\\u0438\\u043B\\u0438\\u0458\\u0430\\u0440\\u0434\\u0435"}, // 10^9 few
78   {1.23456789E11, "120 \\u043C\\u0438\\u043B\\u0438\\u0458\\u0430\\u0440\\u0434\\u0438"}, // 10^9 other
79   {1.23456789E12, "1,2 \\u0442\\u0440\\u0438\\u043B\\u0438\\u043E\\u043D\\u0430"}, // 10^12 few
80   {1.23456789E13, "12 \\u0442\\u0440\\u0438\\u043B\\u0438\\u043E\\u043D\\u0430"}, // 10^12 other
81   {1.23456789E14, "120 \\u0442\\u0440\\u0438\\u043B\\u0438\\u043E\\u043D\\u0430"}, // 10^12 other
82   {1.23456789E15, "1200 \\u0442\\u0440\\u0438\\u043B\\u0438\\u043E\\u043D\\u0430"}}; // 10^12 other
83 
84 static ExpectedResult kSerbianLongNegative[] = {
85   {-1234.0, "-1,2 \\u0445\\u0438\\u0459\\u0430\\u0434\\u0435"},
86   {-12345.0, "-12 \\u0445\\u0438\\u0459\\u0430\\u0434\\u0430"},
87   {-21789.0, "-22 \\u0445\\u0438\\u0459\\u0430\\u0434\\u0435"},
88   {-123456.0, "-120 \\u0445\\u0438\\u0459\\u0430\\u0434\\u0430"},
89   {-999999.0, "-1 \\u043C\\u0438\\u043B\\u0438\\u043E\\u043D"},
90   {-1234567.0, "-1,2 \\u043C\\u0438\\u043B\\u0438\\u043E\\u043D\\u0430"},
91   {-12345678.0, "-12 \\u043C\\u0438\\u043B\\u0438\\u043E\\u043D\\u0430"},
92   {-123456789.0, "-120 \\u043C\\u0438\\u043B\\u0438\\u043E\\u043D\\u0430"},
93   {-1.23456789E9, "-1,2 \\u043C\\u0438\\u043B\\u0438\\u0458\\u0430\\u0440\\u0434\\u0435"},
94   {-1.23456789E10, "-12 \\u043C\\u0438\\u043B\\u0438\\u0458\\u0430\\u0440\\u0434\\u0438"},
95   {-2.08901234E10, "-21 \\u043C\\u0438\\u043B\\u0438\\u0458\\u0430\\u0440\\u0434\\u0430"},
96   {-2.18901234E10, "-22 \\u043C\\u0438\\u043B\\u0438\\u0458\\u0430\\u0440\\u0434\\u0435"},
97   {-1.23456789E11, "-120 \\u043C\\u0438\\u043B\\u0438\\u0458\\u0430\\u0440\\u0434\\u0438"},
98   {-1.23456789E12, "-1,2 \\u0442\\u0440\\u0438\\u043B\\u0438\\u043E\\u043D\\u0430"},
99   {-1.23456789E13, "-12 \\u0442\\u0440\\u0438\\u043B\\u0438\\u043E\\u043D\\u0430"},
100   {-1.23456789E14, "-120 \\u0442\\u0440\\u0438\\u043B\\u0438\\u043E\\u043D\\u0430"},
101   {-1.23456789E15, "-1200 \\u0442\\u0440\\u0438\\u043B\\u0438\\u043E\\u043D\\u0430"}};
102 
103 static ExpectedResult kJapaneseShort[] = {
104   {1234.0, "1.2\\u5343"},
105   {12345.0, "1.2\\u4E07"},
106   {123456.0, "12\\u4E07"},
107   {1234567.0, "120\\u4E07"},
108   {12345678.0, "1200\\u4E07"},
109   {123456789.0, "1.2\\u5104"},
110   {1.23456789E9, "12\\u5104"},
111   {1.23456789E10, "120\\u5104"},
112   {1.23456789E11, "1200\\u5104"},
113   {1.23456789E12, "1.2\\u5146"},
114   {1.23456789E13, "12\\u5146"},
115   {1.23456789E14, "120\\u5146"}};
116 
117 static ExpectedResult kSwahiliShort[] = {
118   {1234.0, "elfu\\u00a01.2"},
119   {12345.0, "elfu\\u00a012"},
120   {123456.0, "laki1.2"},
121   {1234567.0, "M1.2"},
122   {12345678.0, "M12"},
123   {123456789.0, "M120"},
124   {1.23456789E9, "B1.2"},
125   {1.23456789E10, "B12"},
126   {1.23456789E11, "B120"},
127   {1.23456789E12, "T1.2"},
128   {1.23456789E13, "T12"},
129   {1.23456789E15, "T1200"}};
130 
131 static ExpectedResult kCsShort[] = {
132   {1000.0, "1\\u00a0tis."},
133   {1500.0, "1,5\\u00a0tis."},
134   {5000.0, "5\\u00a0tis."},
135   {23000.0, "23\\u00a0tis."},
136   {127123.0, "130\\u00a0tis."},
137   {1271234.0, "1,3\\u00a0mil."},
138   {12712345.0, "13\\u00a0mil."},
139   {127123456.0, "130\\u00a0mil."},
140   {1.27123456E9, "1,3\\u00a0mld."},
141   {1.27123456E10, "13\\u00a0mld."},
142   {1.27123456E11, "130\\u00a0mld."},
143   {1.27123456E12, "1,3\\u00a0bil."},
144   {1.27123456E13, "13\\u00a0bil."},
145   {1.27123456E14, "130\\u00a0bil."}};
146 
147 static ExpectedResult kSkLong[] = {
148   {1000.0, "1 tis\\u00edc"},
149   {1572.0, "1,6 tis\\u00edc"},
150   {5184.0, "5,2 tis\\u00edc"}};
151 
152 static ExpectedResult kSwahiliShortNegative[] = {
153   {-1234.0, "elfu\\u00a0-1.2"},
154   {-12345.0, "elfu\\u00a0-12"},
155   {-123456.0, "laki-1.2"},
156   {-1234567.0, "M-1.2"},
157   {-12345678.0, "M-12"},
158   {-123456789.0, "M-120"},
159   {-1.23456789E9, "B-1.2"},
160   {-1.23456789E10, "B-12"},
161   {-1.23456789E11, "B-120"},
162   {-1.23456789E12, "T-1.2"},
163   {-1.23456789E13, "T-12"},
164   {-1.23456789E15, "T-1200"}};
165 
166 static ExpectedResult kArabicLong[] = {
167   {-5300.0, "\\u200F-\\u0665\\u066B\\u0663 \\u0623\\u0644\\u0641"}};
168 
169 
170 class CompactDecimalFormatTest : public IntlTest {
171 public:
CompactDecimalFormatTest()172     CompactDecimalFormatTest() {
173     }
174 
175     void runIndexedTest(int32_t index, UBool exec, const char *&name, char *par=0);
176 private:
177     void TestEnglishShort();
178     void TestSerbianShort();
179     void TestSerbianLong();
180     void TestSerbianLongNegative();
181     void TestJapaneseShort();
182     void TestSwahiliShort();
183     void TestCsShort();
184     void TestSkLong();
185     void TestSwahiliShortNegative();
186     void TestArabicLong();
187     void TestFieldPosition();
188     void TestSignificantDigits();
189     void CheckLocale(
190         const Locale& locale, UNumberCompactStyle style,
191         const ExpectedResult* expectedResult, int32_t expectedResultLength);
192     void CheckExpectedResult(
193         const CompactDecimalFormat* cdf, const ExpectedResult* expectedResult,
194         const char* description);
195     CompactDecimalFormat* createCDFInstance(const Locale& locale, UNumberCompactStyle style, UErrorCode& status);
196     static const char *StyleStr(UNumberCompactStyle style);
197 };
198 
runIndexedTest(int32_t index,UBool exec,const char * & name,char *)199 void CompactDecimalFormatTest::runIndexedTest(
200     int32_t index, UBool exec, const char *&name, char *) {
201   if (exec) {
202     logln("TestSuite CompactDecimalFormatTest: ");
203   }
204   TESTCASE_AUTO_BEGIN;
205   TESTCASE_AUTO(TestEnglishShort);
206   TESTCASE_AUTO(TestSerbianShort);
207   TESTCASE_AUTO(TestSerbianLong);
208   TESTCASE_AUTO(TestSerbianLongNegative);
209   TESTCASE_AUTO(TestJapaneseShort);
210   TESTCASE_AUTO(TestSwahiliShort);
211   TESTCASE_AUTO(TestCsShort);
212   TESTCASE_AUTO(TestSkLong);
213   TESTCASE_AUTO(TestSwahiliShortNegative);
214   TESTCASE_AUTO(TestArabicLong);
215   TESTCASE_AUTO(TestFieldPosition);
216   TESTCASE_AUTO(TestSignificantDigits);
217   TESTCASE_AUTO_END;
218 }
219 
TestEnglishShort()220 void CompactDecimalFormatTest::TestEnglishShort() {
221   CheckLocale("en", UNUM_SHORT, kEnglishShort, LENGTHOF(kEnglishShort));
222 }
223 
TestSerbianShort()224 void CompactDecimalFormatTest::TestSerbianShort() {
225   CheckLocale("sr", UNUM_SHORT, kSerbianShort, LENGTHOF(kSerbianShort));
226 }
227 
TestSerbianLong()228 void CompactDecimalFormatTest::TestSerbianLong() {
229   CheckLocale("sr", UNUM_LONG, kSerbianLong, LENGTHOF(kSerbianLong));
230 }
231 
TestSerbianLongNegative()232 void CompactDecimalFormatTest::TestSerbianLongNegative() {
233   CheckLocale("sr", UNUM_LONG, kSerbianLongNegative, LENGTHOF(kSerbianLongNegative));
234 }
235 
TestJapaneseShort()236 void CompactDecimalFormatTest::TestJapaneseShort() {
237   CheckLocale(Locale::getJapan(), UNUM_SHORT, kJapaneseShort, LENGTHOF(kJapaneseShort));
238 }
239 
TestSwahiliShort()240 void CompactDecimalFormatTest::TestSwahiliShort() {
241   CheckLocale("sw", UNUM_SHORT, kSwahiliShort, LENGTHOF(kSwahiliShort));
242 }
243 
TestFieldPosition()244 void CompactDecimalFormatTest::TestFieldPosition() {
245   // Swahili uses prefixes which forces offsets in field position to change
246   UErrorCode status = U_ZERO_ERROR;
247   LocalPointer<CompactDecimalFormat> cdf(createCDFInstance("sw", UNUM_SHORT, status));
248   if (U_FAILURE(status)) {
249     dataerrln("Unable to create format object - %s", u_errorName(status));
250     return;
251   }
252   FieldPosition fp(UNUM_INTEGER_FIELD);
253   UnicodeString result;
254   cdf->format(1234567.0, result, fp);
255   UnicodeString subString = result.tempSubString(fp.getBeginIndex(), fp.getEndIndex() - fp.getBeginIndex());
256   if (subString != UnicodeString("1", -1, US_INV)) {
257     errln(UnicodeString("Expected 1, got ") + subString);
258   }
259 }
260 
TestCsShort()261 void CompactDecimalFormatTest::TestCsShort() {
262   CheckLocale("cs", UNUM_SHORT, kCsShort, LENGTHOF(kCsShort));
263 }
264 
TestSkLong()265 void CompactDecimalFormatTest::TestSkLong() {
266   // In CLDR we have:
267   // 1000 {
268   //   few{"0"}
269   //   one{"0"}
270   //   other{"0"}
271   CheckLocale("sk", UNUM_LONG, kSkLong, LENGTHOF(kSkLong));
272 }
273 
TestSwahiliShortNegative()274 void CompactDecimalFormatTest::TestSwahiliShortNegative() {
275   CheckLocale("sw", UNUM_SHORT, kSwahiliShortNegative, LENGTHOF(kSwahiliShortNegative));
276 }
277 
TestArabicLong()278 void CompactDecimalFormatTest::TestArabicLong() {
279   CheckLocale("ar", UNUM_LONG, kArabicLong, LENGTHOF(kArabicLong));
280 }
281 
TestSignificantDigits()282 void CompactDecimalFormatTest::TestSignificantDigits() {
283   UErrorCode status = U_ZERO_ERROR;
284   LocalPointer<CompactDecimalFormat> cdf(CompactDecimalFormat::createInstance("en", UNUM_SHORT, status));
285   if (U_FAILURE(status)) {
286     dataerrln("Unable to create format object - %s", u_errorName(status));
287     return;
288   }
289   UnicodeString actual;
290   cdf->format(123456.0, actual);
291   // We expect 3 significant digits by default
292   UnicodeString expected("123K", -1, US_INV);
293   if (actual != expected) {
294     errln(UnicodeString("Fail: Expected: ") + expected + UnicodeString(" Got: ") + actual);
295   }
296 }
297 
CheckLocale(const Locale & locale,UNumberCompactStyle style,const ExpectedResult * expectedResults,int32_t expectedResultLength)298 void CompactDecimalFormatTest::CheckLocale(const Locale& locale, UNumberCompactStyle style, const ExpectedResult* expectedResults, int32_t expectedResultLength) {
299   UErrorCode status = U_ZERO_ERROR;
300   LocalPointer<CompactDecimalFormat> cdf(createCDFInstance(locale, style, status));
301   if (U_FAILURE(status)) {
302     dataerrln("Unable to create format object - %s", u_errorName(status));
303     return;
304   }
305   char description[256];
306   sprintf(description,"%s - %s", locale.getName(), StyleStr(style));
307   for (int32_t i = 0; i < expectedResultLength; i++) {
308     CheckExpectedResult(cdf.getAlias(), &expectedResults[i], description);
309   }
310 }
311 
CheckExpectedResult(const CompactDecimalFormat * cdf,const ExpectedResult * expectedResult,const char * description)312 void CompactDecimalFormatTest::CheckExpectedResult(
313     const CompactDecimalFormat* cdf, const ExpectedResult* expectedResult, const char* description) {
314   UnicodeString actual;
315   cdf->format(expectedResult->value, actual);
316   UnicodeString expected(expectedResult->expected, -1, US_INV);
317   expected = expected.unescape();
318   if (actual != expected) {
319     errln(UnicodeString("Fail: Expected: ") + expected
320           + UnicodeString(" Got: ") + actual
321           + UnicodeString(" for: ") + UnicodeString(description));
322   }
323 }
324 
325 CompactDecimalFormat*
createCDFInstance(const Locale & locale,UNumberCompactStyle style,UErrorCode & status)326 CompactDecimalFormatTest::createCDFInstance(const Locale& locale, UNumberCompactStyle style, UErrorCode& status) {
327   CompactDecimalFormat* result = CompactDecimalFormat::createInstance(locale, style, status);
328   if (U_FAILURE(status)) {
329     return NULL;
330   }
331   // All tests are written for two significant digits, so we explicitly set here
332   // in case default significant digits change.
333   result->setMaximumSignificantDigits(2);
334   return result;
335 }
336 
StyleStr(UNumberCompactStyle style)337 const char *CompactDecimalFormatTest::StyleStr(UNumberCompactStyle style) {
338   if (style == UNUM_SHORT) {
339     return kShortStr;
340   }
341   return kLongStr;
342 }
343 
createCompactDecimalFormatTest()344 extern IntlTest *createCompactDecimalFormatTest() {
345   return new CompactDecimalFormatTest();
346 }
347 
348 #endif
349