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 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, "1.2M"},
123   {12345678.0, "12M"},
124   {123456789.0, "120M"},
125   {1.23456789E9, "1.2B"},
126   {1.23456789E10, "12B"},
127   {1.23456789E11, "120B"},
128   {1.23456789E12, "1.2T"},
129   {1.23456789E13, "12T"},
130   {1.23456789E15, "1200T"}};
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, "-1.2M"},
158   {-12345678.0, "-12M"},
159   {-123456789.0, "-120M"},
160   {-1.23456789E9, "-1.2B"},
161   {-1.23456789E10, "-12B"},
162   {-1.23456789E11, "-120B"},
163   {-1.23456789E12, "-1.2T"},
164   {-1.23456789E13, "-12T"},
165   {-1.23456789E15, "-1200T"}};
166 
167 static ExpectedResult kArabicLong[] = {
168   {-5300.0, "\\u061C-\\u0665\\u066B\\u0663 \\u0623\\u0644\\u0641"}};
169 
170 static ExpectedResult kChineseCurrencyTestData[] = {
171         {1.0, "\\uFFE51"},
172         {12.0, "\\uFFE512"},
173         {123.0, "\\uFFE5120"},
174         {1234.0, "\\uFFE51200"},
175         {12345.0, "\\uFFE51.2\\u4E07"},
176         {123456.0, "\\uFFE512\\u4E07"},
177         {1234567.0, "\\uFFE5120\\u4E07"},
178         {12345678.0, "\\uFFE51200\\u4E07"},
179         {123456789.0, "\\uFFE51.2\\u4EBF"},
180         {1234567890.0, "\\uFFE512\\u4EBF"},
181         {12345678901.0, "\\uFFE5120\\u4EBF"},
182         {123456789012.0, "\\uFFE51200\\u4EBF"},
183         {1234567890123.0, "\\uFFE51.2\\u5146"},
184         {12345678901234.0, "\\uFFE512\\u5146"},
185         {123456789012345.0, "\\uFFE5120\\u5146"},
186 };
187 static ExpectedResult kGermanCurrencyTestData[] = {
188         {1.0, u8"1\\u00A0\\u20AC"},
189         {12.0, u8"12\\u00A0\\u20AC"},
190         {123.0, u8"120\\u00A0\\u20AC"},
191         {1234.0, u8"1200\\u00A0\\u20AC"},
192         {12345.0, u8"12.000\\u00A0\\u20AC"},
193         {123456.0, u8"120.000\\u00A0\\u20AC"},
194         {1234567.0, u8"1,2\\u00A0Mio.\\u00A0\\u20AC"},
195         {12345678.0, u8"12\\u00A0Mio.\\u00A0\\u20AC"},
196         {123456789.0, u8"120\\u00A0Mio.\\u00A0\\u20AC"},
197         {1234567890.0, u8"1,2\\u00A0Mrd.\\u00A0\\u20AC"},
198         {12345678901.0, u8"12\\u00A0Mrd.\\u00A0\\u20AC"},
199         {123456789012.0, u8"120\\u00A0Mrd.\\u00A0\\u20AC"},
200         {1234567890123.0, u8"1,2\\u00A0Bio.\\u00A0\\u20AC"},
201         {12345678901234.0, u8"12\\u00A0Bio.\\u00A0\\u20AC"},
202         {123456789012345.0, u8"120\\u00A0Bio.\\u00A0\\u20AC"},
203 };
204 static ExpectedResult kEnglishCurrencyTestData[] = {
205         {1.0, u8"$1"},
206         {12.0, u8"$12"},
207         {123.0, u8"$120"},
208         {1234.0, u8"$1.2K"},
209         {12345.0, u8"$12K"},
210         {123456.0, u8"$120K"},
211         {1234567.0, u8"$1.2M"},
212         {12345678.0, u8"$12M"},
213         {123456789.0, u8"$120M"},
214         {1234567890.0, u8"$1.2B"},
215         {12345678901.0, u8"$12B"},
216         {123456789012.0, u8"$120B"},
217         {1234567890123.0, u8"$1.2T"},
218         {12345678901234.0, u8"$12T"},
219         {123456789012345.0, u8"$120T"},
220 };
221 
222 
223 class CompactDecimalFormatTest : public IntlTest {
224 public:
CompactDecimalFormatTest()225     CompactDecimalFormatTest() {
226     }
227 
228     void runIndexedTest(int32_t index, UBool exec, const char *&name, char *par=0);
229 private:
230     void TestEnglishShort();
231     void TestSerbianShort();
232     void TestSerbianLong();
233     void TestSerbianLongNegative();
234     void TestJapaneseShort();
235     void TestSwahiliShort();
236     void TestCsShort();
237     void TestSkLong();
238     void TestSwahiliShortNegative();
239     void TestEnglishCurrency();
240     void TestGermanCurrency();
241     void TestChineseCurrency();
242     void TestArabicLong();
243     void TestFieldPosition();
244     void TestDefaultSignificantDigits();
245     void TestAPIVariants();
246     void TestBug12975();
247 
248     void CheckLocale(
249         const Locale& locale, UNumberCompactStyle style,
250         const ExpectedResult* expectedResults, int32_t expectedResultLength);
251     void CheckLocaleWithCurrency(const Locale& locale, UNumberCompactStyle style, const UChar* currency,
252                                  const ExpectedResult* expectedResults, int32_t expectedResultLength);
253     void CheckExpectedResult(
254         const CompactDecimalFormat* cdf, const ExpectedResult* expectedResult,
255         const char* description);
256     CompactDecimalFormat* createCDFInstance(const Locale& locale, UNumberCompactStyle style, UErrorCode& status);
257     static const char *StyleStr(UNumberCompactStyle style);
258 };
259 
runIndexedTest(int32_t index,UBool exec,const char * & name,char *)260 void CompactDecimalFormatTest::runIndexedTest(
261     int32_t index, UBool exec, const char *&name, char *) {
262   if (exec) {
263     logln("TestSuite CompactDecimalFormatTest: ");
264   }
265   TESTCASE_AUTO_BEGIN;
266   TESTCASE_AUTO(TestEnglishShort);
267   TESTCASE_AUTO(TestSerbianShort);
268   TESTCASE_AUTO(TestSerbianLong);
269   TESTCASE_AUTO(TestSerbianLongNegative);
270   TESTCASE_AUTO(TestJapaneseShort);
271   TESTCASE_AUTO(TestSwahiliShort);
272   TESTCASE_AUTO(TestEnglishCurrency);
273   TESTCASE_AUTO(TestGermanCurrency);
274   TESTCASE_AUTO(TestChineseCurrency);
275   TESTCASE_AUTO(TestCsShort);
276   TESTCASE_AUTO(TestSkLong);
277   TESTCASE_AUTO(TestSwahiliShortNegative);
278   TESTCASE_AUTO(TestArabicLong);
279   TESTCASE_AUTO(TestFieldPosition);
280   TESTCASE_AUTO(TestDefaultSignificantDigits);
281   TESTCASE_AUTO(TestAPIVariants);
282   TESTCASE_AUTO(TestBug12975);
283   TESTCASE_AUTO_END;
284 }
285 
TestEnglishShort()286 void CompactDecimalFormatTest::TestEnglishShort() {
287   CheckLocale("en", UNUM_SHORT, kEnglishShort, UPRV_LENGTHOF(kEnglishShort));
288 }
289 
TestSerbianShort()290 void CompactDecimalFormatTest::TestSerbianShort() {
291   CheckLocale("sr", UNUM_SHORT, kSerbianShort, UPRV_LENGTHOF(kSerbianShort));
292 }
293 
TestSerbianLong()294 void CompactDecimalFormatTest::TestSerbianLong() {
295   CheckLocale("sr", UNUM_LONG, kSerbianLong, UPRV_LENGTHOF(kSerbianLong));
296 }
297 
TestSerbianLongNegative()298 void CompactDecimalFormatTest::TestSerbianLongNegative() {
299   CheckLocale("sr", UNUM_LONG, kSerbianLongNegative, UPRV_LENGTHOF(kSerbianLongNegative));
300 }
301 
TestJapaneseShort()302 void CompactDecimalFormatTest::TestJapaneseShort() {
303   CheckLocale(Locale::getJapan(), UNUM_SHORT, kJapaneseShort, UPRV_LENGTHOF(kJapaneseShort));
304 }
305 
TestSwahiliShort()306 void CompactDecimalFormatTest::TestSwahiliShort() {
307   CheckLocale("sw", UNUM_SHORT, kSwahiliShort, UPRV_LENGTHOF(kSwahiliShort));
308 }
309 
TestEnglishCurrency()310 void CompactDecimalFormatTest::TestEnglishCurrency() {
311     CheckLocaleWithCurrency(
312             "en", UNUM_SHORT, u"USD", kEnglishCurrencyTestData, UPRV_LENGTHOF(kEnglishCurrencyTestData));
313 }
314 
TestGermanCurrency()315 void CompactDecimalFormatTest::TestGermanCurrency() {
316     CheckLocaleWithCurrency(
317             "de", UNUM_SHORT, u"EUR", kGermanCurrencyTestData, UPRV_LENGTHOF(kGermanCurrencyTestData));
318 }
319 
TestChineseCurrency()320 void CompactDecimalFormatTest::TestChineseCurrency() {
321     CheckLocaleWithCurrency(
322             "zh", UNUM_SHORT, u"CNY", kChineseCurrencyTestData, UPRV_LENGTHOF(kChineseCurrencyTestData));
323 }
324 
TestFieldPosition()325 void CompactDecimalFormatTest::TestFieldPosition() {
326   // Swahili uses prefixes which forces offsets in field position to change
327   UErrorCode status = U_ZERO_ERROR;
328   LocalPointer<CompactDecimalFormat> cdf(createCDFInstance("sw", UNUM_SHORT, status));
329   if (U_FAILURE(status)) {
330     dataerrln("Unable to create format object - %s", u_errorName(status));
331     return;
332   }
333   FieldPosition fp(UNUM_INTEGER_FIELD);
334   UnicodeString result;
335   cdf->format(1234567.0, result, fp);
336   UnicodeString subString = result.tempSubString(fp.getBeginIndex(), fp.getEndIndex() - fp.getBeginIndex());
337   if (subString != UnicodeString("1", -1, US_INV)) {
338     errln(UnicodeString("Expected 1, got ") + subString);
339   }
340 }
341 
TestCsShort()342 void CompactDecimalFormatTest::TestCsShort() {
343   CheckLocale("cs", UNUM_SHORT, kCsShort, UPRV_LENGTHOF(kCsShort));
344 }
345 
TestSkLong()346 void CompactDecimalFormatTest::TestSkLong() {
347   // In CLDR we have:
348   // 1000 {
349   //   few{"0"}
350   //   one{"0"}
351   //   other{"0"}
352   CheckLocale("sk", UNUM_LONG, kSkLong, UPRV_LENGTHOF(kSkLong));
353 }
354 
TestSwahiliShortNegative()355 void CompactDecimalFormatTest::TestSwahiliShortNegative() {
356   CheckLocale("sw", UNUM_SHORT, kSwahiliShortNegative, UPRV_LENGTHOF(kSwahiliShortNegative));
357 }
358 
TestArabicLong()359 void CompactDecimalFormatTest::TestArabicLong() {
360   CheckLocale("ar-EG", UNUM_LONG, kArabicLong, UPRV_LENGTHOF(kArabicLong));
361 }
362 
TestDefaultSignificantDigits()363 void CompactDecimalFormatTest::TestDefaultSignificantDigits() {
364   UErrorCode status = U_ZERO_ERROR;
365   LocalPointer<CompactDecimalFormat> cdf(CompactDecimalFormat::createInstance("en", UNUM_SHORT, status));
366   if (U_FAILURE(status)) {
367     dataerrln("Unable to create format object - %s", u_errorName(status));
368     return;
369   }
370   // We are expecting two significant digits for compact formats with one or two zeros,
371   // and rounded to the unit for compact formats with three or more zeros.
372   UnicodeString actual;
373   assertEquals("Default significant digits", u"123K", cdf->format(123456, actual.remove()));
374   assertEquals("Default significant digits", u"12K", cdf->format(12345, actual.remove()));
375   assertEquals("Default significant digits", u"1.2K", cdf->format(1234, actual.remove()));
376   assertEquals("Default significant digits", u"123", cdf->format(123, actual.remove()));
377 }
378 
TestAPIVariants()379 void CompactDecimalFormatTest::TestAPIVariants() {
380   UErrorCode status = U_ZERO_ERROR;
381   LocalPointer<CompactDecimalFormat> cdf(CompactDecimalFormat::createInstance("en", UNUM_SHORT, status));
382   if (U_FAILURE(status)) {
383     dataerrln("Unable to create format object - %s", u_errorName(status));
384     return;
385   }
386   UnicodeString actual;
387   FieldPosition pos;
388   FieldPositionIterator posIter;
389   UnicodeString expected("123K", -1, US_INV);
390   pos.setField(UNUM_INTEGER_FIELD);
391 
392   actual.remove();
393   pos.setBeginIndex(0);
394   pos.setEndIndex(0);
395   cdf->format((double)123456.0, actual, pos);
396   if (actual != expected || pos.getEndIndex() != 3) {
397     errln(UnicodeString("Fail format(double,UnicodeString&,FieldPosition&): Expected: \"") + expected + "\", pos 3; " +
398                                                                            "Got: \"" + actual + "\", pos " + pos.getEndIndex());
399   }
400 
401   actual.remove();
402   pos.setBeginIndex(0);
403   pos.setEndIndex(0);
404   status = U_ZERO_ERROR;
405   cdf->format((double)123456.0, actual, pos, status);
406   if (actual != expected || pos.getEndIndex() != 3 || status != U_ZERO_ERROR) {
407     errln(UnicodeString("Fail format(double,UnicodeString&,FieldPosition&,UErrorCode&): Expected: \"") + expected + "\", pos 3, status U_ZERO_ERROR; " +
408                                                               "Got: \"" + actual + "\", pos " + pos.getEndIndex() + ", status " + u_errorName(status));
409   }
410 
411   actual.remove();
412   pos.setBeginIndex(0);
413   pos.setEndIndex(0);
414   status = U_ZERO_ERROR;
415   cdf->format((double)123456.0, actual, &posIter, status);
416   posIter.next(pos);
417   if (actual != expected || pos.getEndIndex() != 3 || status != U_ZERO_ERROR) {
418     errln(UnicodeString("Fail format(int32_t,UnicodeString&,FieldPosition&,UErrorCode&): Expected: \"") + expected + "\", first pos 3, status U_ZERO_ERROR; " +
419           "Got: \"" + actual + "\", pos " + pos.getEndIndex() + ", status " + u_errorName(status));
420   }
421 
422   actual.remove();
423   pos.setBeginIndex(0);
424   pos.setEndIndex(0);
425   cdf->format((int32_t)123456, actual, pos);
426   if (actual != expected || pos.getEndIndex() != 3) {
427     errln(UnicodeString("Fail format(int32_t,UnicodeString&,FieldPosition&): Expected: \"") + expected + "\", pos 3; " +
428                                                                            "Got: \"" + actual + "\", pos " + pos.getEndIndex());
429   }
430 
431   actual.remove();
432   pos.setBeginIndex(0);
433   pos.setEndIndex(0);
434   status = U_ZERO_ERROR;
435   cdf->format((int32_t)123456, actual, pos, status);
436   if (actual != expected || pos.getEndIndex() != 3 || status != U_ZERO_ERROR) {
437     errln(UnicodeString("Fail format(int32_t,UnicodeString&,FieldPosition&,UErrorCode&): Expected: \"") + expected + "\", pos 3, status U_ZERO_ERROR; " +
438                                                               "Got: \"" + actual + "\", pos " + pos.getEndIndex() + ", status " + u_errorName(status));
439   }
440 
441   actual.remove();
442   pos.setBeginIndex(0);
443   pos.setEndIndex(0);
444   status = U_ZERO_ERROR;
445   cdf->format((int32_t)123456, actual, &posIter, status);
446   posIter.next(pos);
447   if (actual != expected || pos.getEndIndex() != 3 || status != U_ZERO_ERROR) {
448     errln(UnicodeString("Fail format(int32_t,UnicodeString&,FieldPosition&,UErrorCode&): Expected: \"") + expected + "\", first pos 3, status U_ZERO_ERROR; " +
449           "Got: \"" + actual + "\", pos " + pos.getEndIndex() + ", status " + u_errorName(status));
450   }
451 
452   actual.remove();
453   pos.setBeginIndex(0);
454   pos.setEndIndex(0);
455   cdf->format((int64_t)123456, actual, pos);
456   if (actual != expected || pos.getEndIndex() != 3) {
457     errln(UnicodeString("Fail format(int64_t,UnicodeString&,FieldPosition&): Expected: \"") + expected + "\", pos 3; " +
458                                                                            "Got: \"" + actual + "\", pos " + pos.getEndIndex());
459   }
460 
461   actual.remove();
462   pos.setBeginIndex(0);
463   pos.setEndIndex(0);
464   status = U_ZERO_ERROR;
465   cdf->format((int64_t)123456, actual, pos, status);
466   if (actual != expected || pos.getEndIndex() != 3 || status != U_ZERO_ERROR) {
467     errln(UnicodeString("Fail format(int64_t,UnicodeString&,FieldPosition&,UErrorCode&): Expected: \"") + expected + "\", pos 3, status U_ZERO_ERROR; " +
468                                                               "Got: \"" + actual + "\", pos " + pos.getEndIndex() + ", status " + u_errorName(status));
469   }
470 
471   actual.remove();
472   pos.setBeginIndex(0);
473   pos.setEndIndex(0);
474   status = U_ZERO_ERROR;
475   cdf->format((int64_t)123456, actual, &posIter, status);
476   posIter.next(pos);
477   if (actual != expected || pos.getEndIndex() != 3 || status != U_ZERO_ERROR) {
478     errln(UnicodeString("Fail format(int32_t,UnicodeString&,FieldPosition&,UErrorCode&): Expected: \"") + expected + "\", first pos 3, status U_ZERO_ERROR; " +
479           "Got: \"" + actual + "\", pos " + pos.getEndIndex() + ", status " + u_errorName(status));
480   }
481 
482 }
483 
TestBug12975()484 void CompactDecimalFormatTest::TestBug12975() {
485 	IcuTestErrorCode status(*this, "TestBug12975");
486     Locale locale("it");
487     LocalPointer<CompactDecimalFormat> cdf(CompactDecimalFormat::createInstance(locale, UNUM_SHORT, status));
488     if (assertSuccess("", status, true, __FILE__, __LINE__)) {
489         UnicodeString resultCdf;
490         cdf->format(12000, resultCdf);
491         LocalPointer<DecimalFormat> df((DecimalFormat*) DecimalFormat::createInstance(locale, status));
492         UnicodeString resultDefault;
493         df->format(12000, resultDefault);
494         assertEquals("CompactDecimalFormat should use default pattern when compact pattern is unavailable",
495                      resultDefault, resultCdf);
496     }
497 }
498 
499 
500 // End test cases. Helpers:
501 
CheckLocale(const Locale & locale,UNumberCompactStyle style,const ExpectedResult * expectedResults,int32_t expectedResultLength)502 void CompactDecimalFormatTest::CheckLocale(const Locale& locale, UNumberCompactStyle style, const ExpectedResult* expectedResults, int32_t expectedResultLength) {
503   UErrorCode status = U_ZERO_ERROR;
504   LocalPointer<CompactDecimalFormat> cdf(createCDFInstance(locale, style, status));
505   if (U_FAILURE(status)) {
506     dataerrln("Unable to create format object - %s", u_errorName(status));
507     return;
508   }
509   char description[256];
510   sprintf(description,"%s - %s", locale.getName(), StyleStr(style));
511   for (int32_t i = 0; i < expectedResultLength; i++) {
512     CheckExpectedResult(cdf.getAlias(), &expectedResults[i], description);
513   }
514 }
515 
CheckLocaleWithCurrency(const Locale & locale,UNumberCompactStyle style,const UChar * currency,const ExpectedResult * expectedResults,int32_t expectedResultLength)516 void CompactDecimalFormatTest::CheckLocaleWithCurrency(const Locale& locale, UNumberCompactStyle style,
517                                                        const UChar* currency,
518                                                        const ExpectedResult* expectedResults,
519                                                        int32_t expectedResultLength) {
520     UErrorCode status = U_ZERO_ERROR;
521     LocalPointer<CompactDecimalFormat> cdf(createCDFInstance(locale, style, status));
522     if (U_FAILURE(status)) {
523         dataerrln("Unable to create format object - %s", u_errorName(status));
524         return;
525     }
526     cdf->setCurrency(currency, status);
527     assertSuccess("Failed to set currency", status);
528     char description[256];
529     sprintf(description,"%s - %s", locale.getName(), StyleStr(style));
530     for (int32_t i = 0; i < expectedResultLength; i++) {
531         CheckExpectedResult(cdf.getAlias(), &expectedResults[i], description);
532     }
533 }
534 
CheckExpectedResult(const CompactDecimalFormat * cdf,const ExpectedResult * expectedResult,const char * description)535 void CompactDecimalFormatTest::CheckExpectedResult(
536     const CompactDecimalFormat* cdf, const ExpectedResult* expectedResult, const char* description) {
537   UnicodeString actual;
538   cdf->format(expectedResult->value, actual);
539   UnicodeString expected(expectedResult->expected, -1, US_INV);
540   expected = expected.unescape();
541   if (actual != expected) {
542     errln(UnicodeString("Fail: Expected: ") + expected
543           + UnicodeString(" Got: ") + actual
544           + UnicodeString(" for: ") + UnicodeString(description));
545   }
546 }
547 
548 CompactDecimalFormat*
createCDFInstance(const Locale & locale,UNumberCompactStyle style,UErrorCode & status)549 CompactDecimalFormatTest::createCDFInstance(const Locale& locale, UNumberCompactStyle style, UErrorCode& status) {
550   CompactDecimalFormat* result = CompactDecimalFormat::createInstance(locale, style, status);
551   if (U_FAILURE(status)) {
552     return NULL;
553   }
554   // All tests are written for two significant digits, so we explicitly set here
555   // in case default significant digits change.
556   result->setMaximumSignificantDigits(2);
557   return result;
558 }
559 
StyleStr(UNumberCompactStyle style)560 const char *CompactDecimalFormatTest::StyleStr(UNumberCompactStyle style) {
561   if (style == UNUM_SHORT) {
562     return kShortStr;
563   }
564   return kLongStr;
565 }
566 
createCompactDecimalFormatTest()567 extern IntlTest *createCompactDecimalFormatTest() {
568   return new CompactDecimalFormatTest();
569 }
570 
571 #endif
572