1// © 2016 and later: Unicode, Inc. and others.
2// License & terms of use: http://www.unicode.org/copyright.html#License
3/*
4 *******************************************************************************
5 * Copyright (C) 1996-2016, Google, International Business Machines Corporation and
6 * others. All Rights Reserved.                                                *
7 *******************************************************************************
8 */
9package com.ibm.icu.dev.test.format;
10
11import java.io.ByteArrayInputStream;
12import java.io.ByteArrayOutputStream;
13import java.io.IOException;
14import java.io.NotSerializableException;
15import java.io.ObjectInputStream;
16import java.io.ObjectOutputStream;
17import java.math.BigDecimal;
18import java.math.BigInteger;
19import java.text.AttributedCharacterIterator;
20import java.text.CharacterIterator;
21import java.text.FieldPosition;
22import java.text.ParsePosition;
23import java.util.Collection;
24import java.util.HashMap;
25import java.util.LinkedHashSet;
26import java.util.Locale;
27import java.util.Map;
28
29import org.junit.Test;
30
31import com.ibm.icu.dev.test.TestFmwk;
32import com.ibm.icu.text.CompactDecimalFormat;
33import com.ibm.icu.text.CompactDecimalFormat.CompactStyle;
34import com.ibm.icu.text.DecimalFormatSymbols;
35import com.ibm.icu.text.NumberFormat;
36import com.ibm.icu.text.PluralRules;
37import com.ibm.icu.util.Currency;
38import com.ibm.icu.util.CurrencyAmount;
39import com.ibm.icu.util.ULocale;
40
41public class CompactDecimalFormatTest extends TestFmwk {
42    Object[][] EnglishTestData = {
43            // default is 2 digits of accuracy
44            {0.0d, "0"},
45            {0.01d, "0.01"},
46            {0.1d, "0.1"},
47            {1d, "1"},
48            {12, "12"},
49            {123, "120"},
50            {1234, "1.2K"},
51            {1000, "1K"},
52            {1049, "1K"},
53            {12345, "12K"},
54            {123456, "120K"},
55            {1234567, "1.2M"},
56            {12345678, "12M"},
57            {123456789, "120M"},
58            {1234567890, "1.2B"},
59            {12345678901f, "12B"},
60            {123456789012f, "120B"},
61            {1234567890123f, "1.2T"},
62            {12345678901234f, "12T"},
63            {123456789012345f, "120T"},
64            {12345678901234567890f, "12000000T"},
65    };
66
67    Object[][] SerbianTestDataShort = {
68            {1234, "1,2\u00A0\u0445\u0438\u0459."},
69            {12345, "12\u00a0хиљ."},
70            {20789, "21\u00a0хиљ."},
71            {123456, "120\u00a0хиљ."},
72            {1234567, "1,2\u00a0мил."},
73            {12345678, "12\u00a0мил."},
74            {123456789, "120\u00a0мил."},
75            {1234567890, "1,2\u00a0млрд."},
76            {12345678901f, "12\u00a0млрд."},
77            {123456789012f, "120\u00a0млрд."},
78            {1234567890123f, "1,2\u00a0бил."},
79            {12345678901234f, "12\u00a0бил."},
80            {123456789012345f, "120\u00a0бил."},
81            {1234567890123456f, "1200\u00a0бил."},
82    };
83
84    Object[][] SerbianTestDataLong = {
85            {1234, "1,2 хиљаде"},
86            {12345, "12 хиљада"},
87            {21789, "22 хиљаде"},
88            {123456, "120 хиљада"},
89            {999999, "1 милион"},
90            {1234567, "1,2 милиона"},
91            {12345678, "12 милиона"},
92            {123456789, "120 милиона"},
93            {1234567890, "1,2 милијарде"},
94            {12345678901f, "12 милијарди"},
95            {20890123456f, "21 милијарда"},
96            {21890123456f, "22 милијарде"},
97            {123456789012f, "120 милијарди"},
98            {1234567890123f, "1,2 билиона"},
99            {12345678901234f, "12 билиона"},
100            {123456789012345f, "120 билиона"},
101            {1234567890123456f, "1.200 билиона"},
102    };
103
104    Object[][] SerbianTestDataLongNegative = {
105            {-1234, "-1,2 хиљаде"},
106            {-12345, "-12 хиљада"},
107            {-21789, "-22 хиљаде"},
108            {-123456, "-120 хиљада"},
109            {-999999, "-1 милион"},
110            {-1234567, "-1,2 милиона"},
111            {-12345678, "-12 милиона"},
112            {-123456789, "-120 милиона"},
113            {-1234567890, "-1,2 милијарде"},
114            {-12345678901f, "-12 милијарди"},
115            {-20890123456f, "-21 милијарда"},
116            {-21890123456f, "-22 милијарде"},
117            {-123456789012f, "-120 милијарди"},
118            {-1234567890123f, "-1,2 билиона"},
119            {-12345678901234f, "-12 билиона"},
120            {-123456789012345f, "-120 билиона"},
121            {-1234567890123456f, "-1.200 билиона"},
122    };
123
124    Object[][] JapaneseTestData = {
125            {1234f, "1200"},
126            {12345f, "1.2万"},
127            {123456f, "12万"},
128            {1234567f, "120万"},
129            {12345678f, "1200万"},
130            {123456789f, "1.2億"},
131            {1234567890f, "12億"},
132            {12345678901f, "120億"},
133            {123456789012f, "1200億"},
134            {1234567890123f, "1.2兆"},
135            {12345678901234f, "12兆"},
136            {123456789012345f, "120兆"},
137    };
138
139    Object[][] ChineseCurrencyTestData = {
140            // The first one should really have a ¥ in front, but the CLDR data is
141            // incorrect.  See http://unicode.org/cldr/trac/ticket/9298 and update
142            // this test case when the CLDR ticket is fixed.
143            {new CurrencyAmount(1234f, Currency.getInstance("CNY")), "¥1.2千"},
144            {new CurrencyAmount(12345f, Currency.getInstance("CNY")), "¥1.2万"},
145            {new CurrencyAmount(123456f, Currency.getInstance("CNY")), "¥12万"},
146            {new CurrencyAmount(1234567f, Currency.getInstance("CNY")), "¥120万"},
147            {new CurrencyAmount(12345678f, Currency.getInstance("CNY")), "¥1200万"},
148            {new CurrencyAmount(123456789f, Currency.getInstance("CNY")), "¥1.2亿"},
149            {new CurrencyAmount(1234567890f, Currency.getInstance("CNY")), "¥12亿"},
150            {new CurrencyAmount(12345678901f, Currency.getInstance("CNY")), "¥120亿"},
151            {new CurrencyAmount(123456789012f, Currency.getInstance("CNY")), "¥1200亿"},
152            {new CurrencyAmount(1234567890123f, Currency.getInstance("CNY")), "¥1.2兆"},
153            {new CurrencyAmount(12345678901234f, Currency.getInstance("CNY")), "¥12兆"},
154            {new CurrencyAmount(123456789012345f, Currency.getInstance("CNY")), "¥120兆"},
155    };
156    Object[][] GermanCurrencyTestData = {
157            {new CurrencyAmount(1234f, Currency.getInstance("EUR")), "1,2 Tsd. €"},
158            {new CurrencyAmount(12345f, Currency.getInstance("EUR")), "12 Tsd. €"},
159            {new CurrencyAmount(123456f, Currency.getInstance("EUR")), "120 Tsd. €"},
160            {new CurrencyAmount(1234567f, Currency.getInstance("EUR")), "1,2 Mio. €"},
161            {new CurrencyAmount(12345678f, Currency.getInstance("EUR")), "12 Mio. €"},
162            {new CurrencyAmount(123456789f, Currency.getInstance("EUR")), "120 Mio. €"},
163            {new CurrencyAmount(1234567890f, Currency.getInstance("EUR")), "1,2 Mrd. €"},
164            {new CurrencyAmount(12345678901f, Currency.getInstance("EUR")), "12 Mrd. €"},
165            {new CurrencyAmount(123456789012f, Currency.getInstance("EUR")), "120 Mrd. €"},
166            {new CurrencyAmount(1234567890123f, Currency.getInstance("EUR")), "1,2 Bio. €"},
167            {new CurrencyAmount(12345678901234f, Currency.getInstance("EUR")), "12 Bio. €"},
168            {new CurrencyAmount(123456789012345f, Currency.getInstance("EUR")), "120 Bio. €"},
169    };
170    Object[][] EnglishCurrencyTestData = {
171            {new CurrencyAmount(1234f, Currency.getInstance("USD")), "$1.2K"},
172            {new CurrencyAmount(12345f, Currency.getInstance("USD")), "$12K"},
173            {new CurrencyAmount(123456f, Currency.getInstance("USD")), "$120K"},
174            {new CurrencyAmount(1234567f, Currency.getInstance("USD")), "$1.2M"},
175            {new CurrencyAmount(12345678f, Currency.getInstance("USD")), "$12M"},
176            {new CurrencyAmount(123456789f, Currency.getInstance("USD")), "$120M"},
177            {new CurrencyAmount(1234567890f, Currency.getInstance("USD")), "$1.2B"},
178            {new CurrencyAmount(12345678901f, Currency.getInstance("USD")), "$12B"},
179            {new CurrencyAmount(123456789012f, Currency.getInstance("USD")), "$120B"},
180            {new CurrencyAmount(1234567890123f, Currency.getInstance("USD")), "$1.2T"},
181            {new CurrencyAmount(12345678901234f, Currency.getInstance("USD")), "$12T"},
182            {new CurrencyAmount(123456789012345f, Currency.getInstance("USD")), "$120T"},
183    };
184
185    Object[][] SwahiliTestData = {
186            {1234f, "elfu\u00a01.2"},
187            {12345f, "elfu\u00a012"},
188            {123456f, "elfu\u00A0120"},
189            {1234567f, "M1.2"},
190            {12345678f, "M12"},
191            {123456789f, "M120"},
192            {1234567890f, "B1.2"},
193            {12345678901f, "B12"},
194            {123456789012f, "B120"},
195            {1234567890123f, "T1.2"},
196            {12345678901234f, "T12"},
197            {12345678901234567890f, "T12000000"},
198    };
199
200    Object[][] CsTestDataShort = {
201            {1000, "1\u00a0tis."},
202            {1500, "1,5\u00a0tis."},
203            {5000, "5\u00a0tis."},
204            {23000, "23\u00a0tis."},
205            {127123, "130\u00a0tis."},
206            {1271234, "1,3\u00a0mil."},
207            {12712345, "13\u00a0mil."},
208            {127123456, "130\u00a0mil."},
209            {1271234567f, "1,3\u00a0mld."},
210            {12712345678f, "13\u00a0mld."},
211            {127123456789f, "130\u00a0mld."},
212            {1271234567890f, "1,3\u00a0bil."},
213            {12712345678901f, "13\u00a0bil."},
214            {127123456789012f, "130\u00a0bil."},
215    };
216
217    Object[][] SkTestDataLong = {
218            {1000, "1 tis\u00edc"},
219            {1572, "1,6 tis\u00edca"},
220            {5184, "5,2 tis\u00edca"},
221    };
222
223    Object[][] SwahiliTestDataNegative = {
224            {-1234f, "elfu\u00a0-1.2"},
225            {-12345f, "elfu\u00a0-12"},
226            {-123456f, "elfu\u00A0-120"},
227            {-1234567f, "M-1.2"},
228            {-12345678f, "M-12"},
229            {-123456789f, "M-120"},
230            {-1234567890f, "B-1.2"},
231            {-12345678901f, "B-12"},
232            {-123456789012f, "B-120"},
233            {-1234567890123f, "T-1.2"},
234            {-12345678901234f, "T-12"},
235            {-12345678901234567890f, "T-12000000"},
236    };
237
238    Object[][] TestACoreCompactFormatList = {
239            {1000, "1K"},
240            {1100, "1,1K"},
241            {1200, "1,2Ks"},
242            {2000, "2Ks"},
243    };
244
245    Object[][] TestACoreCompactFormatListCurrency = {
246            {1000, "1K$"},
247            {1100, "1,1K$"},
248            {1200, "1,2Ks$s"},
249            {2000, "2Ks$s"},
250    };
251
252    @Test
253    public void TestACoreCompactFormat() {
254        Map<String,String[][]> affixes = new HashMap();
255        affixes.put("one", new String[][] {
256                {"","",}, {"","",}, {"","",},
257                {"","K"}, {"","K"}, {"","K"},
258                {"","M"}, {"","M"}, {"","M"},
259                {"","B"}, {"","B"}, {"","B"},
260                {"","T"}, {"","T"}, {"","T"},
261        });
262        affixes.put("other", new String[][] {
263                {"","",}, {"","",}, {"","",},
264                {"","Ks"}, {"","Ks"}, {"","Ks"},
265                {"","Ms"}, {"","Ms"}, {"","Ms"},
266                {"","Bs"}, {"","Bs"}, {"","Bs"},
267                {"","Ts"}, {"","Ts"}, {"","Ts"},
268        });
269
270        Map<String,String[]> currencyAffixes = new HashMap();
271        currencyAffixes.put("one", new String[] {"", "$"});
272        currencyAffixes.put("other", new String[] {"", "$s"});
273
274        long[] divisors = new long[] {
275                0,0,0,
276                1000, 1000, 1000,
277                1000000, 1000000, 1000000,
278                1000000000L, 1000000000L, 1000000000L,
279                1000000000000L, 1000000000000L, 1000000000000L};
280        long[] divisors_err = new long[] {
281                0,0,0,
282                13, 13, 13,
283                1000000, 1000000, 1000000,
284                1000000000L, 1000000000L, 1000000000L,
285                1000000000000L, 1000000000000L, 1000000000000L};
286        checkCore(affixes, null, divisors, TestACoreCompactFormatList);
287        checkCore(affixes, currencyAffixes, divisors, TestACoreCompactFormatListCurrency);
288        try {
289            checkCore(affixes, null, divisors_err, TestACoreCompactFormatList);
290        } catch(AssertionError e) {
291            // Exception expected, thus return.
292            return;
293        }
294        fail("Error expected but passed");
295    }
296
297    private void checkCore(Map<String, String[][]> affixes, Map<String, String[]> currencyAffixes, long[] divisors, Object[][] testItems) {
298        Collection<String> debugCreationErrors = new LinkedHashSet();
299        CompactDecimalFormat cdf = new CompactDecimalFormat(
300                "#,###.00",
301                DecimalFormatSymbols.getInstance(new ULocale("fr")),
302                CompactStyle.SHORT, PluralRules.createRules("one: j is 1 or f is 1"),
303                divisors, affixes, currencyAffixes,
304                debugCreationErrors
305                );
306        if (debugCreationErrors.size() != 0) {
307            for (String s : debugCreationErrors) {
308                errln("Creation error: " + s);
309            }
310        } else {
311            checkCdf("special cdf ", cdf, testItems);
312        }
313    }
314
315    @Test
316    public void TestDefaultSignificantDigits() {
317        // We are expecting two significant digits as default.
318        CompactDecimalFormat cdf =
319                CompactDecimalFormat.getInstance(ULocale.ENGLISH, CompactStyle.SHORT);
320        assertEquals("Default significant digits", "12K", cdf.format(12345));
321        assertEquals("Default significant digits", "1.2K", cdf.format(1234));
322        assertEquals("Default significant digits", "120", cdf.format(123));
323    }
324
325    @Test
326    public void TestCharacterIterator() {
327        CompactDecimalFormat cdf =
328                getCDFInstance(ULocale.forLanguageTag("sw"), CompactStyle.SHORT);
329        AttributedCharacterIterator iter = cdf.formatToCharacterIterator(1234567);
330        assertEquals("CharacterIterator", "M1.2", iterToString(iter));
331        iter = cdf.formatToCharacterIterator(1234567);
332        iter.setIndex(1);
333        assertEquals("Attributes", NumberFormat.Field.INTEGER, iter.getAttribute(NumberFormat.Field.INTEGER));
334        assertEquals("Attributes", 1, iter.getRunStart());
335        assertEquals("Attributes", 2, iter.getRunLimit());
336    }
337
338    @Test
339    public void TestEnglishShort() {
340        checkLocale(ULocale.ENGLISH, CompactStyle.SHORT, EnglishTestData);
341    }
342
343    @Test
344    public void TestArabicLongStyle() {
345        NumberFormat cdf =
346                CompactDecimalFormat.getInstance(new Locale("ar"), CompactStyle.LONG);
347        assertEquals("Arabic Long", "\u061C-\u0665\u066B\u0663 \u0623\u0644\u0641", cdf.format(-5300));
348    }
349
350    @Test
351    public void TestCsShort() {
352        checkLocale(ULocale.forLanguageTag("cs"), CompactStyle.SHORT, CsTestDataShort);
353    }
354
355    @Test
356    public void TestSkLong() {
357        checkLocale(ULocale.forLanguageTag("sk"), CompactStyle.LONG, SkTestDataLong);
358    }
359
360    @Test
361    public void TestSerbianShort() {
362        checkLocale(ULocale.forLanguageTag("sr"), CompactStyle.SHORT, SerbianTestDataShort);
363    }
364
365    @Test
366    public void TestSerbianLong() {
367        checkLocale(ULocale.forLanguageTag("sr"), CompactStyle.LONG, SerbianTestDataLong);
368    }
369
370    @Test
371    public void TestSerbianLongNegative() {
372        checkLocale(ULocale.forLanguageTag("sr"), CompactStyle.LONG, SerbianTestDataLongNegative);
373    }
374
375    @Test
376    public void TestJapaneseShort() {
377        checkLocale(ULocale.JAPANESE, CompactStyle.SHORT, JapaneseTestData);
378    }
379
380    @Test
381    public void TestSwahiliShort() {
382        checkLocale(ULocale.forLanguageTag("sw"), CompactStyle.SHORT, SwahiliTestData);
383    }
384
385    @Test
386    public void TestSwahiliShortNegative() {
387        checkLocale(ULocale.forLanguageTag("sw"), CompactStyle.SHORT, SwahiliTestDataNegative);
388    }
389
390    @Test
391    public void TestEnglishCurrency() {
392        checkLocale(ULocale.ENGLISH, CompactStyle.SHORT, EnglishCurrencyTestData);
393    }
394
395    @Test
396    public void TestGermanCurrency() {
397        checkLocale(ULocale.GERMAN, CompactStyle.SHORT, GermanCurrencyTestData);
398    }
399
400    @Test
401    public void TestChineseCurrency() {
402        checkLocale(ULocale.CHINESE, CompactStyle.SHORT, ChineseCurrencyTestData);
403    }
404
405    @Test
406    public void TestFieldPosition() {
407        CompactDecimalFormat cdf = getCDFInstance(
408                ULocale.forLanguageTag("sw"), CompactStyle.SHORT);
409        FieldPosition fp = new FieldPosition(0);
410        StringBuffer sb = new StringBuffer();
411        cdf.format(1234567f, sb, fp);
412        assertEquals("fp string", "M1.2", sb.toString());
413        assertEquals("fp start", 1, fp.getBeginIndex());
414        assertEquals("fp end", 2, fp.getEndIndex());
415    }
416
417    @Test
418    public void TestEquals() {
419        CompactDecimalFormat cdf = CompactDecimalFormat.getInstance(
420                ULocale.forLanguageTag("sw"), CompactStyle.SHORT);
421        CompactDecimalFormat equalsCdf = CompactDecimalFormat.getInstance(
422                ULocale.forLanguageTag("sw"), CompactStyle.SHORT);
423        CompactDecimalFormat notEqualsCdf = CompactDecimalFormat.getInstance(
424                ULocale.forLanguageTag("sw"), CompactStyle.LONG);
425        assertEquals("equals", cdf, equalsCdf);
426        assertNotEquals("not equals", cdf, notEqualsCdf);
427
428    }
429
430    @Test
431    public void TestBig() {
432        CompactDecimalFormat cdf = CompactDecimalFormat.getInstance(
433                ULocale.ENGLISH, CompactStyle.LONG);
434        BigInteger source_int = new BigInteger("31415926535897932384626433");
435        assertEquals("BigInteger format wrong: ", "31,000,000,000,000 trillion",
436                     cdf.format(source_int));
437        BigDecimal source_dec = new BigDecimal(source_int);
438        assertEquals("BigDecimal format wrong: ", "31,000,000,000,000 trillion",
439                     cdf.format(source_dec));
440    }
441
442    @Test
443    public void TestParsing() {
444        CompactDecimalFormat cdf = CompactDecimalFormat.getInstance(
445                ULocale.ENGLISH, CompactStyle.LONG);
446        try{
447            cdf.parse("Parse for failure", new ParsePosition(0));
448        } catch(UnsupportedOperationException e) {
449            // Exception expected, thus return.
450            return;
451        }
452        fail("Parsing currently unsupported, expected test to fail but passed");
453    }
454
455    public void checkLocale(ULocale locale, CompactStyle style, Object[][] testData) {
456        CompactDecimalFormat cdf = getCDFInstance(locale, style);
457        checkCdf(locale + " (" + locale.getDisplayName(locale) + ") for ", cdf, testData);
458    }
459
460    private void checkCdf(String title, CompactDecimalFormat cdf, Object[][] testData) {
461        for (Object[] row : testData) {
462            Object source = row[0];
463            Object expected = row[1];
464            assertEquals(title + source, expected,
465                    cdf.format(source));
466        }
467    }
468
469    private static String iterToString(CharacterIterator iter) {
470        StringBuilder builder = new StringBuilder();
471        for (char c = iter.current(); c != CharacterIterator.DONE; c = iter.next()) {
472            builder.append(c);
473        }
474        return builder.toString();
475    }
476
477    private static CompactDecimalFormat getCDFInstance(ULocale locale, CompactStyle style) {
478        CompactDecimalFormat result = CompactDecimalFormat.getInstance(locale, style);
479        // Our tests are written for two significant digits. We set explicitly here
480        // because default significant digits may change.
481        result.setMaximumSignificantDigits(2);
482        return result;
483    }
484
485    @Test
486    public void TestNordic() {
487        if (logKnownIssue("cldrbug:9465","CDF(12,000) for no_NO shouldn't be 12 (12K or similar)")) {
488            return;
489        }
490        String result = CompactDecimalFormat.getInstance( new ULocale("no_NO"),
491                CompactDecimalFormat.CompactStyle.SHORT ).format(12000);
492        assertNotEquals("CDF(12,000) for no_NO shouldn't be 12 (12K or similar)", "12", result);
493    }
494
495    @Test
496    public void TestWriteAndReadObject() throws IOException {
497        ByteArrayOutputStream baos = new ByteArrayOutputStream();
498        ObjectOutputStream objoutstream = new ObjectOutputStream(baos);
499        CompactDecimalFormat cdf = CompactDecimalFormat.getInstance(
500                ULocale.ENGLISH, CompactStyle.LONG);
501
502        try {
503            objoutstream.writeObject(cdf);
504        } catch (NotSerializableException e) {
505            if (logKnownIssue("10494", "PluralRules is not serializable")) {
506                logln("NotSerializableException thrown when serializing CopactDecimalFormat");
507            } else {
508                errln("NotSerializableException thrown when serializing CopactDecimalFormat");
509            }
510        } finally {
511            objoutstream.close();
512        }
513
514        // This test case relies on serialized byte stream which might be premature
515        ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
516        ObjectInputStream objinstream = new ObjectInputStream(bais);
517
518        try {
519            cdf = (CompactDecimalFormat) objinstream.readObject();
520        } catch (NotSerializableException e) {
521            if (logKnownIssue("10494", "PluralRules is not de-serializable")) {
522                logln("NotSerializableException thrown when deserializing CopactDecimalFormat");
523            } else {
524                errln("NotSerializableException thrown when deserializing CopactDecimalFormat");
525            }
526        } catch (ClassNotFoundException e) {
527            errln("ClassNotFoundException: " + e.getMessage());
528        } finally {
529            objinstream.close();
530        }
531    }
532
533    @Test
534    public void TestBug12422() {
535        CompactDecimalFormat cdf;
536        String result;
537
538        // Bug #12422
539        cdf = CompactDecimalFormat.getInstance(new ULocale("ar", "SA"), CompactDecimalFormat.CompactStyle.LONG);
540        result = cdf.format(43000);
541        assertEquals("CDF should correctly format 43000 in 'ar'", "٤٣ ألف", result);
542
543        // Bug #12449
544        cdf = CompactDecimalFormat.getInstance(new ULocale("ar"), CompactDecimalFormat.CompactStyle.SHORT);
545        cdf.setMaximumSignificantDigits(3);
546        result = cdf.format(1234);
547        assertEquals("CDF should correctly format 1234 with 3 significant digits in 'ar'", "١٫٢٣ ألف", result);
548
549        // Check currency formatting as well
550        cdf = CompactDecimalFormat.getInstance(new ULocale("ar"), CompactDecimalFormat.CompactStyle.SHORT);
551        result = cdf.format(new CurrencyAmount(43000f, Currency.getInstance("USD")));
552        assertEquals("CDF should correctly format 43000 with currency in 'ar'", "US$ ٤٣ ألف", result);
553        result = cdf.format(new CurrencyAmount(-43000f, Currency.getInstance("USD")));
554        assertEquals("CDF should correctly format -43000 with currency in 'ar'", "US$ ؜-٤٣ ألف", result);
555
556        // Extra locale with different positive/negative formats
557        cdf = CompactDecimalFormat.getInstance(new ULocale("fi"), CompactDecimalFormat.CompactStyle.SHORT);
558        result = cdf.format(new CurrencyAmount(43000f, Currency.getInstance("USD")));
559        assertEquals("CDF should correctly format 43000 with currency in 'fi'", "43 t. $", result);
560        result = cdf.format(new CurrencyAmount(-43000f, Currency.getInstance("USD")));
561        assertEquals("CDF should correctly format -43000 with currency in 'fi'", "−43 t. $", result);
562    }
563
564
565    @Test
566    public void TestBug12689() {
567        if (logKnownIssue("12689", "CDF fails for numbers less than 1 thousand in most locales")) {
568            return;
569        }
570
571        CompactDecimalFormat cdf;
572        String result;
573
574        cdf = CompactDecimalFormat.getInstance(ULocale.forLanguageTag("en"), CompactStyle.SHORT);
575        result = cdf.format(new CurrencyAmount(123, Currency.getInstance("USD")));
576        assertEquals("CDF should correctly format 123 with currency in 'en'", "$120", result);
577
578        cdf = CompactDecimalFormat.getInstance(ULocale.forLanguageTag("it"), CompactStyle.SHORT);
579        result = cdf.format(new CurrencyAmount(123, Currency.getInstance("EUR")));
580        assertEquals("CDF should correctly format 123 with currency in 'it'", "120 €", result);
581    }
582
583    @Test
584    public void TestBug12688() {
585        if (logKnownIssue("12688", "CDF fails for numbers less than 1 million in 'it'")) {
586            return;
587        }
588
589        CompactDecimalFormat cdf;
590        String result;
591
592        cdf = CompactDecimalFormat.getInstance(ULocale.forLanguageTag("it"), CompactStyle.SHORT);
593        result = cdf.format(new CurrencyAmount(123000, Currency.getInstance("EUR")));
594        assertEquals("CDF should correctly format 123000 with currency in 'it'", "120000 €", result);
595    }
596}
597