1 // © 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();