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) 2001-2011, International Business Machines Corporation and * 6 * others. All Rights Reserved. * 7 ******************************************************************************* 8 */ 9 10 /** 11 * Port From: ICU4C v1.8.1 : format : IntlTestNumberFormat 12 * Source File: $ICU4CRoot/source/test/intltest/tsnmfmt.cpp 13 **/ 14 15 package com.ibm.icu.dev.test.format; 16 import java.util.Locale; 17 import java.util.Random; 18 19 import org.junit.Test; 20 import org.junit.runner.RunWith; 21 import org.junit.runners.JUnit4; 22 23 import com.ibm.icu.dev.test.TestFmwk; 24 import com.ibm.icu.text.DecimalFormat; 25 import com.ibm.icu.text.NumberFormat; 26 27 /** 28 * This test does round-trip testing (format -> parse -> format -> parse -> etc.) of 29 * NumberFormat. 30 */ 31 @RunWith(JUnit4.class) 32 public class IntlTestNumberFormat extends TestFmwk { 33 34 public NumberFormat fNumberFormat; 35 36 /** 37 * Internal use 38 */ 39 private void _testLocale(Locale locale) { 40 String localeName = locale + " (" + locale.getDisplayName() + ")"; 41 42 logln("Number test " + localeName); 43 fNumberFormat = NumberFormat.getInstance(locale); 44 _testFormat(); 45 46 logln("Currency test " + localeName); 47 fNumberFormat = NumberFormat.getCurrencyInstance(locale); 48 _testFormat(); 49 50 logln("Percent test " + localeName); 51 fNumberFormat = NumberFormat.getPercentInstance(locale); 52 _testFormat(); 53 54 if (locale.toString().compareTo("en_US_POSIX") != 0 ) { 55 logln("Scientific test " + localeName); 56 fNumberFormat = NumberFormat.getScientificInstance(locale); 57 _testFormat(); 58 } 59 } 60 61 /** 62 * call _testFormat for currency, percent and plain number instances 63 */ 64 @Test 65 public void TestLocale() { 66 Locale locale = Locale.getDefault(); 67 String localeName = locale + " (" + locale.getDisplayName() + ")"; 68 69 logln("Number test " + localeName); 70 fNumberFormat = NumberFormat.getInstance(locale); 71 _testFormat(); 72 73 logln("Currency test " + localeName); 74 fNumberFormat = NumberFormat.getCurrencyInstance(locale); 75 _testFormat(); 76 77 logln("Percent test " + localeName); 78 fNumberFormat = NumberFormat.getPercentInstance(locale); 79 _testFormat(); 80 } 81 82 /** 83 * call tryIt with many variations, called by testLocale 84 */ 85 private void _testFormat() { 86 87 if (fNumberFormat == null){ 88 errln("**** FAIL: Null format returned by createXxxInstance."); 89 return; 90 } 91 DecimalFormat s = (DecimalFormat)fNumberFormat; 92 logln("pattern :" + s.toPattern()); 93 94 tryIt(-2.02147304840132e-68); 95 tryIt(3.88057859588817e-68); 96 tryIt(-2.64651110485945e+65); 97 tryIt(9.29526819488338e+64); 98 99 tryIt(-2.02147304840132e-100); 100 tryIt(3.88057859588817e-096); 101 tryIt(-2.64651110485945e+306); 102 tryIt(9.29526819488338e+250); 103 104 tryIt(-9.18228054496402e+64); 105 tryIt(-9.69413034454191e+64); 106 107 tryIt(-9.18228054496402e+255); 108 tryIt(-9.69413034454191e+273); 109 110 111 tryIt(1.234e-200); 112 tryIt(-2.3e-168); 113 114 tryIt(Double.NaN); 115 tryIt(Double.POSITIVE_INFINITY); 116 tryIt(Double.NEGATIVE_INFINITY); 117 118 tryIt(251887531); 119 tryIt(5e-20 / 9); 120 tryIt(5e20 / 9); 121 tryIt(1.234e-50); 122 tryIt(9.99999999999996); 123 tryIt(9.999999999999996); 124 125 tryIt(5.06e-27); 126 127 tryIt(Integer.MIN_VALUE); 128 tryIt(Integer.MAX_VALUE); 129 tryIt((double)Integer.MIN_VALUE); 130 tryIt((double)Integer.MAX_VALUE); 131 tryIt(Integer.MIN_VALUE - 1.0); 132 tryIt(Integer.MAX_VALUE + 1.0); 133 134 tryIt(5.0 / 9.0 * 1e-20); 135 tryIt(4.0 / 9.0 * 1e-20); 136 tryIt(5.0 / 9.0 * 1e+20); 137 tryIt(4.0 / 9.0 * 1e+20); 138 139 tryIt(2147483647.); 140 tryIt(0); 141 tryIt(0.0); 142 tryIt(1); 143 tryIt(10); 144 tryIt(100); 145 tryIt(-1); 146 tryIt(-10); 147 tryIt(-100); 148 tryIt(-1913860352); 149 150 Random random = createRandom(); // use test framework's random seed 151 for (int j = 0; j < 10; j++) { 152 double d = random.nextDouble()*2e10 - 1e10; 153 tryIt(d); 154 155 } 156 } 157 158 /** 159 * Perform tests using aNumber and fNumberFormat, called in many variations 160 */ 161 public void tryIt(double aNumber) { 162 final int DEPTH = 10; 163 double[] number = new double[DEPTH]; 164 String[] string = new String[DEPTH]; 165 int numberMatch = 0; 166 int stringMatch = 0; 167 boolean dump = false; 168 int i; 169 170 for (i = 0; i < DEPTH; i++) { 171 if (i == 0) { 172 number[i] = aNumber; 173 } else { 174 try { 175 number[i - 1] = fNumberFormat.parse(string[i - 1]).doubleValue(); 176 } catch(java.text.ParseException pe) { 177 errln("**** FAIL: Parse of " + string[i-1] + " failed."); 178 dump = true; 179 break; 180 } 181 } 182 183 string[i] = fNumberFormat.format(number[i]); 184 if (i > 0) 185 { 186 if (numberMatch == 0 && number[i] == number[i-1]) 187 numberMatch = i; 188 else if (numberMatch > 0 && number[i] != number[i-1]) 189 { 190 errln("**** FAIL: Numeric mismatch after match."); 191 dump = true; 192 break; 193 } 194 if (stringMatch == 0 && string[i] == string[i-1]) 195 stringMatch = i; 196 else if (stringMatch > 0 && string[i] != string[i-1]) 197 { 198 errln("**** FAIL: String mismatch after match."); 199 dump = true; 200 break; 201 } 202 } 203 if (numberMatch > 0 && stringMatch > 0) 204 break; 205 206 if (i == DEPTH) 207 --i; 208 209 if (stringMatch > 2 || numberMatch > 2) 210 { 211 errln("**** FAIL: No string and/or number match within 2 iterations."); 212 dump = true; 213 } 214 215 if (dump) 216 { 217 for (int k=0; k<=i; ++k) 218 { 219 logln(k + ": " + number[k] + " F> " + 220 string[k] + " P> "); 221 } 222 } 223 } 224 } 225 226 /** 227 * perform tests using aNumber and fNumberFormat, called in many variations 228 **/ 229 public void tryIt(int aNumber) { 230 long number; 231 232 String stringNum = fNumberFormat.format(aNumber); 233 try { 234 number = fNumberFormat.parse(stringNum).longValue(); 235 } catch (java.text.ParseException pe) { 236 errln("**** FAIL: Parse of " + stringNum + " failed."); 237 return; 238 } 239 240 if (number != aNumber) { 241 errln("**** FAIL: Parse of " + stringNum + " failed. Got:" + number 242 + " Expected:" + aNumber); 243 } 244 245 } 246 247 /** 248 * test NumberFormat::getAvailableLocales 249 **/ 250 @Test 251 public void TestAvailableLocales() { 252 final Locale[] locales = NumberFormat.getAvailableLocales(); 253 int count = locales.length; 254 logln(count + " available locales"); 255 if (count != 0) 256 { 257 String all = ""; 258 for (int i = 0; i< count; ++i) 259 { 260 if (i!=0) 261 all += ", "; 262 all += locales[i].getDisplayName(); 263 } 264 logln(all); 265 } 266 else 267 errln("**** FAIL: Zero available locales or null array pointer"); 268 } 269 270 /** 271 * call testLocale for all locales 272 **/ 273 @Test 274 public void TestMonster() { 275 final String SEP = "============================================================\n"; 276 int count; 277 final Locale[] allLocales = NumberFormat.getAvailableLocales(); 278 Locale[] locales = allLocales; 279 count = locales.length; 280 if (count != 0) 281 { 282 if (TestFmwk.getExhaustiveness() < 10 && count > 6) { 283 count = 6; 284 locales = new Locale[6]; 285 locales[0] = allLocales[0]; 286 locales[1] = allLocales[1]; 287 locales[2] = allLocales[2]; 288 // In a quick test, make sure we test locales that use 289 // currency prefix, currency suffix, and choice currency 290 // logic. Otherwise bugs in these areas can slip through. 291 locales[3] = new Locale("ar", "AE", ""); 292 locales[4] = new Locale("cs", "CZ", ""); 293 locales[5] = new Locale("en", "IN", ""); 294 } 295 for (int i=0; i<count; ++i) 296 { 297 logln(SEP); 298 _testLocale(locales[i]); 299 } 300 } 301 302 logln(SEP); 303 } 304 } 305