1 /* 2 ******************************************************************************* 3 * Copyright (C) 2001-2012, International Business Machines Corporation and * 4 * others. All Rights Reserved. * 5 ******************************************************************************* 6 */ 7 8 /** 9 * Port From: ICU4C v1.8.1 : format : NumberFormatRegressionTest 10 * Source File: $ICU4CRoot/source/test/intltest/numrgts.cpp 11 **/ 12 13 package com.ibm.icu.dev.test.format; 14 15 import java.io.ByteArrayInputStream; 16 import java.io.IOException; 17 import java.io.ObjectInputStream; 18 import java.text.ParseException; 19 import java.text.ParsePosition; 20 import java.util.Date; 21 import java.util.Locale; 22 23 import com.ibm.icu.text.DateFormat; 24 import com.ibm.icu.text.DecimalFormat; 25 import com.ibm.icu.text.DecimalFormatSymbols; 26 import com.ibm.icu.text.NumberFormat; 27 import com.ibm.icu.util.Calendar; 28 import com.ibm.icu.util.ULocale; 29 30 /** 31 * Performs regression test for MessageFormat 32 **/ 33 public class NumberFormatRegressionTest extends com.ibm.icu.dev.test.TestFmwk { 34 main(String[] args)35 public static void main(String[] args) throws Exception{ 36 new NumberFormatRegressionTest().run(args); 37 } 38 39 /** 40 * alphaWorks upgrade 41 */ Test4161100()42 public void Test4161100() { 43 NumberFormat nf = NumberFormat.getInstance(Locale.US); 44 nf.setMinimumFractionDigits(1); 45 nf.setMaximumFractionDigits(1); 46 double a = -0.09; 47 String s = nf.format(a); 48 logln(a + " x " + 49 ((DecimalFormat) nf).toPattern() + " = " + s); 50 if (!s.equals("-0.1")) { 51 errln("FAIL"); 52 } 53 } 54 55 /** 56 * DateFormat should call setIntegerParseOnly(TRUE) on adopted 57 * NumberFormat objects. 58 */ TestJ691()59 public void TestJ691() { 60 61 Locale loc = new Locale("fr", "CH"); 62 63 // set up the input date string & expected output 64 String udt = "11.10.2000"; 65 String exp = "11.10.00"; 66 67 // create a Calendar for this locale 68 Calendar cal = Calendar.getInstance(loc); 69 70 // create a NumberFormat for this locale 71 NumberFormat nf = NumberFormat.getInstance(loc); 72 73 // *** Here's the key: We don't want to have to do THIS: 74 //nf.setParseIntegerOnly(true); 75 76 // create the DateFormat 77 DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT, loc); 78 79 df.setCalendar(cal); 80 df.setNumberFormat(nf); 81 82 // set parsing to lenient & parse 83 Date ulocdat = new Date(); 84 df.setLenient(true); 85 try { 86 ulocdat = df.parse(udt); 87 } catch (java.text.ParseException pe) { 88 errln(pe.getMessage()); 89 } 90 // format back to a string 91 String outString = df.format(ulocdat); 92 93 if (!outString.equals(exp)) { 94 errln("FAIL: " + udt + " => " + outString); 95 } 96 } 97 98 /** 99 * Test getIntegerInstance(); 100 */ Test4408066()101 public void Test4408066() { 102 103 NumberFormat nf1 = NumberFormat.getIntegerInstance(); 104 NumberFormat nf2 = NumberFormat.getIntegerInstance(Locale.CHINA); 105 106 //test isParseIntegerOnly 107 if (!nf1.isParseIntegerOnly() || !nf2.isParseIntegerOnly()) { 108 errln("Failed : Integer Number Format Instance should set setParseIntegerOnly(true)"); 109 } 110 111 //Test format 112 { 113 double[] data = { 114 -3.75, -2.5, -1.5, 115 -1.25, 0, 1.0, 116 1.25, 1.5, 2.5, 117 3.75, 10.0, 255.5 118 }; 119 String[] expected = { 120 "-4", "-2", "-2", 121 "-1", "0", "1", 122 "1", "2", "2", 123 "4", "10", "256" 124 }; 125 126 for (int i = 0; i < data.length; ++i) { 127 String result = nf1.format(data[i]); 128 if (!result.equals(expected[i])) { 129 errln("Failed => Source: " + Double.toString(data[i]) 130 + ";Formatted : " + result 131 + ";but expectted: " + expected[i]); 132 } 133 } 134 } 135 //Test parse, Parsing should stop at "." 136 { 137 String data[] = { 138 "-3.75", "-2.5", "-1.5", 139 "-1.25", "0", "1.0", 140 "1.25", "1.5", "2.5", 141 "3.75", "10.0", "255.5" 142 }; 143 long[] expected = { 144 -3, -2, -1, 145 -1, 0, 1, 146 1, 1, 2, 147 3, 10, 255 148 }; 149 150 for (int i = 0; i < data.length; ++i) { 151 Number n = null; 152 try { 153 n = nf1.parse(data[i]); 154 } catch (ParseException e) { 155 errln("Failed: " + e.getMessage()); 156 } 157 if (!(n instanceof Long) || (n instanceof Integer)) { 158 errln("Failed: Integer Number Format should parse string to Long/Integer"); 159 } 160 if (n.longValue() != expected[i]) { 161 errln("Failed=> Source: " + data[i] 162 + ";result : " + n.toString() 163 + ";expected :" + Long.toString(expected[i])); 164 } 165 } 166 } 167 } 168 169 //Test New serialized DecimalFormat(2.0) read old serialized forms of DecimalFormat(1.3.1.1) TestSerialization()170 public void TestSerialization() throws IOException{ 171 byte[][] contents = NumberFormatSerialTestData.getContent(); 172 double data = 1234.56; 173 String[] expected = { 174 "1,234.56", "$1,234.56", "123,456%", "1.23456E3"}; 175 for (int i = 0; i < 4; ++i) { 176 ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(contents[i])); 177 try { 178 NumberFormat format = (NumberFormat) ois.readObject(); 179 String result = format.format(data); 180 if (result.equals(expected[i])) { 181 logln("OK: Deserialized bogus NumberFormat(new version read old version)"); 182 } else { 183 errln("FAIL: the test data formats are not euqal"); 184 } 185 } catch (Exception e) { 186 warnln("FAIL: " + e.getMessage()); 187 } 188 } 189 } 190 191 /* 192 * Test case for JB#5509, strict parsing issue 193 */ TestJB5509()194 public void TestJB5509() { 195 String[] data = { 196 "1,2", 197 "1.2", 198 "1,2.5", 199 "1,23.5", 200 "1,234.5", 201 "1,234", 202 "1,234,567", 203 "1,234,567.8", 204 "1,234,5", 205 "1,234,5.6", 206 "1,234,56.7" 207 }; 208 boolean[] expected = { // false for expected parse failure 209 false, 210 true, 211 false, 212 false, 213 true, 214 true, 215 true, 216 true, 217 false, 218 false, 219 false, 220 false 221 }; 222 223 DecimalFormat df = new DecimalFormat("#,##0.###", new DecimalFormatSymbols(new ULocale("en_US"))); 224 df.setParseStrict(true); 225 for (int i = 0; i < data.length; i++) { 226 try { 227 df.parse(data[i]); 228 if (!expected[i]) { 229 errln("Failed: ParseException must be thrown for string " + data[i]); 230 } 231 } catch (ParseException pe) { 232 if (expected[i]) { 233 errln("Failed: ParseException must not be thrown for string " + data[i]); 234 } 235 } 236 } 237 } 238 239 /* 240 * Test case for ticket#5698 - parsing extremely large/small values 241 */ TestT5698()242 public void TestT5698() { 243 final String[] data = { 244 "12345679E66666666666666666", 245 "-12345679E66666666666666666", 246 ".1E2147483648", // exponent > max int 247 ".1E2147483647", // exponent == max int 248 ".1E-2147483648", // exponent == min int 249 ".1E-2147483649", // exponent < min int 250 "1.23E350", // value > max double 251 "1.23E300", // value < max double 252 "-1.23E350", // value < min double 253 "-1.23E300", // value > min double 254 "4.9E-324", // value = smallest non-zero double 255 "1.0E-325", // 0 < value < smallest non-zero positive double0 256 "-1.0E-325", // 0 > value > largest non-zero negative double 257 }; 258 final double[] expected = { 259 Double.POSITIVE_INFINITY, 260 Double.NEGATIVE_INFINITY, 261 Double.POSITIVE_INFINITY, 262 Double.POSITIVE_INFINITY, 263 0.0, 264 0.0, 265 Double.POSITIVE_INFINITY, 266 1.23e300d, 267 Double.NEGATIVE_INFINITY, 268 -1.23e300d, 269 4.9e-324d, 270 0.0, 271 -0.0, 272 }; 273 274 NumberFormat nfmt = NumberFormat.getInstance(); 275 276 for (int i = 0; i < data.length; i++) { 277 try { 278 Number n = nfmt.parse(data[i]); 279 if (expected[i] != n.doubleValue()) { 280 errln("Failed: Parsed result for " + data[i] + ": " 281 + n.doubleValue() + " / expected: " + expected[i]); 282 } 283 } catch (ParseException pe) { 284 errln("Failed: ParseException is thrown for " + data[i]); 285 } 286 } 287 } TestSurrogatesParsing()288 public void TestSurrogatesParsing() { // Test parsing of numbers that use digits from the supplemental planes. 289 final String[] data = { 290 "1\ud801\udca2,3\ud801\udca45.67", // 291 "\ud801\udca1\ud801\udca2,\ud801\udca3\ud801\udca4\ud801\udca5.\ud801\udca6\ud801\udca7\ud801\udca8", // 292 "\ud835\udfd2.\ud835\udfd7E-\ud835\udfd1", 293 "\ud835\udfd3.8E-0\ud835\udfd0" 294 }; 295 final double[] expected = { 296 12345.67, 297 12345.678, 298 0.0049, 299 0.058 300 }; 301 302 NumberFormat nfmt = NumberFormat.getInstance(); 303 304 for (int i = 0; i < data.length; i++) { 305 try { 306 Number n = nfmt.parse(data[i]); 307 if (expected[i] != n.doubleValue()) { 308 errln("Failed: Parsed result for " + data[i] + ": " 309 + n.doubleValue() + " / expected: " + expected[i]); 310 } 311 } catch (ParseException pe) { 312 errln("Failed: ParseException is thrown for " + data[i]); 313 } 314 } 315 } 316 checkNBSPPatternRtNum(String testcase, NumberFormat nf, double myNumber)317 void checkNBSPPatternRtNum(String testcase, NumberFormat nf, double myNumber) { 318 String myString = nf.format(myNumber); 319 320 double aNumber; 321 try { 322 aNumber = nf.parse(myString).doubleValue(); 323 } catch (ParseException e) { 324 // TODO Auto-generated catch block 325 errln("FAIL: " + testcase +" - failed to parse. " + e.toString()); 326 return; 327 } 328 if(Math.abs(aNumber-myNumber)>.001) { 329 errln("FAIL: "+testcase+": formatted "+myNumber+", parsed into "+aNumber+"\n"); 330 } else { 331 logln("PASS: "+testcase+": formatted "+myNumber+", parsed into "+aNumber+"\n"); 332 } 333 } 334 checkNBSPPatternRT(String testcase, NumberFormat nf)335 void checkNBSPPatternRT(String testcase, NumberFormat nf) { 336 checkNBSPPatternRtNum(testcase, nf, 12345.); 337 checkNBSPPatternRtNum(testcase, nf, -12345.); 338 } 339 TestNBSPInPattern()340 public void TestNBSPInPattern() { 341 NumberFormat nf = null; 342 String testcase; 343 344 345 testcase="ar_AE UNUM_CURRENCY"; 346 nf = NumberFormat.getCurrencyInstance(new ULocale("ar_AE")); 347 checkNBSPPatternRT(testcase, nf); 348 // if we don't have CLDR 1.6 data, bring out the problem anyways 349 350 String SPECIAL_PATTERN = "\u00A4\u00A4'\u062f.\u0625.\u200f\u00a0'###0.00"; 351 testcase = "ar_AE special pattern: " + SPECIAL_PATTERN; 352 nf = new DecimalFormat(); 353 ((DecimalFormat)nf).applyPattern(SPECIAL_PATTERN); 354 checkNBSPPatternRT(testcase, nf); 355 356 } 357 358 /* 359 * Test case for #9293 360 * Parsing currency in strict mode 361 */ TestT9293()362 public void TestT9293() { 363 NumberFormat fmt = NumberFormat.getCurrencyInstance(); 364 fmt.setParseStrict(true); 365 366 final int val = 123456; 367 String txt = fmt.format(123456); 368 369 ParsePosition pos = new ParsePosition(0); 370 Number num = fmt.parse(txt, pos); 371 372 if (pos.getErrorIndex() >= 0) { 373 errln("FAIL: Parsing " + txt + " - error index: " + pos.getErrorIndex()); 374 } else if (val != num.intValue()) { 375 errln("FAIL: Parsed result: " + num + " - expected: " + val); 376 } 377 } 378 } 379