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