1 /* 2 ******************************************************************************* 3 * Copyright (C) 2008-2014, International Business Machines Corporation and * 4 * others. All Rights Reserved. * 5 ******************************************************************************* 6 */ 7 package com.ibm.icu.dev.test.format; 8 9 import java.text.ParseException; 10 import java.text.ParsePosition; 11 import java.util.Locale; 12 13 import com.ibm.icu.dev.test.TestFmwk; 14 import com.ibm.icu.math.BigDecimal; 15 import com.ibm.icu.text.MeasureFormat; 16 import com.ibm.icu.text.NumberFormat; 17 import com.ibm.icu.text.TimeUnitFormat; 18 import com.ibm.icu.util.Measure; 19 import com.ibm.icu.util.MeasureUnit; 20 import com.ibm.icu.util.TimeUnit; 21 import com.ibm.icu.util.TimeUnitAmount; 22 import com.ibm.icu.util.ULocale; 23 24 /** 25 * @author markdavis 26 * 27 */ 28 public class TimeUnitTest extends TestFmwk { main(String[] args)29 public static void main(String[] args) throws Exception{ 30 new TimeUnitTest().run(args); 31 } 32 Test10219FractionalPlurals()33 public void Test10219FractionalPlurals() { 34 TimeUnitFormat tuf = new TimeUnitFormat(ULocale.ENGLISH, TimeUnitFormat.FULL_NAME); 35 String[] expected = {"1 minute", "1.5 minutes", "1.58 minutes"}; 36 for (int i = 2; i >= 0; i--) { 37 NumberFormat nf = NumberFormat.getNumberInstance(ULocale.ENGLISH); 38 nf.setRoundingMode(BigDecimal.ROUND_DOWN); 39 nf.setMaximumFractionDigits(i); 40 tuf.setNumberFormat(nf); 41 assertEquals("Test10219", expected[i], tuf.format(new TimeUnitAmount(1.588, TimeUnit.MINUTE))); 42 } 43 } 44 Test10219FactionalPluralsParse()45 public void Test10219FactionalPluralsParse() throws ParseException { 46 TimeUnitFormat tuf = new TimeUnitFormat(ULocale.ENGLISH, TimeUnitFormat.FULL_NAME); 47 ParsePosition ppos = new ParsePosition(0); 48 String parseString = "1 minutes"; 49 tuf.parseObject(parseString, ppos); 50 51 // Parsing should go all the way to the end of the string. 52 // We want the longest match, and we don't care if the plural form of the unit 53 // matches the plural form of the number. 54 assertEquals("Test10219FractionalPluralParse", parseString.length(), ppos.getIndex()); 55 } 56 TestBasic()57 public void TestBasic() { 58 String[] locales = {"en", "sl", "fr", "zh", "ar", "ru", "zh_Hant"}; 59 for ( int locIndex = 0; locIndex < locales.length; ++locIndex ) { 60 //System.out.println("locale: " + locales[locIndex]); 61 TimeUnitFormat[] formats = new TimeUnitFormat[] { 62 new TimeUnitFormat(new ULocale(locales[locIndex]), TimeUnitFormat.FULL_NAME), 63 new TimeUnitFormat(new ULocale(locales[locIndex]), TimeUnitFormat.ABBREVIATED_NAME), 64 65 }; 66 for (int style = TimeUnitFormat.FULL_NAME; 67 style <= TimeUnitFormat.ABBREVIATED_NAME; 68 ++style) { 69 final TimeUnit[] values = TimeUnit.values(); 70 for (int j = 0; j < values.length; ++j) { 71 final TimeUnit timeUnit = values[j]; 72 double[] tests = {0, 0.5, 1, 1.5, 2, 2.5, 3, 3.5, 5, 10, 100, 101.35}; 73 for (int i = 0; i < tests.length; ++i) { 74 TimeUnitAmount source = new TimeUnitAmount(tests[i], timeUnit); 75 String formatted = formats[style].format(source); 76 //System.out.println(formatted); 77 logln(tests[i] + " => " + formatted); 78 try { 79 // Style should not matter when parsing. 80 for (int parseStyle = TimeUnitFormat.FULL_NAME; parseStyle <= TimeUnitFormat.ABBREVIATED_NAME; parseStyle++) { 81 TimeUnitAmount result = (TimeUnitAmount) formats[parseStyle].parseObject(formatted); 82 if (result == null || !source.equals(result)) { 83 errln("No round trip: " + source + " => " + formatted + " => " + result); 84 } 85 } 86 } catch (ParseException e) { 87 errln(e.getMessage()); 88 } 89 } 90 } 91 } 92 } 93 } 94 TestAPI()95 public void TestAPI() { 96 TimeUnitFormat format = new TimeUnitFormat(); 97 format.setLocale(new ULocale("pt_BR")); 98 formatParsing(format); 99 format = new TimeUnitFormat(new ULocale("de")); 100 formatParsing(format); 101 format = new TimeUnitFormat(new ULocale("ja")); 102 format.setNumberFormat(NumberFormat.getNumberInstance(new ULocale("en"))); 103 formatParsing(format); 104 105 format = new TimeUnitFormat(); 106 ULocale es = new ULocale("es"); 107 format.setNumberFormat(NumberFormat.getNumberInstance(es)); 108 format.setLocale(es); 109 formatParsing(format); 110 111 format.setLocale(new Locale("pt_BR")); 112 formatParsing(format); 113 format = new TimeUnitFormat(new Locale("de")); 114 formatParsing(format); 115 format = new TimeUnitFormat(new Locale("ja")); 116 format.setNumberFormat(NumberFormat.getNumberInstance(new Locale("en"))); 117 formatParsing(format); 118 } 119 TestClone()120 public void TestClone() { 121 TimeUnitFormat tuf = new TimeUnitFormat(ULocale.ENGLISH, TimeUnitFormat.ABBREVIATED_NAME); 122 NumberFormat nf = NumberFormat.getInstance(); 123 tuf.setNumberFormat(nf); 124 TimeUnitFormat tufClone = (TimeUnitFormat) tuf.clone(); 125 tuf.setLocale(Locale.GERMAN); 126 assertEquals("", "1 hr", tufClone.format(new TimeUnitAmount(1, TimeUnit.HOUR))); 127 } 128 TestEqHashCode()129 public void TestEqHashCode() { 130 TimeUnitFormat tf = new TimeUnitFormat(ULocale.ENGLISH, TimeUnitFormat.FULL_NAME); 131 MeasureFormat tfeq = new TimeUnitFormat(ULocale.ENGLISH, TimeUnitFormat.FULL_NAME); 132 133 MeasureFormat tfne = new TimeUnitFormat(ULocale.ENGLISH, TimeUnitFormat.ABBREVIATED_NAME); 134 MeasureFormat tfne2 = new TimeUnitFormat(ULocale.GERMAN, TimeUnitFormat.FULL_NAME); 135 verifyEqualsHashCode(tf, tfeq, tfne); 136 verifyEqualsHashCode(tf, tfeq, tfne2); 137 } 138 TestGetLocale()139 public void TestGetLocale() { 140 TimeUnitFormat tf = new TimeUnitFormat(ULocale.GERMAN); 141 assertEquals("", ULocale.GERMAN, tf.getLocale(ULocale.VALID_LOCALE)); 142 } 143 144 /* 145 * @bug 7902 146 * This tests that requests for short unit names correctly fall back 147 * to long unit names for a locale where the locale data does not 148 * provide short unit names. As of CLDR 1.9, Greek is one such language. 149 */ TestGreek()150 public void TestGreek() { 151 String[] locales = {"el_GR", "el"}; 152 final TimeUnit[] units = new TimeUnit[]{ 153 TimeUnit.SECOND, 154 TimeUnit.MINUTE, 155 TimeUnit.HOUR, 156 TimeUnit.DAY, 157 TimeUnit.WEEK, 158 TimeUnit.MONTH, 159 TimeUnit.YEAR}; 160 int[] styles = new int[] {TimeUnitFormat.FULL_NAME, TimeUnitFormat.ABBREVIATED_NAME}; 161 int[] numbers = new int[] {1, 7}; 162 163 String[] expected = { 164 // "el_GR" 1 wide 165 "1 δευτερόλεπτο", 166 "1 λεπτό", 167 "1 ώρα", 168 "1 ημέρα", 169 "1 εβδομάδα", 170 "1 μήνας", 171 "1 έτος", 172 // "el_GR" 1 short 173 "1 δευτ.", 174 "1 λεπ.", 175 "1 ώρα", 176 "1 ημέρα", 177 "1 εβδ.", 178 "1 μήν.", 179 "1 έτ.", // year (one) 180 // "el_GR" 7 wide 181 "7 δευτερόλεπτα", 182 "7 λεπτά", 183 "7 ώρες", 184 "7 ημέρες", 185 "7 εβδομάδες", 186 "7 μήνες", 187 "7 έτη", 188 // "el_GR" 7 short 189 "7 δευτ.", 190 "7 λεπ.", 191 "7 ώρ.", // hour (other) 192 "7 ημέρες", 193 "7 εβδ.", 194 "7 μήν.", 195 "7 έτ.", // year (other) 196 // "el" 1 wide 197 "1 δευτερόλεπτο", 198 "1 λεπτό", 199 "1 ώρα", 200 "1 ημέρα", 201 "1 εβδομάδα", 202 "1 μήνας", 203 "1 έτος", 204 // "el" 1 short 205 "1 δευτ.", 206 "1 λεπ.", 207 "1 ώρα", 208 "1 ημέρα", 209 "1 εβδ.", 210 "1 μήν.", 211 "1 έτ.", // year (one) 212 // "el" 7 wide 213 "7 δευτερόλεπτα", 214 "7 λεπτά", 215 "7 ώρες", 216 "7 ημέρες", 217 "7 εβδομάδες", 218 "7 μήνες", 219 "7 έτη", 220 // "el" 7 short 221 "7 δευτ.", 222 "7 λεπ.", 223 "7 ώρ.", // hour (other) 224 "7 ημέρες", 225 "7 εβδ.", 226 "7 μήν.", 227 "7 έτ."}; // year (other 228 229 int counter = 0; 230 TimeUnitFormat timeUnitFormat; 231 TimeUnitAmount timeUnitAmount; 232 String formatted; 233 234 for ( int locIndex = 0; locIndex < locales.length; ++locIndex ) { 235 for( int numIndex = 0; numIndex < numbers.length; ++numIndex ) { 236 for ( int styleIndex = 0; styleIndex < styles.length; ++styleIndex ) { 237 for ( int unitIndex = 0; unitIndex < units.length; ++unitIndex ) { 238 239 timeUnitAmount = new TimeUnitAmount(numbers[numIndex], units[unitIndex]); 240 timeUnitFormat = new TimeUnitFormat(new ULocale(locales[locIndex]), styles[styleIndex]); 241 formatted = timeUnitFormat.format(timeUnitAmount); 242 243 assertEquals( 244 "locale: " + locales[locIndex] 245 + ", style: " + styles[styleIndex] 246 + ", units: " + units[unitIndex] 247 + ", value: " + numbers[numIndex], 248 expected[counter], formatted); 249 ++counter; 250 } 251 } 252 } 253 } 254 } 255 256 /** 257 * @bug9042 258 * Performs tests for Greek. 259 * This tests that if the plural count listed in time unit format does not 260 * match those in the plural rules for the locale, those plural count in 261 * time unit format will be ingored and subsequently, fall back will kick in 262 * which is tested above. 263 * Without data sanitization, setNumberFormat() would crash. 264 * As of CLDR shiped in ICU4.8, Greek is one such language. 265 */ TestGreekWithSanitization()266 public void TestGreekWithSanitization() { 267 ULocale loc = new ULocale("el"); 268 NumberFormat numfmt = NumberFormat.getInstance(loc); 269 TimeUnitFormat tuf = new TimeUnitFormat(loc); 270 tuf.parseObject("", new ParsePosition(0)); 271 tuf.setNumberFormat(numfmt); 272 } 273 274 formatParsing(TimeUnitFormat format)275 private void formatParsing(TimeUnitFormat format) { 276 final TimeUnit[] values = TimeUnit.values(); 277 for (int j = 0; j < values.length; ++j) { 278 final TimeUnit timeUnit = values[j]; 279 double[] tests = {0, 0.5, 1, 2, 3, 5}; 280 for (int i = 0; i < tests.length; ++i) { 281 TimeUnitAmount source = new TimeUnitAmount(tests[i], timeUnit); 282 String formatted = format.format(source); 283 //System.out.println(formatted); 284 logln(tests[i] + " => " + formatted); 285 try { 286 TimeUnitAmount result = (TimeUnitAmount) format.parseObject(formatted); 287 if (result == null || !source.equals(result)) { 288 errln("No round trip: " + source + " => " + formatted + " => " + result); 289 } 290 } catch (ParseException e) { 291 errln(e.getMessage()); 292 } 293 } 294 } 295 } 296 297 /* 298 * Tests the method public TimeUnitFormat(ULocale locale, int style), public TimeUnitFormat(Locale locale, int style) 299 */ 300 @SuppressWarnings("unused") TestTimeUnitFormat()301 public void TestTimeUnitFormat() { 302 // Tests when "if (style < FULL_NAME || style >= TOTAL_STYLES)" is true 303 // TOTAL_STYLES is 2 304 int[] cases = { TimeUnitFormat.FULL_NAME - 1, TimeUnitFormat.FULL_NAME - 2, 3 }; 305 for (int i = 0; i < cases.length; i++) { 306 try { 307 TimeUnitFormat tuf = new TimeUnitFormat(new ULocale("en_US"), cases[i]); 308 errln("TimeUnitFormat(ULocale,int) was suppose to return an " + "exception for a style value of " 309 + cases[i] + "passed into the constructor."); 310 } catch (Exception e) { 311 } 312 } 313 for (int i = 0; i < cases.length; i++) { 314 try { 315 TimeUnitFormat tuf = new TimeUnitFormat(new Locale("en_US"), cases[i]); 316 errln("TimeUnitFormat(ULocale,int) was suppose to return an " + "exception for a style value of " 317 + cases[i] + "passed into the constructor."); 318 } catch (Exception e) { 319 } 320 } 321 } 322 323 /* 324 * Tests the method public TimeUnitFormat setLocale(ULocale locale) public TimeUnitFormat setLocale(Locale locale) 325 */ TestSetLocale()326 public void TestSetLocale() { 327 // Tests when "if ( locale != this.locale )" is false 328 TimeUnitFormat tuf = new TimeUnitFormat(new ULocale("en_US")); 329 if (!tuf.setLocale(new ULocale("en_US")).equals(tuf) && !tuf.setLocale(new Locale("en_US")).equals(tuf)) { 330 errln("TimeUnitFormat.setLocale(ULocale) was suppose to " 331 + "return the same TimeUnitFormat object if the same " + "ULocale is entered as a parameter."); 332 } 333 } 334 335 /* 336 * Tests the method public TimeUnitFormat setNumberFormat(NumberFormat format) 337 */ TestSetNumberFormat()338 public void TestSetNumberFormat() { 339 TimeUnitFormat tuf = new TimeUnitFormat(); 340 341 // Tests when "if (format == this.format)" is false 342 // Tests when "if ( format == null )" is false 343 tuf.setNumberFormat(NumberFormat.getInstance()); 344 345 // Tests when "if (format == this.format)" is true 346 if (!tuf.setNumberFormat(NumberFormat.getInstance()).equals(tuf)) { 347 errln("TimeUnitFormat.setNumberFormat(NumberFormat) was suppose to " 348 + "return the same object when the same NumberFormat is passed."); 349 } 350 351 // Tests when "if ( format == null )" is true 352 // Tests when "if ( locale == null )" is true 353 if (!tuf.setNumberFormat(null).equals(tuf)) { 354 errln("TimeUnitFormat.setNumberFormat(NumberFormat) was suppose to " 355 + "return the same object when null is passed."); 356 } 357 358 TimeUnitFormat tuf1 = new TimeUnitFormat(new ULocale("en_US")); 359 360 // Tests when "if ( locale == null )" is false 361 tuf1.setNumberFormat(NumberFormat.getInstance()); 362 tuf1.setNumberFormat(null); 363 } 364 365 /* 366 * Tests the method public StringBuffer format(Object obj, ... 367 */ TestFormat()368 public void TestFormat() { 369 TimeUnitFormat tuf = new TimeUnitFormat(); 370 try { 371 tuf.format(new Integer("1"), null, null); 372 errln("TimeUnitFormat.format(Object,StringBuffer,FieldPosition) " 373 + "was suppose to return an exception because the Object " 374 + "parameter was not of type TimeUnitAmount."); 375 } catch (Exception e) { 376 } 377 } 378 379 /* Tests the method private void setup() from 380 * public Object parseObject(String source, ParsePosition pos) 381 * 382 */ TestSetup()383 public void TestSetup(){ 384 TimeUnitFormat tuf = new TimeUnitFormat(); 385 tuf.parseObject("", new ParsePosition(0)); 386 387 TimeUnitFormat tuf1 = new TimeUnitFormat(); 388 tuf1.setNumberFormat(NumberFormat.getInstance()); 389 tuf1.parseObject("", new ParsePosition(0)); 390 } 391 TestStandInForMeasureFormat()392 public void TestStandInForMeasureFormat() { 393 TimeUnitFormat tuf = new TimeUnitFormat(ULocale.FRENCH, TimeUnitFormat.ABBREVIATED_NAME); 394 Measure measure = new Measure(23, MeasureUnit.CELSIUS); 395 assertEquals("23 °C", "23 °C", tuf.format(measure)); 396 tuf = new TimeUnitFormat(ULocale.FRENCH, TimeUnitFormat.FULL_NAME); 397 assertEquals( 398 "70 pied et 5,3 pouces", 399 "70 pieds et 5,3 pouces", 400 tuf.formatMeasures( 401 new Measure(70, MeasureUnit.FOOT), 402 new Measure(5.3, MeasureUnit.INCH))); 403 assertEquals("getLocale", ULocale.FRENCH, tuf.getLocale()); 404 assertEquals("getNumberFormat", ULocale.FRENCH, tuf.getNumberFormat().getLocale(ULocale.VALID_LOCALE)); 405 assertEquals("getWidth", MeasureFormat.FormatWidth.WIDE, tuf.getWidth()); 406 } 407 verifyEqualsHashCode(Object o, Object eq, Object ne)408 private void verifyEqualsHashCode(Object o, Object eq, Object ne) { 409 assertEquals("verifyEqualsHashCodeSame", o, o); 410 assertEquals("verifyEqualsHashCodeEq", o, eq); 411 assertNotEquals("verifyEqualsHashCodeNe", o, ne); 412 assertNotEquals("verifyEqualsHashCodeEqTrans", eq, ne); 413 assertEquals("verifyEqualsHashCodeHashEq", o.hashCode(), eq.hashCode()); 414 415 // May be a flaky test, but generally should be true. 416 // May need to comment this out later. 417 assertNotEquals("verifyEqualsHashCodeHashNe", o.hashCode(), ne.hashCode()); 418 } 419 } 420