1 // Copyright (C) 2016 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html
4 *******************************************************************************
5 * Copyright (C) 1997-2015, International Business Machines Corporation and *
6 * others. All Rights Reserved. *
7 *******************************************************************************
9 * File COMPACTDECIMALFORMATTEST.CPP
11 ********************************************************************************
18 #if !UCONFIG_NO_FORMATTING
20 #include "unicode/compactdecimalformat.h"
21 #include "unicode/unum.h"
24 typedef struct ExpectedResult {
29 static const char *kShortStr = "Short";
30 static const char *kLongStr = "Long";
32 static ExpectedResult kEnglishShort[] = {
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"}};
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."}};
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
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"}};
104 static ExpectedResult kJapaneseShort[] = {
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"}};
118 static ExpectedResult kSwahiliShort[] = {
119 {1234.0, "elfu\\u00a01.2"},
120 {12345.0, "elfu\\u00a012"},
121 {123456.0, "elfu\\u00a0120"},
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"}};
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."}};
148 static ExpectedResult kSkLong[] = {
149 {1000.0, "1 tis\\u00edc"},
150 {1572.0, "1,6 tis\\u00edca"},
151 {5184.0, "5,2 tis\\u00edca"}};
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"}};
167 static ExpectedResult kArabicLong[] = {
168 {-5300.0, "\\u061C-\\u0665\\u066B\\u0663 \\u0623\\u0644\\u0641"}};
171 class CompactDecimalFormatTest : public IntlTest {
173 CompactDecimalFormatTest() {
176 void runIndexedTest(int32_t index, UBool exec, const char *&name, char *par=0);
178 void TestEnglishShort();
179 void TestSerbianShort();
180 void TestSerbianLong();
181 void TestSerbianLongNegative();
182 void TestJapaneseShort();
183 void TestSwahiliShort();
186 void TestSwahiliShortNegative();
187 void TestArabicLong();
188 void TestFieldPosition();
189 void TestSignificantDigits();
190 void TestAPIVariants();
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);
201 void CompactDecimalFormatTest::runIndexedTest(
202 int32_t index, UBool exec, const char *&name, char *) {
204 logln("TestSuite CompactDecimalFormatTest: ");
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);
223 void CompactDecimalFormatTest::TestEnglishShort() {
224 CheckLocale("en", UNUM_SHORT, kEnglishShort, UPRV_LENGTHOF(kEnglishShort));
227 void CompactDecimalFormatTest::TestSerbianShort() {
228 CheckLocale("sr", UNUM_SHORT, kSerbianShort, UPRV_LENGTHOF(kSerbianShort));
231 void CompactDecimalFormatTest::TestSerbianLong() {
232 CheckLocale("sr", UNUM_LONG, kSerbianLong, UPRV_LENGTHOF(kSerbianLong));
235 void CompactDecimalFormatTest::TestSerbianLongNegative() {
236 CheckLocale("sr", UNUM_LONG, kSerbianLongNegative, UPRV_LENGTHOF(kSerbianLongNegative));
239 void CompactDecimalFormatTest::TestJapaneseShort() {
240 CheckLocale(Locale::getJapan(), UNUM_SHORT, kJapaneseShort, UPRV_LENGTHOF(kJapaneseShort));
243 void CompactDecimalFormatTest::TestSwahiliShort() {
244 CheckLocale("sw", UNUM_SHORT, kSwahiliShort, UPRV_LENGTHOF(kSwahiliShort));
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));
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);
264 void CompactDecimalFormatTest::TestCsShort() {
265 CheckLocale("cs", UNUM_SHORT, kCsShort, UPRV_LENGTHOF(kCsShort));
268 void CompactDecimalFormatTest::TestSkLong() {
274 CheckLocale("sk", UNUM_LONG, kSkLong, UPRV_LENGTHOF(kSkLong));
277 void CompactDecimalFormatTest::TestSwahiliShortNegative() {
278 CheckLocale("sw", UNUM_SHORT, kSwahiliShortNegative, UPRV_LENGTHOF(kSwahiliShortNegative));
281 void CompactDecimalFormatTest::TestArabicLong() {
282 CheckLocale("ar", UNUM_LONG, kArabicLong, UPRV_LENGTHOF(kArabicLong));
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));
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);
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));
308 UnicodeString actual;
310 FieldPositionIterator posIter;
311 UnicodeString expected("123K", -1, US_INV);
312 pos.setField(UNUM_INTEGER_FIELD);
315 pos.setBeginIndex(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());
324 pos.setBeginIndex(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));
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));
342 pos.setBeginIndex(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());
351 pos.setBeginIndex(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));
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));
369 pos.setBeginIndex(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());
378 pos.setBeginIndex(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));
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));
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));
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);
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));
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)) {
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);
436 const char *CompactDecimalFormatTest::StyleStr(UNumberCompactStyle style) {
437 if (style == UNUM_SHORT) {
443 extern IntlTest *createCompactDecimalFormatTest() {
444 return new CompactDecimalFormatTest();