1 // © 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 namespace {
25
26 typedef struct ExpectedResult {
27 double value;
28 // Invariant characters, will be converted to UTF-16 and then unescaped.
29 const char *expected;
30 } ExpectedResult;
31
32 const char* kShortStr = "Short";
33 const char* kLongStr = "Long";
34
35 ExpectedResult kEnglishShort[] = {
36 {0.0, "0"},
37 {0.17, "0.17"},
38 {1.0, "1"},
39 {1234.0, "1.2K"},
40 {12345.0, "12K"},
41 {123456.0, "120K"},
42 {1234567.0, "1.2M"},
43 {12345678.0, "12M"},
44 {123456789.0, "120M"},
45 {1.23456789E9, "1.2B"},
46 {1.23456789E10, "12B"},
47 {1.23456789E11, "120B"},
48 {1.23456789E12, "1.2T"},
49 {1.23456789E13, "12T"},
50 {1.23456789E14, "120T"},
51 {1.23456789E15, "1200T"}};
52
53 ExpectedResult kSerbianShort[] = {
54 {1234.0, "1,2\\u00a0\\u0445\\u0438\\u0459."},
55 {12345.0, "12\\u00a0\\u0445\\u0438\\u0459."},
56 {20789.0, "21\\u00a0\\u0445\\u0438\\u0459."},
57 {123456.0, "120\\u00a0\\u0445\\u0438\\u0459."},
58 {1234567.0, "1,2\\u00A0\\u043C\\u0438\\u043B."},
59 {12345678.0, "12\\u00A0\\u043C\\u0438\\u043B."},
60 {123456789.0, "120\\u00A0\\u043C\\u0438\\u043B."},
61 {1.23456789E9, "1,2\\u00A0\\u043C\\u043B\\u0440\\u0434."},
62 {1.23456789E10, "12\\u00A0\\u043C\\u043B\\u0440\\u0434."},
63 {1.23456789E11, "120\\u00A0\\u043C\\u043B\\u0440\\u0434."},
64 {1.23456789E12, "1,2\\u00A0\\u0431\\u0438\\u043B."},
65 {1.23456789E13, "12\\u00A0\\u0431\\u0438\\u043B."},
66 {1.23456789E14, "120\\u00A0\\u0431\\u0438\\u043B."},
67 {1.23456789E15, "1200\\u00A0\\u0431\\u0438\\u043B."}};
68
69 ExpectedResult kSerbianLong[] = {
70 {1234.0, "1,2 \\u0445\\u0438\\u0459\\u0430\\u0434\\u0435"}, // 10^3 few
71 {12345.0, "12 \\u0445\\u0438\\u0459\\u0430\\u0434\\u0430"}, // 10^3 other
72 {21789.0, "22 \\u0445\\u0438\\u0459\\u0430\\u0434\\u0435"}, // 10^3 few
73 {123456.0, "120 \\u0445\\u0438\\u0459\\u0430\\u0434\\u0430"}, // 10^3 other
74 {999999.0, "1 \\u043C\\u0438\\u043B\\u0438\\u043E\\u043D"}, // 10^6 one
75 {1234567.0, "1,2 \\u043C\\u0438\\u043B\\u0438\\u043E\\u043D\\u0430"}, // 10^6 few
76 {12345678.0, "12 \\u043C\\u0438\\u043B\\u0438\\u043E\\u043D\\u0430"}, // 10^6 other
77 {123456789.0, "120 \\u043C\\u0438\\u043B\\u0438\\u043E\\u043D\\u0430"}, // 10^6 other
78 {1.23456789E9, "1,2 \\u043C\\u0438\\u043B\\u0438\\u0458\\u0430\\u0440\\u0434\\u0435"}, // 10^9 few
79 {1.23456789E10, "12 \\u043C\\u0438\\u043B\\u0438\\u0458\\u0430\\u0440\\u0434\\u0438"}, // 10^9 other
80 {2.08901234E10, "21 \\u043C\\u0438\\u043B\\u0438\\u0458\\u0430\\u0440\\u0434\\u0430"}, // 10^9 one
81 {2.18901234E10, "22 \\u043C\\u0438\\u043B\\u0438\\u0458\\u0430\\u0440\\u0434\\u0435"}, // 10^9 few
82 {1.23456789E11, "120 \\u043C\\u0438\\u043B\\u0438\\u0458\\u0430\\u0440\\u0434\\u0438"}, // 10^9 other
83 {1.23456789E12, "1,2 \\u0431\\u0438\\u043B\\u0438\\u043E\\u043D\\u0430"}, // 10^12 few
84 {1.23456789E13, "12 \\u0431\\u0438\\u043B\\u0438\\u043E\\u043D\\u0430"}, // 10^12 other
85 {1.23456789E14, "120 \\u0431\\u0438\\u043B\\u0438\\u043E\\u043D\\u0430"}, // 10^12 other
86 {1.23456789E15, "1200 \\u0431\\u0438\\u043B\\u0438\\u043E\\u043D\\u0430"}}; // 10^12 other
87
88 ExpectedResult kSerbianLongNegative[] = {
89 {-1234.0, "-1,2 \\u0445\\u0438\\u0459\\u0430\\u0434\\u0435"},
90 {-12345.0, "-12 \\u0445\\u0438\\u0459\\u0430\\u0434\\u0430"},
91 {-21789.0, "-22 \\u0445\\u0438\\u0459\\u0430\\u0434\\u0435"},
92 {-123456.0, "-120 \\u0445\\u0438\\u0459\\u0430\\u0434\\u0430"},
93 {-999999.0, "-1 \\u043C\\u0438\\u043B\\u0438\\u043E\\u043D"},
94 {-1234567.0, "-1,2 \\u043C\\u0438\\u043B\\u0438\\u043E\\u043D\\u0430"},
95 {-12345678.0, "-12 \\u043C\\u0438\\u043B\\u0438\\u043E\\u043D\\u0430"},
96 {-123456789.0, "-120 \\u043C\\u0438\\u043B\\u0438\\u043E\\u043D\\u0430"},
97 {-1.23456789E9, "-1,2 \\u043C\\u0438\\u043B\\u0438\\u0458\\u0430\\u0440\\u0434\\u0435"},
98 {-1.23456789E10, "-12 \\u043C\\u0438\\u043B\\u0438\\u0458\\u0430\\u0440\\u0434\\u0438"},
99 {-2.08901234E10, "-21 \\u043C\\u0438\\u043B\\u0438\\u0458\\u0430\\u0440\\u0434\\u0430"},
100 {-2.18901234E10, "-22 \\u043C\\u0438\\u043B\\u0438\\u0458\\u0430\\u0440\\u0434\\u0435"},
101 {-1.23456789E11, "-120 \\u043C\\u0438\\u043B\\u0438\\u0458\\u0430\\u0440\\u0434\\u0438"},
102 {-1.23456789E12, "-1,2 \\u0431\\u0438\\u043B\\u0438\\u043E\\u043D\\u0430"},
103 {-1.23456789E13, "-12 \\u0431\\u0438\\u043B\\u0438\\u043E\\u043D\\u0430"},
104 {-1.23456789E14, "-120 \\u0431\\u0438\\u043B\\u0438\\u043E\\u043D\\u0430"},
105 {-1.23456789E15, "-1200 \\u0431\\u0438\\u043B\\u0438\\u043E\\u043D\\u0430"}};
106
107 ExpectedResult kJapaneseShort[] = {
108 {1234.0, "1200"},
109 {12345.0, "1.2\\u4E07"},
110 {123456.0, "12\\u4E07"},
111 {1234567.0, "120\\u4E07"},
112 {12345678.0, "1200\\u4E07"},
113 {123456789.0, "1.2\\u5104"},
114 {1.23456789E9, "12\\u5104"},
115 {1.23456789E10, "120\\u5104"},
116 {1.23456789E11, "1200\\u5104"},
117 {1.23456789E12, "1.2\\u5146"},
118 {1.23456789E13, "12\\u5146"},
119 {1.23456789E14, "120\\u5146"},
120 {1.23456789E15, "1200\\u5146"},
121 {1.23456789E16, "1.2\\u4EAC"},
122 {1.23456789E17, "12\\u4EAC"},
123 {1.23456789E18, "120\\u4EAC"},
124 {1.23456789E19, "1200\\u4EAC"}};
125
126 ExpectedResult kSwahiliShort[] = {
127 {1234.0, "elfu\\u00a01.2"},
128 {12345.0, "elfu\\u00a012"},
129 {123456.0, "elfu\\u00a0120"},
130 {1234567.0, "1.2M"},
131 {12345678.0, "12M"},
132 {123456789.0, "120M"},
133 {1.23456789E9, "1.2B"},
134 {1.23456789E10, "12B"},
135 {1.23456789E11, "120B"},
136 {1.23456789E12, "1.2T"},
137 {1.23456789E13, "12T"},
138 {1.23456789E15, "1200T"}};
139
140 ExpectedResult kCsShort[] = {
141 {1000.0, "1\\u00a0tis."},
142 {1500.0, "1,5\\u00a0tis."},
143 {5000.0, "5\\u00a0tis."},
144 {23000.0, "23\\u00a0tis."},
145 {127123.0, "130\\u00a0tis."},
146 {1271234.0, "1,3\\u00a0mil."},
147 {12712345.0, "13\\u00a0mil."},
148 {127123456.0, "130\\u00a0mil."},
149 {1.27123456E9, "1,3\\u00a0mld."},
150 {1.27123456E10, "13\\u00a0mld."},
151 {1.27123456E11, "130\\u00a0mld."},
152 {1.27123456E12, "1,3\\u00a0bil."},
153 {1.27123456E13, "13\\u00a0bil."},
154 {1.27123456E14, "130\\u00a0bil."}};
155
156 ExpectedResult kSkLong[] = {
157 {1000.0, "1 tis\\u00edc"},
158 {1572.0, "1,6 tis\\u00edca"},
159 {5184.0, "5,2 tis\\u00edca"}};
160
161 ExpectedResult kSwahiliShortNegative[] = {
162 {-1234.0, "elfu\\u00a0-1.2"},
163 {-12345.0, "elfu\\u00a0-12"},
164 {-123456.0, "elfu\\u00a0-120"},
165 {-1234567.0, "-1.2M"},
166 {-12345678.0, "-12M"},
167 {-123456789.0, "-120M"},
168 {-1.23456789E9, "-1.2B"},
169 {-1.23456789E10, "-12B"},
170 {-1.23456789E11, "-120B"},
171 {-1.23456789E12, "-1.2T"},
172 {-1.23456789E13, "-12T"},
173 {-1.23456789E15, "-1200T"}};
174
175 ExpectedResult kArabicLong[] = {
176 {-5300.0, "\\u061C-\\u0665\\u066B\\u0663 \\u0623\\u0644\\u0641"}};
177
178 ExpectedResult kChineseCurrencyTestData[] = {
179 {1.0, "\\u00A51"},
180 {12.0, "\\u00A512"},
181 {123.0, "\\u00A5120"},
182 {1234.0, "\\u00A51200"},
183 {12345.0, "\\u00A51.2\\u4E07"},
184 {123456.0, "\\u00A512\\u4E07"},
185 {1234567.0, "\\u00A5120\\u4E07"},
186 {12345678.0, "\\u00A51200\\u4E07"},
187 {123456789.0, "\\u00A51.2\\u4EBF"},
188 {1234567890.0, "\\u00A512\\u4EBF"},
189 {12345678901.0, "\\u00A5120\\u4EBF"},
190 {123456789012.0, "\\u00A51200\\u4EBF"},
191 {1234567890123.0, "\\u00A51.2\\u4E07\\u4EBF"},
192 {12345678901234.0, "\\u00A512\\u4E07\\u4EBF"},
193 {123456789012345.0, "\\u00A5120\\u4E07\\u4EBF"},
194 };
195
196 ExpectedResult kGermanCurrencyTestData[] = {
197 {1.0, "1\\u00A0\\u20AC"},
198 {12.0, "12\\u00A0\\u20AC"},
199 {123.0, "120\\u00A0\\u20AC"},
200 {1234.0, "1200\\u00A0\\u20AC"},
201 {12345.0, "12.000\\u00A0\\u20AC"},
202 {123456.0, "120.000\\u00A0\\u20AC"},
203 {1234567.0, "1,2\\u00A0Mio.\\u00A0\\u20AC"},
204 {12345678.0, "12\\u00A0Mio.\\u00A0\\u20AC"},
205 {123456789.0, "120\\u00A0Mio.\\u00A0\\u20AC"},
206 {1234567890.0, "1,2\\u00A0Mrd.\\u00A0\\u20AC"},
207 {12345678901.0, "12\\u00A0Mrd.\\u00A0\\u20AC"},
208 {123456789012.0, "120\\u00A0Mrd.\\u00A0\\u20AC"},
209 {1234567890123.0, "1,2\\u00A0Bio.\\u00A0\\u20AC"},
210 {12345678901234.0, "12\\u00A0Bio.\\u00A0\\u20AC"},
211 {123456789012345.0, "120\\u00A0Bio.\\u00A0\\u20AC"},
212 };
213
214 ExpectedResult kEnglishCurrencyTestData[] = {
215 {1.0, "$1"},
216 {12.0, "$12"},
217 {123.0, "$120"},
218 {1234.0, "$1.2K"},
219 {12345.0, "$12K"},
220 {123456.0, "$120K"},
221 {1234567.0, "$1.2M"},
222 {12345678.0, "$12M"},
223 {123456789.0, "$120M"},
224 {1234567890.0, "$1.2B"},
225 {12345678901.0, "$12B"},
226 {123456789012.0, "$120B"},
227 {1234567890123.0, "$1.2T"},
228 {12345678901234.0, "$12T"},
229 {123456789012345.0, "$120T"},
230 };
231
232 } // namespace
233
234 class CompactDecimalFormatTest : public IntlTest {
235 public:
CompactDecimalFormatTest()236 CompactDecimalFormatTest() {
237 }
238
239 void runIndexedTest(int32_t index, UBool exec, const char*& name, char* par = nullptr) override;
240
241 private:
242 void TestEnglishShort();
243 void TestSerbianShort();
244 void TestSerbianLong();
245 void TestSerbianLongNegative();
246 void TestJapaneseShort();
247 void TestSwahiliShort();
248 void TestCsShort();
249 void TestSkLong();
250 void TestSwahiliShortNegative();
251 void TestEnglishCurrency();
252 void TestGermanCurrency();
253 void TestChineseCurrency();
254 void TestArabicLong();
255 void TestFieldPosition();
256 void TestDefaultSignificantDigits();
257 void TestAPIVariants();
258 void TestBug12975();
259
260 void CheckLocale(
261 const Locale& locale, UNumberCompactStyle style,
262 const ExpectedResult* expectedResults, int32_t expectedResultLength);
263 void CheckLocaleWithCurrency(const Locale& locale, UNumberCompactStyle style, const char16_t* currency,
264 const ExpectedResult* expectedResults, int32_t expectedResultLength);
265 void CheckExpectedResult(
266 const CompactDecimalFormat* cdf, const ExpectedResult* expectedResult,
267 const char* description);
268 CompactDecimalFormat* createCDFInstance(const Locale& locale, UNumberCompactStyle style, UErrorCode& status);
269 static const char *StyleStr(UNumberCompactStyle style);
270 };
271
runIndexedTest(int32_t index,UBool exec,const char * & name,char *)272 void CompactDecimalFormatTest::runIndexedTest(
273 int32_t index, UBool exec, const char *&name, char *) {
274 if (exec) {
275 logln("TestSuite CompactDecimalFormatTest: ");
276 }
277 TESTCASE_AUTO_BEGIN;
278 TESTCASE_AUTO(TestEnglishShort);
279 TESTCASE_AUTO(TestSerbianShort);
280 TESTCASE_AUTO(TestSerbianLong);
281 TESTCASE_AUTO(TestSerbianLongNegative);
282 TESTCASE_AUTO(TestJapaneseShort);
283 TESTCASE_AUTO(TestSwahiliShort);
284 TESTCASE_AUTO(TestEnglishCurrency);
285 TESTCASE_AUTO(TestGermanCurrency);
286 TESTCASE_AUTO(TestChineseCurrency);
287 TESTCASE_AUTO(TestCsShort);
288 TESTCASE_AUTO(TestSkLong);
289 TESTCASE_AUTO(TestSwahiliShortNegative);
290 TESTCASE_AUTO(TestArabicLong);
291 TESTCASE_AUTO(TestFieldPosition);
292 TESTCASE_AUTO(TestDefaultSignificantDigits);
293 TESTCASE_AUTO(TestAPIVariants);
294 TESTCASE_AUTO(TestBug12975);
295 TESTCASE_AUTO_END;
296 }
297
TestEnglishShort()298 void CompactDecimalFormatTest::TestEnglishShort() {
299 CheckLocale("en", UNUM_SHORT, kEnglishShort, UPRV_LENGTHOF(kEnglishShort));
300 }
301
TestSerbianShort()302 void CompactDecimalFormatTest::TestSerbianShort() {
303 CheckLocale("sr", UNUM_SHORT, kSerbianShort, UPRV_LENGTHOF(kSerbianShort));
304 }
305
TestSerbianLong()306 void CompactDecimalFormatTest::TestSerbianLong() {
307 CheckLocale("sr", UNUM_LONG, kSerbianLong, UPRV_LENGTHOF(kSerbianLong));
308 }
309
TestSerbianLongNegative()310 void CompactDecimalFormatTest::TestSerbianLongNegative() {
311 CheckLocale("sr", UNUM_LONG, kSerbianLongNegative, UPRV_LENGTHOF(kSerbianLongNegative));
312 }
313
TestJapaneseShort()314 void CompactDecimalFormatTest::TestJapaneseShort() {
315 CheckLocale(Locale::getJapan(), UNUM_SHORT, kJapaneseShort, UPRV_LENGTHOF(kJapaneseShort));
316 }
317
TestSwahiliShort()318 void CompactDecimalFormatTest::TestSwahiliShort() {
319 CheckLocale("sw", UNUM_SHORT, kSwahiliShort, UPRV_LENGTHOF(kSwahiliShort));
320 }
321
TestEnglishCurrency()322 void CompactDecimalFormatTest::TestEnglishCurrency() {
323 CheckLocaleWithCurrency(
324 "en", UNUM_SHORT, u"USD", kEnglishCurrencyTestData, UPRV_LENGTHOF(kEnglishCurrencyTestData));
325 }
326
TestGermanCurrency()327 void CompactDecimalFormatTest::TestGermanCurrency() {
328 CheckLocaleWithCurrency(
329 "de", UNUM_SHORT, u"EUR", kGermanCurrencyTestData, UPRV_LENGTHOF(kGermanCurrencyTestData));
330 }
331
TestChineseCurrency()332 void CompactDecimalFormatTest::TestChineseCurrency() {
333 CheckLocaleWithCurrency(
334 "zh", UNUM_SHORT, u"CNY", kChineseCurrencyTestData, UPRV_LENGTHOF(kChineseCurrencyTestData));
335 }
336
TestFieldPosition()337 void CompactDecimalFormatTest::TestFieldPosition() {
338 // Swahili uses prefixes which forces offsets in field position to change
339 UErrorCode status = U_ZERO_ERROR;
340 LocalPointer<CompactDecimalFormat> cdf(createCDFInstance("sw", UNUM_SHORT, status));
341 if (U_FAILURE(status)) {
342 dataerrln("Unable to create format object - %s", u_errorName(status));
343 return;
344 }
345 FieldPosition fp(UNUM_INTEGER_FIELD);
346 UnicodeString result;
347 cdf->format(1234567.0, result, fp);
348 UnicodeString subString = result.tempSubString(fp.getBeginIndex(), fp.getEndIndex() - fp.getBeginIndex());
349 if (subString != UnicodeString("1", -1, US_INV)) {
350 errln(UnicodeString("Expected 1, got ") + subString);
351 }
352 }
353
TestCsShort()354 void CompactDecimalFormatTest::TestCsShort() {
355 CheckLocale("cs", UNUM_SHORT, kCsShort, UPRV_LENGTHOF(kCsShort));
356 }
357
TestSkLong()358 void CompactDecimalFormatTest::TestSkLong() {
359 // In CLDR we have:
360 // 1000 {
361 // few{"0"}
362 // one{"0"}
363 // other{"0"}
364 CheckLocale("sk", UNUM_LONG, kSkLong, UPRV_LENGTHOF(kSkLong));
365 }
366
TestSwahiliShortNegative()367 void CompactDecimalFormatTest::TestSwahiliShortNegative() {
368 CheckLocale("sw", UNUM_SHORT, kSwahiliShortNegative, UPRV_LENGTHOF(kSwahiliShortNegative));
369 }
370
TestArabicLong()371 void CompactDecimalFormatTest::TestArabicLong() {
372 CheckLocale("ar-EG", UNUM_LONG, kArabicLong, UPRV_LENGTHOF(kArabicLong));
373 }
374
TestDefaultSignificantDigits()375 void CompactDecimalFormatTest::TestDefaultSignificantDigits() {
376 UErrorCode status = U_ZERO_ERROR;
377 LocalPointer<CompactDecimalFormat> cdf(CompactDecimalFormat::createInstance("en", UNUM_SHORT, status));
378 if (U_FAILURE(status)) {
379 dataerrln("Unable to create format object - %s", u_errorName(status));
380 return;
381 }
382 // We are expecting two significant digits for compact formats with one or two zeros,
383 // and rounded to the unit for compact formats with three or more zeros.
384 UnicodeString actual;
385 assertEquals("Default significant digits", u"123K", cdf->format(123456, actual.remove()));
386 assertEquals("Default significant digits", u"12K", cdf->format(12345, actual.remove()));
387 assertEquals("Default significant digits", u"1.2K", cdf->format(1234, actual.remove()));
388 assertEquals("Default significant digits", u"123", cdf->format(123, actual.remove()));
389 }
390
TestAPIVariants()391 void CompactDecimalFormatTest::TestAPIVariants() {
392 UErrorCode status = U_ZERO_ERROR;
393 LocalPointer<CompactDecimalFormat> cdf(CompactDecimalFormat::createInstance("en", UNUM_SHORT, status));
394 if (U_FAILURE(status)) {
395 dataerrln("Unable to create format object - %s", u_errorName(status));
396 return;
397 }
398 UnicodeString actual;
399 FieldPosition pos;
400 FieldPositionIterator posIter;
401 UnicodeString expected("123K", -1, US_INV);
402 pos.setField(UNUM_INTEGER_FIELD);
403
404 actual.remove();
405 pos.setBeginIndex(0);
406 pos.setEndIndex(0);
407 cdf->format(123456.0, actual, pos);
408 if (actual != expected || pos.getEndIndex() != 3) {
409 errln(UnicodeString("Fail format(double,UnicodeString&,FieldPosition&): Expected: \"") + expected + "\", pos 3; " +
410 "Got: \"" + actual + "\", pos " + pos.getEndIndex());
411 }
412
413 actual.remove();
414 pos.setBeginIndex(0);
415 pos.setEndIndex(0);
416 status = U_ZERO_ERROR;
417 cdf->format(123456.0, actual, pos, status);
418 if (actual != expected || pos.getEndIndex() != 3 || status != U_ZERO_ERROR) {
419 errln(UnicodeString("Fail format(double,UnicodeString&,FieldPosition&,UErrorCode&): Expected: \"") + expected + "\", pos 3, status U_ZERO_ERROR; " +
420 "Got: \"" + actual + "\", pos " + pos.getEndIndex() + ", status " + u_errorName(status));
421 }
422
423 actual.remove();
424 pos.setBeginIndex(0);
425 pos.setEndIndex(0);
426 status = U_ZERO_ERROR;
427 cdf->format(123456.0, actual, &posIter, status);
428 posIter.next(pos);
429 if (actual != expected || pos.getEndIndex() != 3 || status != U_ZERO_ERROR) {
430 errln(UnicodeString("Fail format(int32_t,UnicodeString&,FieldPosition&,UErrorCode&): Expected: \"") + expected + "\", first pos 3, status U_ZERO_ERROR; " +
431 "Got: \"" + actual + "\", pos " + pos.getEndIndex() + ", status " + u_errorName(status));
432 }
433
434 actual.remove();
435 pos.setBeginIndex(0);
436 pos.setEndIndex(0);
437 cdf->format(static_cast<int32_t>(123456), actual, pos);
438 if (actual != expected || pos.getEndIndex() != 3) {
439 errln(UnicodeString("Fail format(int32_t,UnicodeString&,FieldPosition&): Expected: \"") + expected + "\", pos 3; " +
440 "Got: \"" + actual + "\", pos " + pos.getEndIndex());
441 }
442
443 actual.remove();
444 pos.setBeginIndex(0);
445 pos.setEndIndex(0);
446 status = U_ZERO_ERROR;
447 cdf->format(static_cast<int32_t>(123456), actual, pos, status);
448 if (actual != expected || pos.getEndIndex() != 3 || status != U_ZERO_ERROR) {
449 errln(UnicodeString("Fail format(int32_t,UnicodeString&,FieldPosition&,UErrorCode&): Expected: \"") + expected + "\", pos 3, status U_ZERO_ERROR; " +
450 "Got: \"" + actual + "\", pos " + pos.getEndIndex() + ", status " + u_errorName(status));
451 }
452
453 actual.remove();
454 pos.setBeginIndex(0);
455 pos.setEndIndex(0);
456 status = U_ZERO_ERROR;
457 cdf->format(static_cast<int32_t>(123456), actual, &posIter, status);
458 posIter.next(pos);
459 if (actual != expected || pos.getEndIndex() != 3 || status != U_ZERO_ERROR) {
460 errln(UnicodeString("Fail format(int32_t,UnicodeString&,FieldPosition&,UErrorCode&): Expected: \"") + expected + "\", first pos 3, status U_ZERO_ERROR; " +
461 "Got: \"" + actual + "\", pos " + pos.getEndIndex() + ", status " + u_errorName(status));
462 }
463
464 actual.remove();
465 pos.setBeginIndex(0);
466 pos.setEndIndex(0);
467 cdf->format(static_cast<int64_t>(123456), actual, pos);
468 if (actual != expected || pos.getEndIndex() != 3) {
469 errln(UnicodeString("Fail format(int64_t,UnicodeString&,FieldPosition&): Expected: \"") + expected + "\", pos 3; " +
470 "Got: \"" + actual + "\", pos " + pos.getEndIndex());
471 }
472
473 actual.remove();
474 pos.setBeginIndex(0);
475 pos.setEndIndex(0);
476 status = U_ZERO_ERROR;
477 cdf->format(static_cast<int64_t>(123456), actual, pos, status);
478 if (actual != expected || pos.getEndIndex() != 3 || status != U_ZERO_ERROR) {
479 errln(UnicodeString("Fail format(int64_t,UnicodeString&,FieldPosition&,UErrorCode&): Expected: \"") + expected + "\", pos 3, status U_ZERO_ERROR; " +
480 "Got: \"" + actual + "\", pos " + pos.getEndIndex() + ", status " + u_errorName(status));
481 }
482
483 actual.remove();
484 pos.setBeginIndex(0);
485 pos.setEndIndex(0);
486 status = U_ZERO_ERROR;
487 cdf->format(static_cast<int64_t>(123456), actual, &posIter, status);
488 posIter.next(pos);
489 if (actual != expected || pos.getEndIndex() != 3 || status != U_ZERO_ERROR) {
490 errln(UnicodeString("Fail format(int32_t,UnicodeString&,FieldPosition&,UErrorCode&): Expected: \"") + expected + "\", first pos 3, status U_ZERO_ERROR; " +
491 "Got: \"" + actual + "\", pos " + pos.getEndIndex() + ", status " + u_errorName(status));
492 }
493
494 }
495
TestBug12975()496 void CompactDecimalFormatTest::TestBug12975() {
497 IcuTestErrorCode status(*this, "TestBug12975");
498 Locale locale("it");
499 LocalPointer<CompactDecimalFormat> cdf(CompactDecimalFormat::createInstance(locale, UNUM_SHORT, status));
500 if (assertSuccess("", status, true, __FILE__, __LINE__)) {
501 UnicodeString resultCdf;
502 cdf->format(12000, resultCdf);
503 LocalPointer<DecimalFormat> df(dynamic_cast<DecimalFormat*>(DecimalFormat::createInstance(locale, status)));
504 UnicodeString resultDefault;
505 df->format(12000, resultDefault);
506 assertEquals("CompactDecimalFormat should use default pattern when compact pattern is unavailable",
507 resultDefault, resultCdf);
508 }
509 }
510
511
512 // End test cases. Helpers:
513
CheckLocale(const Locale & locale,UNumberCompactStyle style,const ExpectedResult * expectedResults,int32_t expectedResultLength)514 void CompactDecimalFormatTest::CheckLocale(const Locale& locale, UNumberCompactStyle style, const ExpectedResult* expectedResults, int32_t expectedResultLength) {
515 UErrorCode status = U_ZERO_ERROR;
516 LocalPointer<CompactDecimalFormat> cdf(createCDFInstance(locale, style, status));
517 if (U_FAILURE(status)) {
518 dataerrln("Unable to create format object - %s", u_errorName(status));
519 return;
520 }
521 char description[256];
522 snprintf(description, sizeof(description), "%s - %s", locale.getName(), StyleStr(style));
523 for (int32_t i = 0; i < expectedResultLength; i++) {
524 CheckExpectedResult(cdf.getAlias(), &expectedResults[i], description);
525 }
526 }
527
CheckLocaleWithCurrency(const Locale & locale,UNumberCompactStyle style,const char16_t * currency,const ExpectedResult * expectedResults,int32_t expectedResultLength)528 void CompactDecimalFormatTest::CheckLocaleWithCurrency(const Locale& locale, UNumberCompactStyle style,
529 const char16_t* currency,
530 const ExpectedResult* expectedResults,
531 int32_t expectedResultLength) {
532 UErrorCode status = U_ZERO_ERROR;
533 LocalPointer<CompactDecimalFormat> cdf(createCDFInstance(locale, style, status));
534 if (U_FAILURE(status)) {
535 dataerrln("Unable to create format object - %s", u_errorName(status));
536 return;
537 }
538 cdf->setCurrency(currency, status);
539 assertSuccess("Failed to set currency", status);
540 char description[256];
541 snprintf(description, sizeof(description), "%s - %s", locale.getName(), StyleStr(style));
542 for (int32_t i = 0; i < expectedResultLength; i++) {
543 CheckExpectedResult(cdf.getAlias(), &expectedResults[i], description);
544 }
545 }
546
CheckExpectedResult(const CompactDecimalFormat * cdf,const ExpectedResult * expectedResult,const char * description)547 void CompactDecimalFormatTest::CheckExpectedResult(
548 const CompactDecimalFormat* cdf, const ExpectedResult* expectedResult, const char* description) {
549 UnicodeString actual;
550 cdf->format(expectedResult->value, actual);
551 UnicodeString expected(expectedResult->expected, -1, US_INV);
552 expected = expected.unescape();
553 if (actual != expected) {
554 errln(UnicodeString("Fail: Expected: ") + expected
555 + UnicodeString(" Got: ") + actual
556 + UnicodeString(" for: ") + UnicodeString(description));
557 }
558 }
559
560 CompactDecimalFormat*
createCDFInstance(const Locale & locale,UNumberCompactStyle style,UErrorCode & status)561 CompactDecimalFormatTest::createCDFInstance(const Locale& locale, UNumberCompactStyle style, UErrorCode& status) {
562 CompactDecimalFormat* result = CompactDecimalFormat::createInstance(locale, style, status);
563 if (U_FAILURE(status)) {
564 return nullptr;
565 }
566 // All tests are written for two significant digits, so we explicitly set here
567 // in case default significant digits change.
568 result->setMaximumSignificantDigits(2);
569 return result;
570 }
571
StyleStr(UNumberCompactStyle style)572 const char *CompactDecimalFormatTest::StyleStr(UNumberCompactStyle style) {
573 if (style == UNUM_SHORT) {
574 return kShortStr;
575 }
576 return kLongStr;
577 }
578
createCompactDecimalFormatTest()579 extern IntlTest *createCompactDecimalFormatTest() {
580 return new CompactDecimalFormatTest();
581 }
582
583 #endif
584