1/* 2 ******************************************************************************* 3 * Copyright (C) 1996-2015, Google, International Business Machines Corporation and 4 * others. All Rights Reserved. * 5 ******************************************************************************* 6 */ 7package com.ibm.icu.dev.test.format; 8 9import java.text.AttributedCharacterIterator; 10import java.text.CharacterIterator; 11import java.text.FieldPosition; 12import java.util.Collection; 13import java.util.HashMap; 14import java.util.LinkedHashSet; 15import java.util.Locale; 16import java.util.Map; 17 18import com.ibm.icu.dev.test.TestFmwk; 19import com.ibm.icu.text.CompactDecimalFormat; 20import com.ibm.icu.text.CompactDecimalFormat.CompactStyle; 21import com.ibm.icu.text.DecimalFormatSymbols; 22import com.ibm.icu.text.NumberFormat; 23import com.ibm.icu.text.PluralRules; 24import com.ibm.icu.util.ULocale; 25 26public class CompactDecimalFormatTest extends TestFmwk { 27 28 public static void main(String[] args) { 29 new CompactDecimalFormatTest().run(args); 30 } 31 32 Object[][] EnglishTestData = { 33 // default is 2 digits of accuracy 34 {0.0d, "0"}, 35 {0.01d, "0.01"}, 36 {0.1d, "0.1"}, 37 {1d, "1"}, 38 {12, "12"}, 39 {123, "120"}, 40 {1234, "1.2K"}, 41 {1000, "1K"}, 42 {1049, "1K"}, 43 {12345, "12K"}, 44 {123456, "120K"}, 45 {1234567, "1.2M"}, 46 {12345678, "12M"}, 47 {123456789, "120M"}, 48 {1234567890, "1.2B"}, 49 {12345678901f, "12B"}, 50 {123456789012f, "120B"}, 51 {1234567890123f, "1.2T"}, 52 {12345678901234f, "12T"}, 53 {123456789012345f, "120T"}, 54 {12345678901234567890f, "12000000T"}, 55 }; 56 57 Object[][] SerbianTestDataShort = { 58 {1234, "1,2\u00A0\u0445\u0438\u0459."}, 59 {12345, "12\u00a0хиљ."}, 60 {20789, "21\u00a0хиљ."}, 61 {123456, "120\u00a0хиљ."}, 62 {1234567, "1,2\u00a0мил."}, 63 {12345678, "12\u00a0мил."}, 64 {123456789, "120\u00a0мил."}, 65 {1234567890, "1,2\u00a0млрд."}, 66 {12345678901f, "12\u00a0млрд."}, 67 {123456789012f, "120\u00a0млрд."}, 68 {1234567890123f, "1,2\u00a0бил."}, 69 {12345678901234f, "12\u00a0бил."}, 70 {123456789012345f, "120\u00a0бил."}, 71 {1234567890123456f, "1200\u00a0бил."}, 72 }; 73 74 Object[][] SerbianTestDataLong = { 75 {1234, "1,2 хиљаде"}, 76 {12345, "12 хиљада"}, 77 {21789, "22 хиљаде"}, 78 {123456, "120 хиљада"}, 79 {999999, "1 милион"}, 80 {1234567, "1,2 милиона"}, 81 {12345678, "12 милиона"}, 82 {123456789, "120 милиона"}, 83 {1234567890, "1,2 милијарде"}, 84 {12345678901f, "12 милијарди"}, 85 {20890123456f, "21 милијарда"}, 86 {21890123456f, "22 милијарде"}, 87 {123456789012f, "120 милијарди"}, 88 {1234567890123f, "1,2 трилиона"}, 89 {12345678901234f, "12 трилиона"}, 90 {123456789012345f, "120 трилиона"}, 91 {1234567890123456f, "1.200 трилиона"}, 92 }; 93 94 Object[][] SerbianTestDataLongNegative = { 95 {-1234, "-1,2 хиљаде"}, 96 {-12345, "-12 хиљада"}, 97 {-21789, "-22 хиљаде"}, 98 {-123456, "-120 хиљада"}, 99 {-999999, "-1 милион"}, 100 {-1234567, "-1,2 милиона"}, 101 {-12345678, "-12 милиона"}, 102 {-123456789, "-120 милиона"}, 103 {-1234567890, "-1,2 милијарде"}, 104 {-12345678901f, "-12 милијарди"}, 105 {-20890123456f, "-21 милијарда"}, 106 {-21890123456f, "-22 милијарде"}, 107 {-123456789012f, "-120 милијарди"}, 108 {-1234567890123f, "-1,2 трилиона"}, 109 {-12345678901234f, "-12 трилиона"}, 110 {-123456789012345f, "-120 трилиона"}, 111 {-1234567890123456f, "-1.200 трилиона"}, 112 }; 113 114 Object[][] JapaneseTestData = { 115 {1234f, "1200"}, 116 {12345f, "1.2万"}, 117 {123456f, "12万"}, 118 {1234567f, "120万"}, 119 {12345678f, "1200万"}, 120 {123456789f, "1.2億"}, 121 {1234567890f, "12億"}, 122 {12345678901f, "120億"}, 123 {123456789012f, "1200億"}, 124 {1234567890123f, "1.2兆"}, 125 {12345678901234f, "12兆"}, 126 {123456789012345f, "120兆"}, 127 }; 128 129 Object[][] SwahiliTestData = { 130 {1234f, "elfu\u00a01.2"}, 131 {12345f, "elfu\u00a012"}, 132 {123456f, "elfu\u00A0120"}, 133 {1234567f, "M1.2"}, 134 {12345678f, "M12"}, 135 {123456789f, "M120"}, 136 {1234567890f, "B1.2"}, 137 {12345678901f, "B12"}, 138 {123456789012f, "B120"}, 139 {1234567890123f, "T1.2"}, 140 {12345678901234f, "T12"}, 141 {12345678901234567890f, "T12000000"}, 142 }; 143 144 Object[][] CsTestDataShort = { 145 {1000, "1\u00a0tis."}, 146 {1500, "1,5\u00a0tis."}, 147 {5000, "5\u00a0tis."}, 148 {23000, "23\u00a0tis."}, 149 {127123, "130\u00a0tis."}, 150 {1271234, "1,3\u00a0mil."}, 151 {12712345, "13\u00a0mil."}, 152 {127123456, "130\u00a0mil."}, 153 {1271234567f, "1,3\u00a0mld."}, 154 {12712345678f, "13\u00a0mld."}, 155 {127123456789f, "130\u00a0mld."}, 156 {1271234567890f, "1,3\u00a0bil."}, 157 {12712345678901f, "13\u00a0bil."}, 158 {127123456789012f, "130\u00a0bil."}, 159 }; 160 161 Object[][] SkTestDataLong = { 162 {1000, "1 tis\u00edc"}, 163 {1572, "1,6 tis\u00edca"}, 164 {5184, "5,2 tis\u00edca"}, 165 }; 166 167 Object[][] SwahiliTestDataNegative = { 168 {-1234f, "elfu\u00a0-1.2"}, 169 {-12345f, "elfu\u00a0-12"}, 170 {-123456f, "elfu\u00A0-120"}, 171 {-1234567f, "M-1.2"}, 172 {-12345678f, "M-12"}, 173 {-123456789f, "M-120"}, 174 {-1234567890f, "B-1.2"}, 175 {-12345678901f, "B-12"}, 176 {-123456789012f, "B-120"}, 177 {-1234567890123f, "T-1.2"}, 178 {-12345678901234f, "T-12"}, 179 {-12345678901234567890f, "T-12000000"}, 180 }; 181 182 Object[][] TestACoreCompactFormatList = { 183 {1000, "1K"}, 184 {1100, "1,1K"}, 185 {1200, "1,2Ks"}, 186 {2000, "2Ks"}, 187 }; 188 189 Object[][] TestACoreCompactFormatListCurrency = { 190 {1000, "1K$"}, 191 {1100, "1,1K$"}, 192 {1200, "1,2Ks$s"}, 193 {2000, "2Ks$s"}, 194 }; 195 196 public void TestACoreCompactFormat() { 197 Map<String,String[][]> affixes = new HashMap(); 198 affixes.put("one", new String[][] { 199 {"","",}, {"","",}, {"","",}, 200 {"","K"}, {"","K"}, {"","K"}, 201 {"","M"}, {"","M"}, {"","M"}, 202 {"","B"}, {"","B"}, {"","B"}, 203 {"","T"}, {"","T"}, {"","T"}, 204 }); 205 affixes.put("other", new String[][] { 206 {"","",}, {"","",}, {"","",}, 207 {"","Ks"}, {"","Ks"}, {"","Ks"}, 208 {"","Ms"}, {"","Ms"}, {"","Ms"}, 209 {"","Bs"}, {"","Bs"}, {"","Bs"}, 210 {"","Ts"}, {"","Ts"}, {"","Ts"}, 211 }); 212 213 Map<String,String[]> currencyAffixes = new HashMap(); 214 currencyAffixes.put("one", new String[] {"", "$"}); 215 currencyAffixes.put("other", new String[] {"", "$s"}); 216 217 long[] divisors = new long[] { 218 0,0,0, 219 1000, 1000, 1000, 220 1000000, 1000000, 1000000, 221 1000000000L, 1000000000L, 1000000000L, 222 1000000000000L, 1000000000000L, 1000000000000L}; 223 checkCore(affixes, null, divisors, TestACoreCompactFormatList); 224 checkCore(affixes, currencyAffixes, divisors, TestACoreCompactFormatListCurrency); 225 } 226 227 private void checkCore(Map<String, String[][]> affixes, Map<String, String[]> currencyAffixes, long[] divisors, Object[][] testItems) { 228 Collection<String> debugCreationErrors = new LinkedHashSet(); 229 CompactDecimalFormat cdf = new CompactDecimalFormat( 230 "#,###.00", 231 DecimalFormatSymbols.getInstance(new ULocale("fr")), 232 CompactStyle.SHORT, PluralRules.createRules("one: j is 1 or f is 1"), 233 divisors, affixes, currencyAffixes, 234 debugCreationErrors 235 ); 236 if (debugCreationErrors.size() != 0) { 237 for (String s : debugCreationErrors) { 238 errln("Creation error: " + s); 239 } 240 } else { 241 checkCdf("special cdf ", cdf, testItems); 242 } 243 } 244 245 public void TestDefaultSignificantDigits() { 246 // We are expecting two significant digits as default. 247 CompactDecimalFormat cdf = 248 CompactDecimalFormat.getInstance(ULocale.ENGLISH, CompactStyle.SHORT); 249 assertEquals("Default significant digits", "12K", cdf.format(12345)); 250 assertEquals("Default significant digits", "1.2K", cdf.format(1234)); 251 assertEquals("Default significant digits", "120", cdf.format(123)); 252 } 253 254 public void TestCharacterIterator() { 255 CompactDecimalFormat cdf = 256 getCDFInstance(ULocale.forLanguageTag("sw"), CompactStyle.SHORT); 257 AttributedCharacterIterator iter = cdf.formatToCharacterIterator(1234567); 258 assertEquals("CharacterIterator", "M1.2", iterToString(iter)); 259 iter = cdf.formatToCharacterIterator(1234567); 260 iter.setIndex(1); 261 assertEquals("Attributes", NumberFormat.Field.INTEGER, iter.getAttribute(NumberFormat.Field.INTEGER)); 262 assertEquals("Attributes", 1, iter.getRunStart()); 263 assertEquals("Attributes", 2, iter.getRunLimit()); 264 } 265 266 public void TestEnglishShort() { 267 checkLocale(ULocale.ENGLISH, CompactStyle.SHORT, EnglishTestData); 268 } 269 270 public void TestArabicLongStyle() { 271 NumberFormat cdf = 272 CompactDecimalFormat.getInstance(new Locale("ar"), CompactStyle.LONG); 273 assertEquals("Arabic Long", "\u200F-\u0665\u066B\u0663 \u0623\u0644\u0641", cdf.format(-5300)); 274 } 275 276 public void TestCsShort() { 277 checkLocale(ULocale.forLanguageTag("cs"), CompactStyle.SHORT, CsTestDataShort); 278 } 279 280 public void TestSkLong() { 281 checkLocale(ULocale.forLanguageTag("sk"), CompactStyle.LONG, SkTestDataLong); 282 } 283 284 public void TestSerbianShort() { 285 checkLocale(ULocale.forLanguageTag("sr"), CompactStyle.SHORT, SerbianTestDataShort); 286 } 287 288 public void TestSerbianLong() { 289 checkLocale(ULocale.forLanguageTag("sr"), CompactStyle.LONG, SerbianTestDataLong); 290 } 291 292 public void TestSerbianLongNegative() { 293 checkLocale(ULocale.forLanguageTag("sr"), CompactStyle.LONG, SerbianTestDataLongNegative); 294 } 295 296 public void TestJapaneseShort() { 297 checkLocale(ULocale.JAPANESE, CompactStyle.SHORT, JapaneseTestData); 298 } 299 300 public void TestSwahiliShort() { 301 checkLocale(ULocale.forLanguageTag("sw"), CompactStyle.SHORT, SwahiliTestData); 302 } 303 304 public void TestSwahiliShortNegative() { 305 checkLocale(ULocale.forLanguageTag("sw"), CompactStyle.SHORT, SwahiliTestDataNegative); 306 } 307 308 public void TestFieldPosition() { 309 CompactDecimalFormat cdf = getCDFInstance( 310 ULocale.forLanguageTag("sw"), CompactStyle.SHORT); 311 FieldPosition fp = new FieldPosition(0); 312 StringBuffer sb = new StringBuffer(); 313 cdf.format(1234567f, sb, fp); 314 assertEquals("fp string", "M1.2", sb.toString()); 315 assertEquals("fp start", 1, fp.getBeginIndex()); 316 assertEquals("fp end", 2, fp.getEndIndex()); 317 } 318 319 public void TestEquals() { 320 CompactDecimalFormat cdf = CompactDecimalFormat.getInstance( 321 ULocale.forLanguageTag("sw"), CompactStyle.SHORT); 322 CompactDecimalFormat equalsCdf = CompactDecimalFormat.getInstance( 323 ULocale.forLanguageTag("sw"), CompactStyle.SHORT); 324 CompactDecimalFormat notEqualsCdf = CompactDecimalFormat.getInstance( 325 ULocale.forLanguageTag("sw"), CompactStyle.LONG); 326 assertEquals("equals", cdf, equalsCdf); 327 assertNotEquals("not equals", cdf, notEqualsCdf); 328 329 } 330 331 public void checkLocale(ULocale locale, CompactStyle style, Object[][] testData) { 332 CompactDecimalFormat cdf = getCDFInstance(locale, style); 333 checkCdf(locale + " (" + locale.getDisplayName(locale) + ") for ", cdf, testData); 334 } 335 336 private void checkCdf(String title, CompactDecimalFormat cdf, Object[][] testData) { 337 for (Object[] row : testData) { 338 Object source = row[0]; 339 Object expected = row[1]; 340 assertEquals(title + source, expected, 341 cdf.format(source)); 342 } 343 } 344 345 private static String iterToString(CharacterIterator iter) { 346 StringBuilder builder = new StringBuilder(); 347 for (char c = iter.current(); c != CharacterIterator.DONE; c = iter.next()) { 348 builder.append(c); 349 } 350 return builder.toString(); 351 } 352 353 private static CompactDecimalFormat getCDFInstance(ULocale locale, CompactStyle style) { 354 CompactDecimalFormat result = CompactDecimalFormat.getInstance(locale, style); 355 // Our tests are written for two significant digits. We set explicitly here 356 // because default significant digits may change. 357 result.setMaximumSignificantDigits(2); 358 return result; 359 } 360} 361