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) 2013-2016, 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.ObjectInputStream; 15import java.io.ObjectOutputStream; 16import java.io.Serializable; 17import java.lang.reflect.Field; 18import java.text.FieldPosition; 19import java.util.ArrayList; 20import java.util.Collections; 21import java.util.Comparator; 22import java.util.HashMap; 23import java.util.HashSet; 24import java.util.List; 25import java.util.Locale; 26import java.util.Map; 27import java.util.Set; 28import java.util.TreeMap; 29 30import org.junit.Test; 31 32import com.ibm.icu.dev.test.TestFmwk; 33import com.ibm.icu.dev.test.serializable.SerializableTestUtility; 34import com.ibm.icu.impl.Pair; 35import com.ibm.icu.impl.Utility; 36import com.ibm.icu.math.BigDecimal; 37import com.ibm.icu.text.MeasureFormat; 38import com.ibm.icu.text.MeasureFormat.FormatWidth; 39import com.ibm.icu.text.NumberFormat; 40import com.ibm.icu.util.Currency; 41import com.ibm.icu.util.Measure; 42import com.ibm.icu.util.MeasureUnit; 43import com.ibm.icu.util.TimeUnit; 44import com.ibm.icu.util.TimeUnitAmount; 45import com.ibm.icu.util.ULocale; 46 47/** 48 * See https://sites.google.com/site/icusite/processes/release/tasks/standards?pli=1 49 * for information on how to update with each new release. 50 * @author markdavis 51 */ 52public class MeasureUnitTest extends TestFmwk { 53 54 static class OrderedPair<F extends Comparable, S extends Comparable> extends Pair<F, S> implements Comparable<OrderedPair<F, S>> { 55 56 OrderedPair(F first, S second) { 57 super(first, second); 58 } 59 60 public static <F extends Comparable, S extends Comparable> OrderedPair<F, S> of(F first, S second) { 61 if (first == null || second == null) { 62 throw new IllegalArgumentException("OrderedPair.of requires non null values."); 63 } 64 return new OrderedPair<F, S>(first, second); 65 } 66 67 @Override 68 public int compareTo(OrderedPair<F, S> other) { 69 int result = first.compareTo(other.first); 70 if (result != 0) { 71 return result; 72 } 73 return second.compareTo(other.second); 74 } 75 } 76 77 private static final String[] DRAFT_VERSIONS = {"57", "58"}; 78 79 private static final HashSet<String> DRAFT_VERSION_SET = new HashSet<String>(); 80 81 private static final HashSet<String> TIME_CODES = new HashSet<String>(); 82 83 private static final String[][] JAVA_VERSIONS = { 84 {"G_FORCE", "53"}, 85 {"DEGREE", "53"}, 86 {"ARC_MINUTE", "53"}, 87 {"ARC_SECOND", "53"}, 88 {"ACRE", "53"}, 89 {"HECTARE", "53"}, 90 {"SQUARE_FOOT", "53"}, 91 {"SQUARE_KILOMETER", "53"}, 92 {"SQUARE_METER", "53"}, 93 {"SQUARE_MILE", "53"}, 94 {"MILLISECOND", "53"}, 95 {"CENTIMETER", "53"}, 96 {"FOOT", "53"}, 97 {"INCH", "53"}, 98 {"KILOMETER", "53"}, 99 {"LIGHT_YEAR", "53"}, 100 {"METER", "53"}, 101 {"MILE", "53"}, 102 {"MILLIMETER", "53"}, 103 {"PICOMETER", "53"}, 104 {"YARD", "53"}, 105 {"GRAM", "53"}, 106 {"KILOGRAM", "53"}, 107 {"OUNCE", "53"}, 108 {"POUND", "53"}, 109 {"HORSEPOWER", "53"}, 110 {"KILOWATT", "53"}, 111 {"WATT", "53"}, 112 {"HECTOPASCAL", "53"}, 113 {"INCH_HG", "53"}, 114 {"MILLIBAR", "53"}, 115 {"KILOMETER_PER_HOUR", "53"}, 116 {"METER_PER_SECOND", "53"}, 117 {"MILE_PER_HOUR", "53"}, 118 {"CELSIUS", "53"}, 119 {"FAHRENHEIT", "53"}, 120 {"CUBIC_KILOMETER", "53"}, 121 {"CUBIC_MILE", "53"}, 122 {"LITER", "53"}, 123 {"YEAR", "53"}, 124 {"MONTH", "53"}, 125 {"WEEK", "53"}, 126 {"DAY", "53"}, 127 {"HOUR", "53"}, 128 {"MINUTE", "53"}, 129 {"SECOND", "53"}, 130 {"METER_PER_SECOND_SQUARED", "54"}, 131 {"RADIAN", "54"}, 132 {"SQUARE_CENTIMETER", "54"}, 133 {"SQUARE_INCH", "54"}, 134 {"SQUARE_YARD", "54"}, 135 {"LITER_PER_KILOMETER", "54"}, 136 {"MILE_PER_GALLON", "54"}, 137 {"BIT", "54"}, 138 {"BYTE", "54"}, 139 {"GIGABIT", "54"}, 140 {"GIGABYTE", "54"}, 141 {"KILOBIT", "54"}, 142 {"KILOBYTE", "54"}, 143 {"MEGABIT", "54"}, 144 {"MEGABYTE", "54"}, 145 {"TERABIT", "54"}, 146 {"TERABYTE", "54"}, 147 {"MICROSECOND", "54"}, 148 {"NANOSECOND", "54"}, 149 {"AMPERE", "54"}, 150 {"MILLIAMPERE", "54"}, 151 {"OHM", "54"}, 152 {"VOLT", "54"}, 153 {"CALORIE", "54"}, 154 {"FOODCALORIE", "54"}, 155 {"JOULE", "54"}, 156 {"KILOCALORIE", "54"}, 157 {"KILOJOULE", "54"}, 158 {"KILOWATT_HOUR", "54"}, 159 {"GIGAHERTZ", "54"}, 160 {"HERTZ", "54"}, 161 {"KILOHERTZ", "54"}, 162 {"MEGAHERTZ", "54"}, 163 {"ASTRONOMICAL_UNIT", "54"}, 164 {"DECIMETER", "54"}, 165 {"FATHOM", "54"}, 166 {"FURLONG", "54"}, 167 {"MICROMETER", "54"}, 168 {"NANOMETER", "54"}, 169 {"NAUTICAL_MILE", "54"}, 170 {"PARSEC", "54"}, 171 {"LUX", "54"}, 172 {"CARAT", "54"}, 173 {"METRIC_TON", "54"}, 174 {"MICROGRAM", "54"}, 175 {"MILLIGRAM", "54"}, 176 {"OUNCE_TROY", "54"}, 177 {"STONE", "54"}, 178 {"TON", "54"}, 179 {"GIGAWATT", "54"}, 180 {"MEGAWATT", "54"}, 181 {"MILLIWATT", "54"}, 182 {"MILLIMETER_OF_MERCURY", "54"}, 183 {"POUND_PER_SQUARE_INCH", "54"}, 184 {"KARAT", "54"}, 185 {"KELVIN", "54"}, 186 {"ACRE_FOOT", "54"}, 187 {"BUSHEL", "54"}, 188 {"CENTILITER", "54"}, 189 {"CUBIC_CENTIMETER", "54"}, 190 {"CUBIC_FOOT", "54"}, 191 {"CUBIC_INCH", "54"}, 192 {"CUBIC_METER", "54"}, 193 {"CUBIC_YARD", "54"}, 194 {"CUP", "54"}, 195 {"DECILITER", "54"}, 196 {"FLUID_OUNCE", "54"}, 197 {"GALLON", "54"}, 198 {"HECTOLITER", "54"}, 199 {"MEGALITER", "54"}, 200 {"MILLILITER", "54"}, 201 {"PINT", "54"}, 202 {"QUART", "54"}, 203 {"TABLESPOON", "54"}, 204 {"TEASPOON", "54"}, 205 {"GENERIC_TEMPERATURE", "56"}, 206 {"REVOLUTION_ANGLE", "56"}, 207 {"LITER_PER_100KILOMETERS", "56"}, 208 {"CENTURY", "56"}, 209 {"MILE_SCANDINAVIAN", "56"}, 210 {"KNOT", "56"}, 211 {"CUP_METRIC", "56"}, 212 {"PINT_METRIC", "56"}, 213 {"MILLIGRAM_PER_DECILITER", "57"}, 214 {"MILLIMOLE_PER_LITER", "57"}, 215 {"PART_PER_MILLION", "57"}, 216 {"MILE_PER_GALLON_IMPERIAL", "57"}, 217 {"GALLON_IMPERIAL", "57"}, 218 {"EAST", "58"}, 219 {"NORTH", "58"}, 220 {"SOUTH", "58"}, 221 {"WEST", "58"}, 222 }; 223 224 private static final HashMap<String, String> JAVA_VERSION_MAP = new HashMap<String, String>(); 225 226 static { 227 TIME_CODES.add("year"); 228 TIME_CODES.add("month"); 229 TIME_CODES.add("week"); 230 TIME_CODES.add("day"); 231 TIME_CODES.add("hour"); 232 TIME_CODES.add("minute"); 233 TIME_CODES.add("second"); 234 for (String verNum : DRAFT_VERSIONS) { 235 DRAFT_VERSION_SET.add(verNum); 236 } 237 for (String[] funcNameAndVersion : JAVA_VERSIONS) { 238 JAVA_VERSION_MAP.put(funcNameAndVersion[0], funcNameAndVersion[1]); 239 } 240 } 241 242 /** 243 * @author markdavis 244 * 245 */ 246 // TODO(junit): resolve 247// public static void main(String[] args) { 248// //generateConstants(); if (true) return; 249// 250// // Ticket #12034 deadlock on multi-threaded static init of MeasureUnit. 251// // The code below reliably deadlocks with ICU 56. 252// // The test is here in main() rather than in a test function so it can be made to run 253// // before anything else. 254// Thread thread = new Thread() { 255// @Override 256// public void run() { 257// @SuppressWarnings("unused") 258// Set<String> measureUnitTypes = MeasureUnit.getAvailableTypes(); 259// } 260// }; 261// thread.start(); 262// @SuppressWarnings("unused") 263// Currency cur = Currency.getInstance(ULocale.ENGLISH); 264// try {thread.join();} catch(InterruptedException e) {}; 265// // System.out.println("Done with MeasureUnit thread test."); 266// 267// new MeasureUnitTest().run(args); 268// } 269 270/* 271 @Test 272 public void testZZZ() { 273 // various generateXXX calls go here, see 274 // http://site.icu-project.org/design/formatting/measureformat/updating-measure-unit 275 // use this test to run each of the ollowing in succession 276 //generateConstants("58"); // for MeasureUnit.java, update generated MeasureUnit constants 277 //generateBackwardCompatibilityTest("58.1"); // for MeasureUnitTest.java, create TestCompatible58_1 278 //generateCXXHConstants("58"); // for measunit.h, update generated createXXX methods 279 //generateCXXConstants(); // for measunit.cpp, update generated code 280 //generateCXXBackwardCompatibilityTest("58.1"); // for measfmttest.cpp, create TestCompatible58_1 281 updateJAVAVersions("58"); // for MeasureUnitTest.java, JAVA_VERSIONS 282 } 283*/ 284 285 @Test 286 public void TestCompatible53_1() { 287 MeasureUnit[] units = { 288 MeasureUnit.G_FORCE, 289 MeasureUnit.DEGREE, 290 MeasureUnit.ARC_MINUTE, 291 MeasureUnit.ARC_SECOND, 292 MeasureUnit.ACRE, 293 MeasureUnit.HECTARE, 294 MeasureUnit.SQUARE_FOOT, 295 MeasureUnit.SQUARE_KILOMETER, 296 MeasureUnit.SQUARE_METER, 297 MeasureUnit.SQUARE_MILE, 298 MeasureUnit.MILLISECOND, 299 MeasureUnit.CENTIMETER, 300 MeasureUnit.FOOT, 301 MeasureUnit.INCH, 302 MeasureUnit.KILOMETER, 303 MeasureUnit.LIGHT_YEAR, 304 MeasureUnit.METER, 305 MeasureUnit.MILE, 306 MeasureUnit.MILLIMETER, 307 MeasureUnit.PICOMETER, 308 MeasureUnit.YARD, 309 MeasureUnit.GRAM, 310 MeasureUnit.KILOGRAM, 311 MeasureUnit.OUNCE, 312 MeasureUnit.POUND, 313 MeasureUnit.HORSEPOWER, 314 MeasureUnit.KILOWATT, 315 MeasureUnit.WATT, 316 MeasureUnit.HECTOPASCAL, 317 MeasureUnit.INCH_HG, 318 MeasureUnit.MILLIBAR, 319 MeasureUnit.KILOMETER_PER_HOUR, 320 MeasureUnit.METER_PER_SECOND, 321 MeasureUnit.MILE_PER_HOUR, 322 MeasureUnit.CELSIUS, 323 MeasureUnit.FAHRENHEIT, 324 MeasureUnit.CUBIC_KILOMETER, 325 MeasureUnit.CUBIC_MILE, 326 MeasureUnit.LITER, 327 MeasureUnit.YEAR, 328 MeasureUnit.MONTH, 329 MeasureUnit.WEEK, 330 MeasureUnit.DAY, 331 MeasureUnit.HOUR, 332 MeasureUnit.MINUTE, 333 MeasureUnit.SECOND, 334 }; 335 assertEquals("", 46, units.length); 336 } 337 338 @Test 339 public void TestCompatible54_1() { 340 MeasureUnit[] units = { 341 MeasureUnit.G_FORCE, 342 MeasureUnit.METER_PER_SECOND_SQUARED, 343 MeasureUnit.ARC_MINUTE, 344 MeasureUnit.ARC_SECOND, 345 MeasureUnit.DEGREE, 346 MeasureUnit.RADIAN, 347 MeasureUnit.ACRE, 348 MeasureUnit.HECTARE, 349 MeasureUnit.SQUARE_CENTIMETER, 350 MeasureUnit.SQUARE_FOOT, 351 MeasureUnit.SQUARE_INCH, 352 MeasureUnit.SQUARE_KILOMETER, 353 MeasureUnit.SQUARE_METER, 354 MeasureUnit.SQUARE_MILE, 355 MeasureUnit.SQUARE_YARD, 356 MeasureUnit.LITER_PER_KILOMETER, 357 MeasureUnit.MILE_PER_GALLON, 358 MeasureUnit.BIT, 359 MeasureUnit.BYTE, 360 MeasureUnit.GIGABIT, 361 MeasureUnit.GIGABYTE, 362 MeasureUnit.KILOBIT, 363 MeasureUnit.KILOBYTE, 364 MeasureUnit.MEGABIT, 365 MeasureUnit.MEGABYTE, 366 MeasureUnit.TERABIT, 367 MeasureUnit.TERABYTE, 368 MeasureUnit.DAY, 369 MeasureUnit.HOUR, 370 MeasureUnit.MICROSECOND, 371 MeasureUnit.MILLISECOND, 372 MeasureUnit.MINUTE, 373 MeasureUnit.MONTH, 374 MeasureUnit.NANOSECOND, 375 MeasureUnit.SECOND, 376 MeasureUnit.WEEK, 377 MeasureUnit.YEAR, 378 MeasureUnit.AMPERE, 379 MeasureUnit.MILLIAMPERE, 380 MeasureUnit.OHM, 381 MeasureUnit.VOLT, 382 MeasureUnit.CALORIE, 383 MeasureUnit.FOODCALORIE, 384 MeasureUnit.JOULE, 385 MeasureUnit.KILOCALORIE, 386 MeasureUnit.KILOJOULE, 387 MeasureUnit.KILOWATT_HOUR, 388 MeasureUnit.GIGAHERTZ, 389 MeasureUnit.HERTZ, 390 MeasureUnit.KILOHERTZ, 391 MeasureUnit.MEGAHERTZ, 392 MeasureUnit.ASTRONOMICAL_UNIT, 393 MeasureUnit.CENTIMETER, 394 MeasureUnit.DECIMETER, 395 MeasureUnit.FATHOM, 396 MeasureUnit.FOOT, 397 MeasureUnit.FURLONG, 398 MeasureUnit.INCH, 399 MeasureUnit.KILOMETER, 400 MeasureUnit.LIGHT_YEAR, 401 MeasureUnit.METER, 402 MeasureUnit.MICROMETER, 403 MeasureUnit.MILE, 404 MeasureUnit.MILLIMETER, 405 MeasureUnit.NANOMETER, 406 MeasureUnit.NAUTICAL_MILE, 407 MeasureUnit.PARSEC, 408 MeasureUnit.PICOMETER, 409 MeasureUnit.YARD, 410 MeasureUnit.LUX, 411 MeasureUnit.CARAT, 412 MeasureUnit.GRAM, 413 MeasureUnit.KILOGRAM, 414 MeasureUnit.METRIC_TON, 415 MeasureUnit.MICROGRAM, 416 MeasureUnit.MILLIGRAM, 417 MeasureUnit.OUNCE, 418 MeasureUnit.OUNCE_TROY, 419 MeasureUnit.POUND, 420 MeasureUnit.STONE, 421 MeasureUnit.TON, 422 MeasureUnit.GIGAWATT, 423 MeasureUnit.HORSEPOWER, 424 MeasureUnit.KILOWATT, 425 MeasureUnit.MEGAWATT, 426 MeasureUnit.MILLIWATT, 427 MeasureUnit.WATT, 428 MeasureUnit.HECTOPASCAL, 429 MeasureUnit.INCH_HG, 430 MeasureUnit.MILLIBAR, 431 MeasureUnit.MILLIMETER_OF_MERCURY, 432 MeasureUnit.POUND_PER_SQUARE_INCH, 433 MeasureUnit.KARAT, 434 MeasureUnit.KILOMETER_PER_HOUR, 435 MeasureUnit.METER_PER_SECOND, 436 MeasureUnit.MILE_PER_HOUR, 437 MeasureUnit.CELSIUS, 438 MeasureUnit.FAHRENHEIT, 439 MeasureUnit.KELVIN, 440 MeasureUnit.ACRE_FOOT, 441 MeasureUnit.BUSHEL, 442 MeasureUnit.CENTILITER, 443 MeasureUnit.CUBIC_CENTIMETER, 444 MeasureUnit.CUBIC_FOOT, 445 MeasureUnit.CUBIC_INCH, 446 MeasureUnit.CUBIC_KILOMETER, 447 MeasureUnit.CUBIC_METER, 448 MeasureUnit.CUBIC_MILE, 449 MeasureUnit.CUBIC_YARD, 450 MeasureUnit.CUP, 451 MeasureUnit.DECILITER, 452 MeasureUnit.FLUID_OUNCE, 453 MeasureUnit.GALLON, 454 MeasureUnit.HECTOLITER, 455 MeasureUnit.LITER, 456 MeasureUnit.MEGALITER, 457 MeasureUnit.MILLILITER, 458 MeasureUnit.PINT, 459 MeasureUnit.QUART, 460 MeasureUnit.TABLESPOON, 461 MeasureUnit.TEASPOON, 462 }; 463 assertEquals("", 121, units.length); 464 } 465 466 @Test 467 public void TestCompatible55_1() { 468 MeasureUnit[] units = { 469 MeasureUnit.G_FORCE, 470 MeasureUnit.METER_PER_SECOND_SQUARED, 471 MeasureUnit.ARC_MINUTE, 472 MeasureUnit.ARC_SECOND, 473 MeasureUnit.DEGREE, 474 MeasureUnit.RADIAN, 475 MeasureUnit.ACRE, 476 MeasureUnit.HECTARE, 477 MeasureUnit.SQUARE_CENTIMETER, 478 MeasureUnit.SQUARE_FOOT, 479 MeasureUnit.SQUARE_INCH, 480 MeasureUnit.SQUARE_KILOMETER, 481 MeasureUnit.SQUARE_METER, 482 MeasureUnit.SQUARE_MILE, 483 MeasureUnit.SQUARE_YARD, 484 MeasureUnit.LITER_PER_KILOMETER, 485 MeasureUnit.MILE_PER_GALLON, 486 MeasureUnit.BIT, 487 MeasureUnit.BYTE, 488 MeasureUnit.GIGABIT, 489 MeasureUnit.GIGABYTE, 490 MeasureUnit.KILOBIT, 491 MeasureUnit.KILOBYTE, 492 MeasureUnit.MEGABIT, 493 MeasureUnit.MEGABYTE, 494 MeasureUnit.TERABIT, 495 MeasureUnit.TERABYTE, 496 MeasureUnit.DAY, 497 MeasureUnit.HOUR, 498 MeasureUnit.MICROSECOND, 499 MeasureUnit.MILLISECOND, 500 MeasureUnit.MINUTE, 501 MeasureUnit.MONTH, 502 MeasureUnit.NANOSECOND, 503 MeasureUnit.SECOND, 504 MeasureUnit.WEEK, 505 MeasureUnit.YEAR, 506 MeasureUnit.AMPERE, 507 MeasureUnit.MILLIAMPERE, 508 MeasureUnit.OHM, 509 MeasureUnit.VOLT, 510 MeasureUnit.CALORIE, 511 MeasureUnit.FOODCALORIE, 512 MeasureUnit.JOULE, 513 MeasureUnit.KILOCALORIE, 514 MeasureUnit.KILOJOULE, 515 MeasureUnit.KILOWATT_HOUR, 516 MeasureUnit.GIGAHERTZ, 517 MeasureUnit.HERTZ, 518 MeasureUnit.KILOHERTZ, 519 MeasureUnit.MEGAHERTZ, 520 MeasureUnit.ASTRONOMICAL_UNIT, 521 MeasureUnit.CENTIMETER, 522 MeasureUnit.DECIMETER, 523 MeasureUnit.FATHOM, 524 MeasureUnit.FOOT, 525 MeasureUnit.FURLONG, 526 MeasureUnit.INCH, 527 MeasureUnit.KILOMETER, 528 MeasureUnit.LIGHT_YEAR, 529 MeasureUnit.METER, 530 MeasureUnit.MICROMETER, 531 MeasureUnit.MILE, 532 MeasureUnit.MILLIMETER, 533 MeasureUnit.NANOMETER, 534 MeasureUnit.NAUTICAL_MILE, 535 MeasureUnit.PARSEC, 536 MeasureUnit.PICOMETER, 537 MeasureUnit.YARD, 538 MeasureUnit.LUX, 539 MeasureUnit.CARAT, 540 MeasureUnit.GRAM, 541 MeasureUnit.KILOGRAM, 542 MeasureUnit.METRIC_TON, 543 MeasureUnit.MICROGRAM, 544 MeasureUnit.MILLIGRAM, 545 MeasureUnit.OUNCE, 546 MeasureUnit.OUNCE_TROY, 547 MeasureUnit.POUND, 548 MeasureUnit.STONE, 549 MeasureUnit.TON, 550 MeasureUnit.GIGAWATT, 551 MeasureUnit.HORSEPOWER, 552 MeasureUnit.KILOWATT, 553 MeasureUnit.MEGAWATT, 554 MeasureUnit.MILLIWATT, 555 MeasureUnit.WATT, 556 MeasureUnit.HECTOPASCAL, 557 MeasureUnit.INCH_HG, 558 MeasureUnit.MILLIBAR, 559 MeasureUnit.MILLIMETER_OF_MERCURY, 560 MeasureUnit.POUND_PER_SQUARE_INCH, 561 MeasureUnit.KARAT, 562 MeasureUnit.KILOMETER_PER_HOUR, 563 MeasureUnit.METER_PER_SECOND, 564 MeasureUnit.MILE_PER_HOUR, 565 MeasureUnit.CELSIUS, 566 MeasureUnit.FAHRENHEIT, 567 MeasureUnit.GENERIC_TEMPERATURE, 568 MeasureUnit.KELVIN, 569 MeasureUnit.ACRE_FOOT, 570 MeasureUnit.BUSHEL, 571 MeasureUnit.CENTILITER, 572 MeasureUnit.CUBIC_CENTIMETER, 573 MeasureUnit.CUBIC_FOOT, 574 MeasureUnit.CUBIC_INCH, 575 MeasureUnit.CUBIC_KILOMETER, 576 MeasureUnit.CUBIC_METER, 577 MeasureUnit.CUBIC_MILE, 578 MeasureUnit.CUBIC_YARD, 579 MeasureUnit.CUP, 580 MeasureUnit.DECILITER, 581 MeasureUnit.FLUID_OUNCE, 582 MeasureUnit.GALLON, 583 MeasureUnit.HECTOLITER, 584 MeasureUnit.LITER, 585 MeasureUnit.MEGALITER, 586 MeasureUnit.MILLILITER, 587 MeasureUnit.PINT, 588 MeasureUnit.QUART, 589 MeasureUnit.TABLESPOON, 590 MeasureUnit.TEASPOON, 591 }; 592 assertEquals("", 122, units.length); 593 } 594 595 @Test 596 public void TestCompatible56_1() { 597 MeasureUnit[] units = { 598 MeasureUnit.G_FORCE, 599 MeasureUnit.METER_PER_SECOND_SQUARED, 600 MeasureUnit.ARC_MINUTE, 601 MeasureUnit.ARC_SECOND, 602 MeasureUnit.DEGREE, 603 MeasureUnit.RADIAN, 604 MeasureUnit.REVOLUTION_ANGLE, 605 MeasureUnit.ACRE, 606 MeasureUnit.HECTARE, 607 MeasureUnit.SQUARE_CENTIMETER, 608 MeasureUnit.SQUARE_FOOT, 609 MeasureUnit.SQUARE_INCH, 610 MeasureUnit.SQUARE_KILOMETER, 611 MeasureUnit.SQUARE_METER, 612 MeasureUnit.SQUARE_MILE, 613 MeasureUnit.SQUARE_YARD, 614 MeasureUnit.LITER_PER_100KILOMETERS, 615 MeasureUnit.LITER_PER_KILOMETER, 616 MeasureUnit.MILE_PER_GALLON, 617 MeasureUnit.BIT, 618 MeasureUnit.BYTE, 619 MeasureUnit.GIGABIT, 620 MeasureUnit.GIGABYTE, 621 MeasureUnit.KILOBIT, 622 MeasureUnit.KILOBYTE, 623 MeasureUnit.MEGABIT, 624 MeasureUnit.MEGABYTE, 625 MeasureUnit.TERABIT, 626 MeasureUnit.TERABYTE, 627 MeasureUnit.CENTURY, 628 MeasureUnit.DAY, 629 MeasureUnit.HOUR, 630 MeasureUnit.MICROSECOND, 631 MeasureUnit.MILLISECOND, 632 MeasureUnit.MINUTE, 633 MeasureUnit.MONTH, 634 MeasureUnit.NANOSECOND, 635 MeasureUnit.SECOND, 636 MeasureUnit.WEEK, 637 MeasureUnit.YEAR, 638 MeasureUnit.AMPERE, 639 MeasureUnit.MILLIAMPERE, 640 MeasureUnit.OHM, 641 MeasureUnit.VOLT, 642 MeasureUnit.CALORIE, 643 MeasureUnit.FOODCALORIE, 644 MeasureUnit.JOULE, 645 MeasureUnit.KILOCALORIE, 646 MeasureUnit.KILOJOULE, 647 MeasureUnit.KILOWATT_HOUR, 648 MeasureUnit.GIGAHERTZ, 649 MeasureUnit.HERTZ, 650 MeasureUnit.KILOHERTZ, 651 MeasureUnit.MEGAHERTZ, 652 MeasureUnit.ASTRONOMICAL_UNIT, 653 MeasureUnit.CENTIMETER, 654 MeasureUnit.DECIMETER, 655 MeasureUnit.FATHOM, 656 MeasureUnit.FOOT, 657 MeasureUnit.FURLONG, 658 MeasureUnit.INCH, 659 MeasureUnit.KILOMETER, 660 MeasureUnit.LIGHT_YEAR, 661 MeasureUnit.METER, 662 MeasureUnit.MICROMETER, 663 MeasureUnit.MILE, 664 MeasureUnit.MILE_SCANDINAVIAN, 665 MeasureUnit.MILLIMETER, 666 MeasureUnit.NANOMETER, 667 MeasureUnit.NAUTICAL_MILE, 668 MeasureUnit.PARSEC, 669 MeasureUnit.PICOMETER, 670 MeasureUnit.YARD, 671 MeasureUnit.LUX, 672 MeasureUnit.CARAT, 673 MeasureUnit.GRAM, 674 MeasureUnit.KILOGRAM, 675 MeasureUnit.METRIC_TON, 676 MeasureUnit.MICROGRAM, 677 MeasureUnit.MILLIGRAM, 678 MeasureUnit.OUNCE, 679 MeasureUnit.OUNCE_TROY, 680 MeasureUnit.POUND, 681 MeasureUnit.STONE, 682 MeasureUnit.TON, 683 MeasureUnit.GIGAWATT, 684 MeasureUnit.HORSEPOWER, 685 MeasureUnit.KILOWATT, 686 MeasureUnit.MEGAWATT, 687 MeasureUnit.MILLIWATT, 688 MeasureUnit.WATT, 689 MeasureUnit.HECTOPASCAL, 690 MeasureUnit.INCH_HG, 691 MeasureUnit.MILLIBAR, 692 MeasureUnit.MILLIMETER_OF_MERCURY, 693 MeasureUnit.POUND_PER_SQUARE_INCH, 694 MeasureUnit.KARAT, 695 MeasureUnit.KILOMETER_PER_HOUR, 696 MeasureUnit.KNOT, 697 MeasureUnit.METER_PER_SECOND, 698 MeasureUnit.MILE_PER_HOUR, 699 MeasureUnit.CELSIUS, 700 MeasureUnit.FAHRENHEIT, 701 MeasureUnit.GENERIC_TEMPERATURE, 702 MeasureUnit.KELVIN, 703 MeasureUnit.ACRE_FOOT, 704 MeasureUnit.BUSHEL, 705 MeasureUnit.CENTILITER, 706 MeasureUnit.CUBIC_CENTIMETER, 707 MeasureUnit.CUBIC_FOOT, 708 MeasureUnit.CUBIC_INCH, 709 MeasureUnit.CUBIC_KILOMETER, 710 MeasureUnit.CUBIC_METER, 711 MeasureUnit.CUBIC_MILE, 712 MeasureUnit.CUBIC_YARD, 713 MeasureUnit.CUP, 714 MeasureUnit.CUP_METRIC, 715 MeasureUnit.DECILITER, 716 MeasureUnit.FLUID_OUNCE, 717 MeasureUnit.GALLON, 718 MeasureUnit.HECTOLITER, 719 MeasureUnit.LITER, 720 MeasureUnit.MEGALITER, 721 MeasureUnit.MILLILITER, 722 MeasureUnit.PINT, 723 MeasureUnit.PINT_METRIC, 724 MeasureUnit.QUART, 725 MeasureUnit.TABLESPOON, 726 MeasureUnit.TEASPOON, 727 }; 728 assertEquals("", 129, units.length); 729 } 730 731 @Test 732 public void TestCompatible57_1() { 733 MeasureUnit[] units = { 734 MeasureUnit.G_FORCE, 735 MeasureUnit.METER_PER_SECOND_SQUARED, 736 MeasureUnit.ARC_MINUTE, 737 MeasureUnit.ARC_SECOND, 738 MeasureUnit.DEGREE, 739 MeasureUnit.RADIAN, 740 MeasureUnit.REVOLUTION_ANGLE, 741 MeasureUnit.ACRE, 742 MeasureUnit.HECTARE, 743 MeasureUnit.SQUARE_CENTIMETER, 744 MeasureUnit.SQUARE_FOOT, 745 MeasureUnit.SQUARE_INCH, 746 MeasureUnit.SQUARE_KILOMETER, 747 MeasureUnit.SQUARE_METER, 748 MeasureUnit.SQUARE_MILE, 749 MeasureUnit.SQUARE_YARD, 750 MeasureUnit.KARAT, 751 MeasureUnit.MILLIGRAM_PER_DECILITER, 752 MeasureUnit.MILLIMOLE_PER_LITER, 753 MeasureUnit.PART_PER_MILLION, 754 MeasureUnit.LITER_PER_100KILOMETERS, 755 MeasureUnit.LITER_PER_KILOMETER, 756 MeasureUnit.MILE_PER_GALLON, 757 MeasureUnit.MILE_PER_GALLON_IMPERIAL, 758 MeasureUnit.BIT, 759 MeasureUnit.BYTE, 760 MeasureUnit.GIGABIT, 761 MeasureUnit.GIGABYTE, 762 MeasureUnit.KILOBIT, 763 MeasureUnit.KILOBYTE, 764 MeasureUnit.MEGABIT, 765 MeasureUnit.MEGABYTE, 766 MeasureUnit.TERABIT, 767 MeasureUnit.TERABYTE, 768 MeasureUnit.CENTURY, 769 MeasureUnit.DAY, 770 MeasureUnit.HOUR, 771 MeasureUnit.MICROSECOND, 772 MeasureUnit.MILLISECOND, 773 MeasureUnit.MINUTE, 774 MeasureUnit.MONTH, 775 MeasureUnit.NANOSECOND, 776 MeasureUnit.SECOND, 777 MeasureUnit.WEEK, 778 MeasureUnit.YEAR, 779 MeasureUnit.AMPERE, 780 MeasureUnit.MILLIAMPERE, 781 MeasureUnit.OHM, 782 MeasureUnit.VOLT, 783 MeasureUnit.CALORIE, 784 MeasureUnit.FOODCALORIE, 785 MeasureUnit.JOULE, 786 MeasureUnit.KILOCALORIE, 787 MeasureUnit.KILOJOULE, 788 MeasureUnit.KILOWATT_HOUR, 789 MeasureUnit.GIGAHERTZ, 790 MeasureUnit.HERTZ, 791 MeasureUnit.KILOHERTZ, 792 MeasureUnit.MEGAHERTZ, 793 MeasureUnit.ASTRONOMICAL_UNIT, 794 MeasureUnit.CENTIMETER, 795 MeasureUnit.DECIMETER, 796 MeasureUnit.FATHOM, 797 MeasureUnit.FOOT, 798 MeasureUnit.FURLONG, 799 MeasureUnit.INCH, 800 MeasureUnit.KILOMETER, 801 MeasureUnit.LIGHT_YEAR, 802 MeasureUnit.METER, 803 MeasureUnit.MICROMETER, 804 MeasureUnit.MILE, 805 MeasureUnit.MILE_SCANDINAVIAN, 806 MeasureUnit.MILLIMETER, 807 MeasureUnit.NANOMETER, 808 MeasureUnit.NAUTICAL_MILE, 809 MeasureUnit.PARSEC, 810 MeasureUnit.PICOMETER, 811 MeasureUnit.YARD, 812 MeasureUnit.LUX, 813 MeasureUnit.CARAT, 814 MeasureUnit.GRAM, 815 MeasureUnit.KILOGRAM, 816 MeasureUnit.METRIC_TON, 817 MeasureUnit.MICROGRAM, 818 MeasureUnit.MILLIGRAM, 819 MeasureUnit.OUNCE, 820 MeasureUnit.OUNCE_TROY, 821 MeasureUnit.POUND, 822 MeasureUnit.STONE, 823 MeasureUnit.TON, 824 MeasureUnit.GIGAWATT, 825 MeasureUnit.HORSEPOWER, 826 MeasureUnit.KILOWATT, 827 MeasureUnit.MEGAWATT, 828 MeasureUnit.MILLIWATT, 829 MeasureUnit.WATT, 830 MeasureUnit.HECTOPASCAL, 831 MeasureUnit.INCH_HG, 832 MeasureUnit.MILLIBAR, 833 MeasureUnit.MILLIMETER_OF_MERCURY, 834 MeasureUnit.POUND_PER_SQUARE_INCH, 835 MeasureUnit.KILOMETER_PER_HOUR, 836 MeasureUnit.KNOT, 837 MeasureUnit.METER_PER_SECOND, 838 MeasureUnit.MILE_PER_HOUR, 839 MeasureUnit.CELSIUS, 840 MeasureUnit.FAHRENHEIT, 841 MeasureUnit.GENERIC_TEMPERATURE, 842 MeasureUnit.KELVIN, 843 MeasureUnit.ACRE_FOOT, 844 MeasureUnit.BUSHEL, 845 MeasureUnit.CENTILITER, 846 MeasureUnit.CUBIC_CENTIMETER, 847 MeasureUnit.CUBIC_FOOT, 848 MeasureUnit.CUBIC_INCH, 849 MeasureUnit.CUBIC_KILOMETER, 850 MeasureUnit.CUBIC_METER, 851 MeasureUnit.CUBIC_MILE, 852 MeasureUnit.CUBIC_YARD, 853 MeasureUnit.CUP, 854 MeasureUnit.CUP_METRIC, 855 MeasureUnit.DECILITER, 856 MeasureUnit.FLUID_OUNCE, 857 MeasureUnit.GALLON, 858 MeasureUnit.GALLON_IMPERIAL, 859 MeasureUnit.HECTOLITER, 860 MeasureUnit.LITER, 861 MeasureUnit.MEGALITER, 862 MeasureUnit.MILLILITER, 863 MeasureUnit.PINT, 864 MeasureUnit.PINT_METRIC, 865 MeasureUnit.QUART, 866 MeasureUnit.TABLESPOON, 867 MeasureUnit.TEASPOON, 868 }; 869 assertEquals("", 134, units.length); 870 } 871 872 @Test 873 public void TestCompatible58_1() { 874 MeasureUnit[] units = { 875 MeasureUnit.G_FORCE, 876 MeasureUnit.METER_PER_SECOND_SQUARED, 877 MeasureUnit.ARC_MINUTE, 878 MeasureUnit.ARC_SECOND, 879 MeasureUnit.DEGREE, 880 MeasureUnit.RADIAN, 881 MeasureUnit.REVOLUTION_ANGLE, 882 MeasureUnit.ACRE, 883 MeasureUnit.HECTARE, 884 MeasureUnit.SQUARE_CENTIMETER, 885 MeasureUnit.SQUARE_FOOT, 886 MeasureUnit.SQUARE_INCH, 887 MeasureUnit.SQUARE_KILOMETER, 888 MeasureUnit.SQUARE_METER, 889 MeasureUnit.SQUARE_MILE, 890 MeasureUnit.SQUARE_YARD, 891 MeasureUnit.KARAT, 892 MeasureUnit.MILLIGRAM_PER_DECILITER, 893 MeasureUnit.MILLIMOLE_PER_LITER, 894 MeasureUnit.PART_PER_MILLION, 895 MeasureUnit.LITER_PER_100KILOMETERS, 896 MeasureUnit.LITER_PER_KILOMETER, 897 MeasureUnit.MILE_PER_GALLON, 898 MeasureUnit.MILE_PER_GALLON_IMPERIAL, 899 MeasureUnit.EAST, 900 MeasureUnit.NORTH, 901 MeasureUnit.SOUTH, 902 MeasureUnit.WEST, 903 MeasureUnit.BIT, 904 MeasureUnit.BYTE, 905 MeasureUnit.GIGABIT, 906 MeasureUnit.GIGABYTE, 907 MeasureUnit.KILOBIT, 908 MeasureUnit.KILOBYTE, 909 MeasureUnit.MEGABIT, 910 MeasureUnit.MEGABYTE, 911 MeasureUnit.TERABIT, 912 MeasureUnit.TERABYTE, 913 MeasureUnit.CENTURY, 914 MeasureUnit.DAY, 915 MeasureUnit.HOUR, 916 MeasureUnit.MICROSECOND, 917 MeasureUnit.MILLISECOND, 918 MeasureUnit.MINUTE, 919 MeasureUnit.MONTH, 920 MeasureUnit.NANOSECOND, 921 MeasureUnit.SECOND, 922 MeasureUnit.WEEK, 923 MeasureUnit.YEAR, 924 MeasureUnit.AMPERE, 925 MeasureUnit.MILLIAMPERE, 926 MeasureUnit.OHM, 927 MeasureUnit.VOLT, 928 MeasureUnit.CALORIE, 929 MeasureUnit.FOODCALORIE, 930 MeasureUnit.JOULE, 931 MeasureUnit.KILOCALORIE, 932 MeasureUnit.KILOJOULE, 933 MeasureUnit.KILOWATT_HOUR, 934 MeasureUnit.GIGAHERTZ, 935 MeasureUnit.HERTZ, 936 MeasureUnit.KILOHERTZ, 937 MeasureUnit.MEGAHERTZ, 938 MeasureUnit.ASTRONOMICAL_UNIT, 939 MeasureUnit.CENTIMETER, 940 MeasureUnit.DECIMETER, 941 MeasureUnit.FATHOM, 942 MeasureUnit.FOOT, 943 MeasureUnit.FURLONG, 944 MeasureUnit.INCH, 945 MeasureUnit.KILOMETER, 946 MeasureUnit.LIGHT_YEAR, 947 MeasureUnit.METER, 948 MeasureUnit.MICROMETER, 949 MeasureUnit.MILE, 950 MeasureUnit.MILE_SCANDINAVIAN, 951 MeasureUnit.MILLIMETER, 952 MeasureUnit.NANOMETER, 953 MeasureUnit.NAUTICAL_MILE, 954 MeasureUnit.PARSEC, 955 MeasureUnit.PICOMETER, 956 MeasureUnit.YARD, 957 MeasureUnit.LUX, 958 MeasureUnit.CARAT, 959 MeasureUnit.GRAM, 960 MeasureUnit.KILOGRAM, 961 MeasureUnit.METRIC_TON, 962 MeasureUnit.MICROGRAM, 963 MeasureUnit.MILLIGRAM, 964 MeasureUnit.OUNCE, 965 MeasureUnit.OUNCE_TROY, 966 MeasureUnit.POUND, 967 MeasureUnit.STONE, 968 MeasureUnit.TON, 969 MeasureUnit.GIGAWATT, 970 MeasureUnit.HORSEPOWER, 971 MeasureUnit.KILOWATT, 972 MeasureUnit.MEGAWATT, 973 MeasureUnit.MILLIWATT, 974 MeasureUnit.WATT, 975 MeasureUnit.HECTOPASCAL, 976 MeasureUnit.INCH_HG, 977 MeasureUnit.MILLIBAR, 978 MeasureUnit.MILLIMETER_OF_MERCURY, 979 MeasureUnit.POUND_PER_SQUARE_INCH, 980 MeasureUnit.KILOMETER_PER_HOUR, 981 MeasureUnit.KNOT, 982 MeasureUnit.METER_PER_SECOND, 983 MeasureUnit.MILE_PER_HOUR, 984 MeasureUnit.CELSIUS, 985 MeasureUnit.FAHRENHEIT, 986 MeasureUnit.GENERIC_TEMPERATURE, 987 MeasureUnit.KELVIN, 988 MeasureUnit.ACRE_FOOT, 989 MeasureUnit.BUSHEL, 990 MeasureUnit.CENTILITER, 991 MeasureUnit.CUBIC_CENTIMETER, 992 MeasureUnit.CUBIC_FOOT, 993 MeasureUnit.CUBIC_INCH, 994 MeasureUnit.CUBIC_KILOMETER, 995 MeasureUnit.CUBIC_METER, 996 MeasureUnit.CUBIC_MILE, 997 MeasureUnit.CUBIC_YARD, 998 MeasureUnit.CUP, 999 MeasureUnit.CUP_METRIC, 1000 MeasureUnit.DECILITER, 1001 MeasureUnit.FLUID_OUNCE, 1002 MeasureUnit.GALLON, 1003 MeasureUnit.GALLON_IMPERIAL, 1004 MeasureUnit.HECTOLITER, 1005 MeasureUnit.LITER, 1006 MeasureUnit.MEGALITER, 1007 MeasureUnit.MILLILITER, 1008 MeasureUnit.PINT, 1009 MeasureUnit.PINT_METRIC, 1010 MeasureUnit.QUART, 1011 MeasureUnit.TABLESPOON, 1012 MeasureUnit.TEASPOON, 1013 }; 1014 assertEquals("", 138, units.length); 1015 } 1016 1017 @Test 1018 public void TestExamplesInDocs() { 1019 MeasureFormat fmtFr = MeasureFormat.getInstance( 1020 ULocale.FRENCH, FormatWidth.SHORT); 1021 Measure measure = new Measure(23, MeasureUnit.CELSIUS); 1022 assertEquals("23 °C", "23 °C", fmtFr.format(measure)); 1023 Measure measureF = new Measure(70, MeasureUnit.FAHRENHEIT); 1024 assertEquals("70 °F", "70 °F", fmtFr.format(measureF)); 1025 MeasureFormat fmtFrFull = MeasureFormat.getInstance( 1026 ULocale.FRENCH, FormatWidth.WIDE); 1027 assertEquals( 1028 "70 pied et 5,3 pouces", 1029 "70 pieds et 5,3 pouces", 1030 fmtFrFull.formatMeasures( 1031 new Measure(70, MeasureUnit.FOOT), 1032 new Measure(5.3, MeasureUnit.INCH))); 1033 assertEquals( 1034 "1 pied et 1 pouce", 1035 "1 pied et 1 pouce", 1036 fmtFrFull.formatMeasures( 1037 new Measure(1, MeasureUnit.FOOT), 1038 new Measure(1, MeasureUnit.INCH))); 1039 MeasureFormat fmtFrNarrow = MeasureFormat.getInstance( 1040 ULocale.FRENCH, FormatWidth.NARROW); 1041 assertEquals( 1042 "1′ 1″", 1043 "1′ 1″", 1044 fmtFrNarrow.formatMeasures( 1045 new Measure(1, MeasureUnit.FOOT), 1046 new Measure(1, MeasureUnit.INCH))); 1047 MeasureFormat fmtEn = MeasureFormat.getInstance(ULocale.ENGLISH, FormatWidth.WIDE); 1048 assertEquals( 1049 "1 inch, 2 feet", 1050 "1 inch, 2 feet", 1051 fmtEn.formatMeasures( 1052 new Measure(1, MeasureUnit.INCH), 1053 new Measure(2, MeasureUnit.FOOT))); 1054 } 1055 1056 @Test 1057 public void TestFormatPeriodEn() { 1058 TimeUnitAmount[] _19m = {new TimeUnitAmount(19.0, TimeUnit.MINUTE)}; 1059 TimeUnitAmount[] _1h_23_5s = { 1060 new TimeUnitAmount(1.0, TimeUnit.HOUR), 1061 new TimeUnitAmount(23.5, TimeUnit.SECOND)}; 1062 TimeUnitAmount[] _1h_23_5m = { 1063 new TimeUnitAmount(1.0, TimeUnit.HOUR), 1064 new TimeUnitAmount(23.5, TimeUnit.MINUTE)}; 1065 TimeUnitAmount[] _1h_0m_23s = { 1066 new TimeUnitAmount(1.0, TimeUnit.HOUR), 1067 new TimeUnitAmount(0.0, TimeUnit.MINUTE), 1068 new TimeUnitAmount(23.0, TimeUnit.SECOND)}; 1069 TimeUnitAmount[] _2y_5M_3w_4d = { 1070 new TimeUnitAmount(2.0, TimeUnit.YEAR), 1071 new TimeUnitAmount(5.0, TimeUnit.MONTH), 1072 new TimeUnitAmount(3.0, TimeUnit.WEEK), 1073 new TimeUnitAmount(4.0, TimeUnit.DAY)}; 1074 TimeUnitAmount[] _1m_59_9996s = { 1075 new TimeUnitAmount(1.0, TimeUnit.MINUTE), 1076 new TimeUnitAmount(59.9996, TimeUnit.SECOND)}; 1077 TimeUnitAmount[] _5h_17m = { 1078 new TimeUnitAmount(5.0, TimeUnit.HOUR), 1079 new TimeUnitAmount(17.0, TimeUnit.MINUTE)}; 1080 TimeUnitAmount[] _neg5h_17m = { 1081 new TimeUnitAmount(-5.0, TimeUnit.HOUR), 1082 new TimeUnitAmount(17.0, TimeUnit.MINUTE)}; 1083 TimeUnitAmount[] _19m_28s = { 1084 new TimeUnitAmount(19.0, TimeUnit.MINUTE), 1085 new TimeUnitAmount(28.0, TimeUnit.SECOND)}; 1086 TimeUnitAmount[] _0h_0m_9s = { 1087 new TimeUnitAmount(0.0, TimeUnit.HOUR), 1088 new TimeUnitAmount(0.0, TimeUnit.MINUTE), 1089 new TimeUnitAmount(9.0, TimeUnit.SECOND)}; 1090 TimeUnitAmount[] _0h_0m_17s = { 1091 new TimeUnitAmount(0.0, TimeUnit.HOUR), 1092 new TimeUnitAmount(0.0, TimeUnit.MINUTE), 1093 new TimeUnitAmount(17.0, TimeUnit.SECOND)}; 1094 TimeUnitAmount[] _6h_56_92m = { 1095 new TimeUnitAmount(6.0, TimeUnit.HOUR), 1096 new TimeUnitAmount(56.92, TimeUnit.MINUTE)}; 1097 TimeUnitAmount[] _3h_4s_5m = { 1098 new TimeUnitAmount(3.0, TimeUnit.HOUR), 1099 new TimeUnitAmount(4.0, TimeUnit.SECOND), 1100 new TimeUnitAmount(5.0, TimeUnit.MINUTE)}; 1101 TimeUnitAmount[] _6_7h_56_92m = { 1102 new TimeUnitAmount(6.7, TimeUnit.HOUR), 1103 new TimeUnitAmount(56.92, TimeUnit.MINUTE)}; 1104 TimeUnitAmount[] _3h_5h = { 1105 new TimeUnitAmount(3.0, TimeUnit.HOUR), 1106 new TimeUnitAmount(5.0, TimeUnit.HOUR)}; 1107 1108 Object[][] fullData = { 1109 {_1m_59_9996s, "1 minute, 59.9996 seconds"}, 1110 {_19m, "19 minutes"}, 1111 {_1h_23_5s, "1 hour, 23.5 seconds"}, 1112 {_1h_23_5m, "1 hour, 23.5 minutes"}, 1113 {_1h_0m_23s, "1 hour, 0 minutes, 23 seconds"}, 1114 {_2y_5M_3w_4d, "2 years, 5 months, 3 weeks, 4 days"}}; 1115 Object[][] abbrevData = { 1116 {_1m_59_9996s, "1 min, 59.9996 sec"}, 1117 {_19m, "19 min"}, 1118 {_1h_23_5s, "1 hr, 23.5 sec"}, 1119 {_1h_23_5m, "1 hr, 23.5 min"}, 1120 {_1h_0m_23s, "1 hr, 0 min, 23 sec"}, 1121 {_2y_5M_3w_4d, "2 yrs, 5 mths, 3 wks, 4 days"}}; 1122 Object[][] narrowData = { 1123 {_1m_59_9996s, "1m 59.9996s"}, 1124 {_19m, "19m"}, 1125 {_1h_23_5s, "1h 23.5s"}, 1126 {_1h_23_5m, "1h 23.5m"}, 1127 {_1h_0m_23s, "1h 0m 23s"}, 1128 {_2y_5M_3w_4d, "2y 5m 3w 4d"}}; 1129 1130 1131 Object[][] numericData = { 1132 {_1m_59_9996s, "1:59.9996"}, 1133 {_19m, "19m"}, 1134 {_1h_23_5s, "1:00:23.5"}, 1135 {_1h_0m_23s, "1:00:23"}, 1136 {_1h_23_5m, "1:23.5"}, 1137 {_5h_17m, "5:17"}, 1138 {_neg5h_17m, "-5h 17m"}, 1139 {_19m_28s, "19:28"}, 1140 {_2y_5M_3w_4d, "2y 5m 3w 4d"}, 1141 {_0h_0m_9s, "0:00:09"}, 1142 {_6h_56_92m, "6:56.92"}, 1143 {_6_7h_56_92m, "6:56.92"}, 1144 {_3h_4s_5m, "3h 4s 5m"}, 1145 {_3h_5h, "3h 5h"}}; 1146 Object[][] fullDataDe = { 1147 {_1m_59_9996s, "1 Minute, 59,9996 Sekunden"}, 1148 {_19m, "19 Minuten"}, 1149 {_1h_23_5s, "1 Stunde, 23,5 Sekunden"}, 1150 {_1h_23_5m, "1 Stunde, 23,5 Minuten"}, 1151 {_1h_0m_23s, "1 Stunde, 0 Minuten und 23 Sekunden"}, 1152 {_2y_5M_3w_4d, "2 Jahre, 5 Monate, 3 Wochen und 4 Tage"}}; 1153 Object[][] numericDataDe = { 1154 {_1m_59_9996s, "1:59,9996"}, 1155 {_19m, "19 Min."}, 1156 {_1h_23_5s, "1:00:23,5"}, 1157 {_1h_0m_23s, "1:00:23"}, 1158 {_1h_23_5m, "1:23,5"}, 1159 {_5h_17m, "5:17"}, 1160 {_19m_28s, "19:28"}, 1161 {_2y_5M_3w_4d, "2 J, 5 M, 3 W und 4 T"}, 1162 {_0h_0m_17s, "0:00:17"}, 1163 {_6h_56_92m, "6:56,92"}, 1164 {_3h_5h, "3 Std., 5 Std."}}; 1165 1166 NumberFormat nf = NumberFormat.getNumberInstance(ULocale.ENGLISH); 1167 nf.setMaximumFractionDigits(4); 1168 MeasureFormat mf = MeasureFormat.getInstance(ULocale.ENGLISH, FormatWidth.WIDE, nf); 1169 verifyFormatPeriod("en FULL", mf, fullData); 1170 mf = MeasureFormat.getInstance(ULocale.ENGLISH, FormatWidth.SHORT, nf); 1171 verifyFormatPeriod("en SHORT", mf, abbrevData); 1172 mf = MeasureFormat.getInstance(ULocale.ENGLISH, FormatWidth.NARROW, nf); 1173 verifyFormatPeriod("en NARROW", mf, narrowData); 1174 mf = MeasureFormat.getInstance(ULocale.ENGLISH, FormatWidth.NUMERIC, nf); 1175 verifyFormatPeriod("en NUMERIC", mf, numericData); 1176 1177 nf = NumberFormat.getNumberInstance(ULocale.GERMAN); 1178 nf.setMaximumFractionDigits(4); 1179 mf = MeasureFormat.getInstance(ULocale.GERMAN, FormatWidth.WIDE, nf); 1180 verifyFormatPeriod("de FULL", mf, fullDataDe); 1181 mf = MeasureFormat.getInstance(ULocale.GERMAN, FormatWidth.NUMERIC, nf); 1182 verifyFormatPeriod("de NUMERIC", mf, numericDataDe); 1183 1184 // Same tests, with Java Locale 1185 nf = NumberFormat.getNumberInstance(Locale.GERMAN); 1186 nf.setMaximumFractionDigits(4); 1187 mf = MeasureFormat.getInstance(Locale.GERMAN, FormatWidth.WIDE, nf); 1188 verifyFormatPeriod("de FULL(Java Locale)", mf, fullDataDe); 1189 mf = MeasureFormat.getInstance(Locale.GERMAN, FormatWidth.NUMERIC, nf); 1190 verifyFormatPeriod("de NUMERIC(Java Locale)", mf, numericDataDe); 1191 1192 } 1193 1194 private void verifyFormatPeriod(String desc, MeasureFormat mf, Object[][] testData) { 1195 StringBuilder builder = new StringBuilder(); 1196 boolean failure = false; 1197 for (Object[] testCase : testData) { 1198 String actual = mf.format(testCase[0]); 1199 if (!testCase[1].equals(actual)) { 1200 builder.append(String.format("%s: Expected: '%s', got: '%s'\n", desc, testCase[1], actual)); 1201 failure = true; 1202 } 1203 } 1204 if (failure) { 1205 errln(builder.toString()); 1206 } 1207 } 1208 1209 @Test 1210 public void Test10219FractionalPlurals() { 1211 double[] values = {1.588, 1.011}; 1212 String[][] expected = { 1213 {"1 minute", "1.5 minutes", "1.58 minutes"}, 1214 {"1 minute", "1.0 minutes", "1.01 minutes"} 1215 }; 1216 for (int j = 0; j < values.length; j++) { 1217 for (int i = 0; i < expected[j].length; i++) { 1218 NumberFormat nf = NumberFormat.getNumberInstance(ULocale.ENGLISH); 1219 nf.setRoundingMode(BigDecimal.ROUND_DOWN); 1220 nf.setMinimumFractionDigits(i); 1221 nf.setMaximumFractionDigits(i); 1222 MeasureFormat mf = MeasureFormat.getInstance( 1223 ULocale.ENGLISH, FormatWidth.WIDE, nf); 1224 assertEquals("Test10219", expected[j][i], mf.format(new Measure(values[j], MeasureUnit.MINUTE))); 1225 } 1226 } 1227 } 1228 1229 @Test 1230 public void TestGreek() { 1231 String[] locales = {"el_GR", "el"}; 1232 final MeasureUnit[] units = new MeasureUnit[]{ 1233 MeasureUnit.SECOND, 1234 MeasureUnit.MINUTE, 1235 MeasureUnit.HOUR, 1236 MeasureUnit.DAY, 1237 MeasureUnit.WEEK, 1238 MeasureUnit.MONTH, 1239 MeasureUnit.YEAR}; 1240 FormatWidth[] styles = new FormatWidth[] {FormatWidth.WIDE, FormatWidth.SHORT}; 1241 int[] numbers = new int[] {1, 7}; 1242 String[] expected = { 1243 // "el_GR" 1 wide 1244 "1 δευτερόλεπτο", 1245 "1 λεπτό", 1246 "1 ώρα", 1247 "1 ημέρα", 1248 "1 εβδομάδα", 1249 "1 μήνας", 1250 "1 έτος", 1251 // "el_GR" 1 short 1252 "1 δευτ.", 1253 "1 λεπ.", 1254 "1 ώρα", 1255 "1 ημέρα", 1256 "1 εβδ.", 1257 "1 μήν.", 1258 "1 έτ.", // year (one) 1259 // "el_GR" 7 wide 1260 "7 δευτερόλεπτα", 1261 "7 λεπτά", 1262 "7 ώρες", 1263 "7 ημέρες", 1264 "7 εβδομάδες", 1265 "7 μήνες", 1266 "7 έτη", 1267 // "el_GR" 7 short 1268 "7 δευτ.", 1269 "7 λεπ.", 1270 "7 ώρ.", // hour (other) 1271 "7 ημέρες", 1272 "7 εβδ.", 1273 "7 μήν.", 1274 "7 έτ.", // year (other) 1275 // "el" 1 wide 1276 "1 δευτερόλεπτο", 1277 "1 λεπτό", 1278 "1 ώρα", 1279 "1 ημέρα", 1280 "1 εβδομάδα", 1281 "1 μήνας", 1282 "1 έτος", 1283 // "el" 1 short 1284 "1 δευτ.", 1285 "1 λεπ.", 1286 "1 ώρα", 1287 "1 ημέρα", 1288 "1 εβδ.", 1289 "1 μήν.", 1290 "1 έτ.", // year (one) 1291 // "el" 7 wide 1292 "7 δευτερόλεπτα", 1293 "7 λεπτά", 1294 "7 ώρες", 1295 "7 ημέρες", 1296 "7 εβδομάδες", 1297 "7 μήνες", 1298 "7 έτη", 1299 // "el" 7 short 1300 "7 δευτ.", 1301 "7 λεπ.", 1302 "7 ώρ.", // hour (other) 1303 "7 ημέρες", 1304 "7 εβδ.", 1305 "7 μήν.", 1306 "7 έτ."}; // year (other 1307 int counter = 0; 1308 String formatted; 1309 for ( int locIndex = 0; locIndex < locales.length; ++locIndex ) { 1310 for( int numIndex = 0; numIndex < numbers.length; ++numIndex ) { 1311 for ( int styleIndex = 0; styleIndex < styles.length; ++styleIndex ) { 1312 for ( int unitIndex = 0; unitIndex < units.length; ++unitIndex ) { 1313 Measure m = new Measure(numbers[numIndex], units[unitIndex]); 1314 MeasureFormat fmt = MeasureFormat.getInstance(new ULocale(locales[locIndex]), styles[styleIndex]); 1315 formatted = fmt.format(m); 1316 assertEquals( 1317 "locale: " + locales[locIndex] 1318 + ", style: " + styles[styleIndex] 1319 + ", units: " + units[unitIndex] 1320 + ", value: " + numbers[numIndex], 1321 expected[counter], formatted); 1322 ++counter; 1323 } 1324 } 1325 } 1326 } 1327 } 1328 1329 @Test 1330 public void testAUnit() { 1331 String lastType = null; 1332 for (MeasureUnit expected : MeasureUnit.getAvailable()) { 1333 String type = expected.getType(); 1334 String code = expected.getSubtype(); 1335 if (!type.equals(lastType)) { 1336 logln(type); 1337 lastType = type; 1338 } 1339 MeasureUnit actual = MeasureUnit.internalGetInstance(type, code); 1340 assertSame("Identity check", expected, actual); 1341 } 1342 } 1343 1344 @Test 1345 public void testFormatSingleArg() { 1346 MeasureFormat mf = MeasureFormat.getInstance(ULocale.ENGLISH, FormatWidth.WIDE); 1347 assertEquals("", "5 meters", mf.format(new Measure(5, MeasureUnit.METER))); 1348 } 1349 1350 @Test 1351 public void testFormatMeasuresZeroArg() { 1352 MeasureFormat mf = MeasureFormat.getInstance(ULocale.ENGLISH, FormatWidth.WIDE); 1353 assertEquals("", "", mf.formatMeasures()); 1354 } 1355 1356 @Test 1357 public void testFormatMeasuresOneArg() { 1358 MeasureFormat mf = MeasureFormat.getInstance(ULocale.ENGLISH, FormatWidth.WIDE); 1359 assertEquals("", "5 meters", mf.formatMeasures(new Measure(5, MeasureUnit.METER))); 1360 } 1361 1362 1363 1364 @Test 1365 public void testMultiples() { 1366 ULocale russia = new ULocale("ru"); 1367 Object[][] data = new Object[][] { 1368 {ULocale.ENGLISH, FormatWidth.WIDE, "2 miles, 1 foot, 2.3 inches"}, 1369 {ULocale.ENGLISH, FormatWidth.SHORT, "2 mi, 1 ft, 2.3 in"}, 1370 {ULocale.ENGLISH, FormatWidth.NARROW, "2mi 1\u2032 2.3\u2033"}, 1371 {russia, FormatWidth.WIDE, "2 \u043C\u0438\u043B\u0438 1 \u0444\u0443\u0442 \u0438 2,3 \u0434\u044E\u0439\u043C\u0430"}, 1372 {russia, FormatWidth.SHORT, "2 \u043C\u0438\u043B\u0438 1 \u0444\u0443\u0442 \u0438 2,3 \u0434\u044E\u0439\u043C."}, 1373 {russia, FormatWidth.NARROW, "2 \u043C\u0438\u043B\u044C 1 \u0444\u0443\u0442 2,3 \u0434\u044E\u0439\u043C\u0430"}, 1374 }; 1375 for (Object[] row : data) { 1376 MeasureFormat mf = MeasureFormat.getInstance( 1377 (ULocale) row[0], (FormatWidth) row[1]); 1378 assertEquals( 1379 "testMultiples", 1380 row[2], 1381 mf.formatMeasures( 1382 new Measure(2, MeasureUnit.MILE), 1383 new Measure(1, MeasureUnit.FOOT), 1384 new Measure(2.3, MeasureUnit.INCH))); 1385 } 1386 } 1387 1388 @Test 1389 public void testManyLocaleDurations() { 1390 Measure hours = new Measure(5, MeasureUnit.HOUR); 1391 Measure minutes = new Measure(37, MeasureUnit.MINUTE); 1392 ULocale ulocDanish = new ULocale("da"); 1393 ULocale ulocSpanish = new ULocale("es"); 1394 ULocale ulocFinnish = new ULocale("fi"); 1395 ULocale ulocIcelandic = new ULocale("is"); 1396 ULocale ulocNorwegianBok = new ULocale("nb"); 1397 ULocale ulocNorwegianNyn = new ULocale("nn"); 1398 ULocale ulocDutch = new ULocale("nl"); 1399 ULocale ulocSwedish = new ULocale("sv"); 1400 Object[][] data = new Object[][] { 1401 { ulocDanish, FormatWidth.NARROW, "5 t og 37 min" }, 1402 { ulocDanish, FormatWidth.NUMERIC, "5.37" }, 1403 { ULocale.GERMAN, FormatWidth.NARROW, "5 Std., 37 Min." }, 1404 { ULocale.GERMAN, FormatWidth.NUMERIC, "5:37" }, 1405 { ULocale.ENGLISH, FormatWidth.NARROW, "5h 37m" }, 1406 { ULocale.ENGLISH, FormatWidth.NUMERIC, "5:37" }, 1407 { ulocSpanish, FormatWidth.NARROW, "5h 37min" }, 1408 { ulocSpanish, FormatWidth.NUMERIC, "5:37" }, 1409 { ulocFinnish, FormatWidth.NARROW, "5t 37min" }, 1410 { ulocFinnish, FormatWidth.NUMERIC, "5.37" }, 1411 { ULocale.FRENCH, FormatWidth.NARROW, "5h 37m" }, 1412 { ULocale.FRENCH, FormatWidth.NUMERIC, "05:37" }, 1413 { ulocIcelandic, FormatWidth.NARROW, "5 klst. og 37 m\u00EDn." }, 1414 { ulocIcelandic, FormatWidth.NUMERIC, "5:37" }, 1415 { ULocale.JAPANESE, FormatWidth.NARROW, "5h37m" }, 1416 { ULocale.JAPANESE, FormatWidth.NUMERIC, "5:37" }, 1417 { ulocNorwegianBok, FormatWidth.NARROW, "5t, 37m" }, 1418 { ulocNorwegianBok, FormatWidth.NUMERIC, "5:37" }, 1419 { ulocDutch, FormatWidth.NARROW, "5 u, 37 m" }, 1420 { ulocDutch, FormatWidth.NUMERIC, "5:37" }, 1421 { ulocNorwegianNyn, FormatWidth.NARROW, "5 h og 37 min" }, 1422 { ulocNorwegianNyn, FormatWidth.NUMERIC, "5:37" }, 1423 { ulocSwedish, FormatWidth.NARROW, "5h 37m" }, 1424 { ulocSwedish, FormatWidth.NUMERIC, "5:37" }, 1425 { ULocale.CHINESE, FormatWidth.NARROW, "5\u5C0F\u65F637\u5206\u949F" }, 1426 { ULocale.CHINESE, FormatWidth.NUMERIC, "5:37" }, 1427 }; 1428 for (Object[] row : data) { 1429 MeasureFormat mf = null; 1430 try{ 1431 mf = MeasureFormat.getInstance( (ULocale)row[0], (FormatWidth)row[1] ); 1432 } catch(Exception e) { 1433 errln("Exception creating MeasureFormat for locale " + row[0] + ", width " + 1434 row[1] + ": " + e); 1435 continue; 1436 } 1437 String result = mf.formatMeasures(hours, minutes); 1438 if (!result.equals(row[2])) { 1439 errln("MeasureFormat.formatMeasures for locale " + row[0] + ", width " + 1440 row[1] + ", expected \"" + (String)row[2] + "\", got \"" + result + "\"" ); 1441 } 1442 } 1443 } 1444 1445 @Test 1446 public void testSimplePer() { 1447 Object DONT_CARE = null; 1448 Object[][] data = new Object[][] { 1449 // per unit pattern 1450 {FormatWidth.WIDE, 1.0, MeasureUnit.SECOND, "1 pound per second", DONT_CARE, 0, 0}, 1451 {FormatWidth.WIDE, 2.0, MeasureUnit.SECOND, "2 pounds per second", DONT_CARE, 0, 0}, 1452 // compound pattern 1453 {FormatWidth.WIDE, 1.0, MeasureUnit.MINUTE, "1 pound per minute", DONT_CARE, 0, 0}, 1454 {FormatWidth.WIDE, 2.0, MeasureUnit.MINUTE, "2 pounds per minute", DONT_CARE, 0, 0}, 1455 // per unit 1456 {FormatWidth.SHORT, 1.0, MeasureUnit.SECOND, "1 lb/s", DONT_CARE, 0, 0}, 1457 {FormatWidth.SHORT, 2.0, MeasureUnit.SECOND, "2 lb/s", DONT_CARE, 0, 0}, 1458 // compound 1459 {FormatWidth.SHORT, 1.0, MeasureUnit.MINUTE, "1 lb/min", DONT_CARE, 0, 0}, 1460 {FormatWidth.SHORT, 2.0, MeasureUnit.MINUTE, "2 lb/min", DONT_CARE, 0, 0}, 1461 // per unit 1462 {FormatWidth.NARROW, 1.0, MeasureUnit.SECOND, "1#/s", DONT_CARE, 0, 0}, 1463 {FormatWidth.NARROW, 2.0, MeasureUnit.SECOND, "2#/s", DONT_CARE, 0, 0}, 1464 // compound 1465 {FormatWidth.NARROW, 1.0, MeasureUnit.MINUTE, "1#/min", DONT_CARE, 0, 0}, 1466 {FormatWidth.NARROW, 2.0, MeasureUnit.MINUTE, "2#/min", DONT_CARE, 0, 0}, 1467 // field positions 1468 {FormatWidth.SHORT, 23.3, MeasureUnit.SECOND, "23.3 lb/s", NumberFormat.Field.DECIMAL_SEPARATOR, 2, 3}, 1469 {FormatWidth.SHORT, 23.3, MeasureUnit.SECOND, "23.3 lb/s", NumberFormat.Field.INTEGER, 0, 2}, 1470 {FormatWidth.SHORT, 23.3, MeasureUnit.MINUTE, "23.3 lb/min", NumberFormat.Field.DECIMAL_SEPARATOR, 2, 3}, 1471 {FormatWidth.SHORT, 23.3, MeasureUnit.MINUTE, "23.3 lb/min", NumberFormat.Field.INTEGER, 0, 2}, 1472 1473 }; 1474 1475 for (Object[] row : data) { 1476 FormatWidth formatWidth = (FormatWidth) row[0]; 1477 Number amount = (Number) row[1]; 1478 MeasureUnit perUnit = (MeasureUnit) row[2]; 1479 String expected = row[3].toString(); 1480 NumberFormat.Field field = (NumberFormat.Field) row[4]; 1481 int startOffset = ((Integer) row[5]).intValue(); 1482 int endOffset = ((Integer) row[6]).intValue(); 1483 MeasureFormat mf = MeasureFormat.getInstance( 1484 ULocale.ENGLISH, formatWidth); 1485 FieldPosition pos = field != null ? new FieldPosition(field) : new FieldPosition(0); 1486 String prefix = "Prefix: "; 1487 assertEquals( 1488 "", 1489 prefix + expected, 1490 mf.formatMeasurePerUnit( 1491 new Measure(amount, MeasureUnit.POUND), 1492 perUnit, 1493 new StringBuilder(prefix), 1494 pos).toString()); 1495 if (field != DONT_CARE) { 1496 assertEquals("startOffset", startOffset, pos.getBeginIndex() - prefix.length()); 1497 assertEquals("endOffset", endOffset, pos.getEndIndex() - prefix.length()); 1498 } 1499 } 1500 } 1501 1502 @Test 1503 public void testNumeratorPlurals() { 1504 ULocale polish = new ULocale("pl"); 1505 Object[][] data = new Object[][] { 1506 {1, "1 stopa na sekundę"}, 1507 {2, "2 stopy na sekundę"}, 1508 {5, "5 stóp na sekundę"}, 1509 {1.5, "1,5 stopy na sekundę"}}; 1510 1511 for (Object[] row : data) { 1512 MeasureFormat mf = MeasureFormat.getInstance(polish, FormatWidth.WIDE); 1513 assertEquals( 1514 "", 1515 row[1], 1516 mf.formatMeasurePerUnit( 1517 new Measure((Number) row[0], MeasureUnit.FOOT), 1518 MeasureUnit.SECOND, 1519 new StringBuilder(), 1520 new FieldPosition(0)).toString()); 1521 } 1522 } 1523 1524 @Test 1525 public void testGram() { 1526 MeasureFormat mf = MeasureFormat.getInstance(ULocale.ENGLISH, FormatWidth.SHORT); 1527 assertEquals( 1528 "testGram", 1529 "1 g", 1530 mf.format(new Measure(1, MeasureUnit.GRAM))); 1531 assertEquals( 1532 "testGram", 1533 "1 G", 1534 mf.format(new Measure(1, MeasureUnit.G_FORCE))); 1535 } 1536 1537 @Test 1538 public void testCurrencies() { 1539 Measure USD_1 = new Measure(1.0, Currency.getInstance("USD")); 1540 Measure USD_2 = new Measure(2.0, Currency.getInstance("USD")); 1541 Measure USD_NEG_1 = new Measure(-1.0, Currency.getInstance("USD")); 1542 MeasureFormat mf = MeasureFormat.getInstance(ULocale.ENGLISH, FormatWidth.WIDE); 1543 assertEquals("Wide currency", "-1.00 US dollars", mf.format(USD_NEG_1)); 1544 assertEquals("Wide currency", "1.00 US dollars", mf.format(USD_1)); 1545 assertEquals("Wide currency", "2.00 US dollars", mf.format(USD_2)); 1546 mf = MeasureFormat.getInstance(ULocale.ENGLISH, FormatWidth.SHORT); 1547 assertEquals("short currency", "-USD1.00", mf.format(USD_NEG_1)); 1548 assertEquals("short currency", "USD1.00", mf.format(USD_1)); 1549 assertEquals("short currency", "USD2.00", mf.format(USD_2)); 1550 mf = MeasureFormat.getInstance(ULocale.ENGLISH, FormatWidth.NARROW); 1551 assertEquals("narrow currency", "-$1.00", mf.format(USD_NEG_1)); 1552 assertEquals("narrow currency", "$1.00", mf.format(USD_1)); 1553 assertEquals("narrow currency", "$2.00", mf.format(USD_2)); 1554 mf = MeasureFormat.getInstance(ULocale.ENGLISH, FormatWidth.NUMERIC); 1555 assertEquals("numeric currency", "-$1.00", mf.format(USD_NEG_1)); 1556 assertEquals("numeric currency", "$1.00", mf.format(USD_1)); 1557 assertEquals("numeric currency", "$2.00", mf.format(USD_2)); 1558 1559 mf = MeasureFormat.getInstance(ULocale.JAPAN, FormatWidth.WIDE); 1560 assertEquals("Wide currency", "-1.00\u7C73\u30C9\u30EB", mf.format(USD_NEG_1)); 1561 assertEquals("Wide currency", "1.00\u7C73\u30C9\u30EB", mf.format(USD_1)); 1562 assertEquals("Wide currency", "2.00\u7C73\u30C9\u30EB", mf.format(USD_2)); 1563 1564 Measure CAD_1 = new Measure(1.0, Currency.getInstance("CAD")); 1565 mf = MeasureFormat.getInstance(ULocale.CANADA, FormatWidth.SHORT); 1566 assertEquals("short currency", "CAD1.00", mf.format(CAD_1)); 1567 } 1568 1569 @Test 1570 public void testDisplayNames() { 1571 Object[][] data = new Object[][] { 1572 // Unit, locale, width, expected result 1573 { MeasureUnit.YEAR, "en", FormatWidth.WIDE, "years" }, 1574 { MeasureUnit.YEAR, "ja", FormatWidth.WIDE, "年" }, 1575 { MeasureUnit.YEAR, "es", FormatWidth.WIDE, "años" }, 1576 { MeasureUnit.YEAR, "pt", FormatWidth.WIDE, "anos" }, 1577 { MeasureUnit.YEAR, "pt-PT", FormatWidth.WIDE, "anos" }, 1578 { MeasureUnit.AMPERE, "en", FormatWidth.WIDE, "amperes" }, 1579 { MeasureUnit.AMPERE, "ja", FormatWidth.WIDE, "アンペア" }, 1580 { MeasureUnit.AMPERE, "es", FormatWidth.WIDE, "amperios" }, 1581 { MeasureUnit.AMPERE, "pt", FormatWidth.WIDE, "amperes" }, 1582 { MeasureUnit.AMPERE, "pt-PT", FormatWidth.WIDE, "amperes" }, 1583 { MeasureUnit.METER_PER_SECOND_SQUARED, "pt", FormatWidth.WIDE, "metros por segundo ao quadrado" }, 1584 { MeasureUnit.METER_PER_SECOND_SQUARED, "pt-PT", FormatWidth.WIDE, "metros por segundo quadrado" }, 1585 { MeasureUnit.SQUARE_KILOMETER, "pt", FormatWidth.NARROW, "km²" }, 1586 { MeasureUnit.SQUARE_KILOMETER, "pt", FormatWidth.SHORT, "km²" }, 1587 { MeasureUnit.SQUARE_KILOMETER, "pt", FormatWidth.WIDE, "quilômetros quadrados" }, 1588 { MeasureUnit.SECOND, "pt-PT", FormatWidth.NARROW, "s" }, 1589 { MeasureUnit.SECOND, "pt-PT", FormatWidth.SHORT, "s" }, 1590 { MeasureUnit.SECOND, "pt-PT", FormatWidth.WIDE, "segundos" }, 1591 { MeasureUnit.SECOND, "pt", FormatWidth.NARROW, "seg" }, 1592 { MeasureUnit.SECOND, "pt", FormatWidth.SHORT, "segs" }, 1593 { MeasureUnit.SECOND, "pt", FormatWidth.WIDE, "segundos" }, 1594 }; 1595 1596 for (Object[] test : data) { 1597 MeasureUnit unit = (MeasureUnit) test[0]; 1598 ULocale locale = ULocale.forLanguageTag((String) test[1]); 1599 FormatWidth formatWidth = (FormatWidth) test[2]; 1600 String expected = (String) test[3]; 1601 1602 MeasureFormat mf = MeasureFormat.getInstance(locale, formatWidth); 1603 String actual = mf.getUnitDisplayName(unit); 1604 assertEquals(String.format("Unit Display Name for %s, %s, %s", unit, locale, formatWidth), 1605 expected, actual); 1606 } 1607 } 1608 1609 @Test 1610 public void testFieldPosition() { 1611 MeasureFormat fmt = MeasureFormat.getInstance( 1612 ULocale.ENGLISH, FormatWidth.SHORT); 1613 FieldPosition pos = new FieldPosition(NumberFormat.Field.DECIMAL_SEPARATOR); 1614 fmt.format(new Measure(43.5, MeasureUnit.FOOT), new StringBuffer("123456: "), pos); 1615 assertEquals("beginIndex", 10, pos.getBeginIndex()); 1616 assertEquals("endIndex", 11, pos.getEndIndex()); 1617 1618 pos = new FieldPosition(NumberFormat.Field.DECIMAL_SEPARATOR); 1619 fmt.format(new Measure(43, MeasureUnit.FOOT), new StringBuffer(), pos); 1620 assertEquals("beginIndex", 0, pos.getBeginIndex()); 1621 assertEquals("endIndex", 0, pos.getEndIndex()); 1622 } 1623 1624 @Test 1625 public void testFieldPositionMultiple() { 1626 MeasureFormat fmt = MeasureFormat.getInstance( 1627 ULocale.ENGLISH, FormatWidth.SHORT); 1628 FieldPosition pos = new FieldPosition(NumberFormat.Field.INTEGER); 1629 String result = fmt.formatMeasures( 1630 new StringBuilder(), 1631 pos, 1632 new Measure(354, MeasureUnit.METER), 1633 new Measure(23, MeasureUnit.CENTIMETER)).toString(); 1634 assertEquals("result", "354 m, 23 cm", result); 1635 1636 // According to javadocs for {@link Format#format} FieldPosition is set to 1637 // beginning and end of first such field encountered instead of the last 1638 // such field encountered. 1639 assertEquals("beginIndex", 0, pos.getBeginIndex()); 1640 assertEquals("endIndex", 3, pos.getEndIndex()); 1641 1642 pos = new FieldPosition(NumberFormat.Field.DECIMAL_SEPARATOR); 1643 result = fmt.formatMeasures( 1644 new StringBuilder("123456: "), 1645 pos, 1646 new Measure(354, MeasureUnit.METER), 1647 new Measure(23, MeasureUnit.CENTIMETER), 1648 new Measure(5.4, MeasureUnit.MILLIMETER)).toString(); 1649 assertEquals("result", "123456: 354 m, 23 cm, 5.4 mm", result); 1650 assertEquals("beginIndex", 23, pos.getBeginIndex()); 1651 assertEquals("endIndex", 24, pos.getEndIndex()); 1652 1653 result = fmt.formatMeasures( 1654 new StringBuilder(), 1655 pos, 1656 new Measure(3, MeasureUnit.METER), 1657 new Measure(23, MeasureUnit.CENTIMETER), 1658 new Measure(5.4, MeasureUnit.MILLIMETER)).toString(); 1659 assertEquals("result", "3 m, 23 cm, 5.4 mm", result); 1660 assertEquals("beginIndex", 13, pos.getBeginIndex()); 1661 assertEquals("endIndex", 14, pos.getEndIndex()); 1662 1663 pos = new FieldPosition(NumberFormat.Field.DECIMAL_SEPARATOR); 1664 result = fmt.formatMeasures( 1665 new StringBuilder("123456: "), 1666 pos, 1667 new Measure(3, MeasureUnit.METER), 1668 new Measure(23, MeasureUnit.CENTIMETER), 1669 new Measure(5, MeasureUnit.MILLIMETER)).toString(); 1670 assertEquals("result", "123456: 3 m, 23 cm, 5 mm", result); 1671 assertEquals("beginIndex", 0, pos.getBeginIndex()); 1672 assertEquals("endIndex", 0, pos.getEndIndex()); 1673 1674 pos = new FieldPosition(NumberFormat.Field.INTEGER); 1675 result = fmt.formatMeasures( 1676 new StringBuilder("123456: "), 1677 pos, 1678 new Measure(57, MeasureUnit.MILLIMETER)).toString(); 1679 assertEquals("result", "123456: 57 mm", result); 1680 assertEquals("beginIndex", 8, pos.getBeginIndex()); 1681 assertEquals("endIndex", 10, pos.getEndIndex()); 1682 1683 } 1684 1685 @Test 1686 public void testOldFormatWithList() { 1687 List<Measure> measures = new ArrayList<Measure>(2); 1688 measures.add(new Measure(5, MeasureUnit.ACRE)); 1689 measures.add(new Measure(3000, MeasureUnit.SQUARE_FOOT)); 1690 MeasureFormat fmt = MeasureFormat.getInstance( 1691 ULocale.ENGLISH, FormatWidth.WIDE); 1692 assertEquals("", "5 acres, 3,000 square feet", fmt.format(measures)); 1693 assertEquals("", "5 acres", fmt.format(measures.subList(0, 1))); 1694 List<String> badList = new ArrayList<String>(); 1695 badList.add("be"); 1696 badList.add("you"); 1697 try { 1698 fmt.format(badList); 1699 fail("Expected IllegalArgumentException."); 1700 } catch (IllegalArgumentException expected) { 1701 // Expected 1702 } 1703 } 1704 1705 @Test 1706 public void testOldFormatWithArray() { 1707 Measure[] measures = new Measure[] { 1708 new Measure(5, MeasureUnit.ACRE), 1709 new Measure(3000, MeasureUnit.SQUARE_FOOT), 1710 }; 1711 MeasureFormat fmt = MeasureFormat.getInstance( 1712 ULocale.ENGLISH, FormatWidth.WIDE); 1713 assertEquals("", "5 acres, 3,000 square feet", fmt.format(measures)); 1714 } 1715 1716 @Test 1717 public void testOldFormatBadArg() { 1718 MeasureFormat fmt = MeasureFormat.getInstance( 1719 ULocale.ENGLISH, FormatWidth.WIDE); 1720 try { 1721 fmt.format("be"); 1722 fail("Expected IllegalArgumentExceptino."); 1723 } catch (IllegalArgumentException e) { 1724 // Expected 1725 } 1726 } 1727 1728 @Test 1729 public void testUnitPerUnitResolution() { 1730 // Ticket 11274 1731 MeasureFormat fmt = MeasureFormat.getInstance(Locale.ENGLISH, FormatWidth.SHORT); 1732 1733 // This fails unless we resolve to MeasureUnit.POUND_PER_SQUARE_INCH 1734 assertEquals("", "50 psi", 1735 fmt.formatMeasurePerUnit( 1736 new Measure(50, MeasureUnit.POUND), 1737 MeasureUnit.SQUARE_INCH, 1738 new StringBuilder(), 1739 new FieldPosition(0)).toString()); 1740 } 1741 1742 @Test 1743 public void testEqHashCode() { 1744 MeasureFormat mf = MeasureFormat.getInstance(ULocale.CANADA, FormatWidth.SHORT); 1745 MeasureFormat mfeq = MeasureFormat.getInstance(ULocale.CANADA, FormatWidth.SHORT); 1746 MeasureFormat mfne = MeasureFormat.getInstance(ULocale.CANADA, FormatWidth.WIDE); 1747 MeasureFormat mfne2 = MeasureFormat.getInstance(ULocale.ENGLISH, FormatWidth.SHORT); 1748 verifyEqualsHashCode(mf, mfeq, mfne); 1749 verifyEqualsHashCode(mf, mfeq, mfne2); 1750 } 1751 1752 @Test 1753 public void testEqHashCodeOfMeasure() { 1754 Measure _3feetDouble = new Measure(3.0, MeasureUnit.FOOT); 1755 Measure _3feetInt = new Measure(3, MeasureUnit.FOOT); 1756 Measure _4feetInt = new Measure(4, MeasureUnit.FOOT); 1757 verifyEqualsHashCode(_3feetDouble, _3feetInt, _4feetInt); 1758 } 1759 1760 @Test 1761 public void testGetLocale() { 1762 MeasureFormat mf = MeasureFormat.getInstance(ULocale.GERMAN, FormatWidth.SHORT); 1763 assertEquals("", ULocale.GERMAN, mf.getLocale(ULocale.VALID_LOCALE)); 1764 } 1765 1766 @Test 1767 public void TestSerial() { 1768 checkStreamingEquality(MeasureUnit.CELSIUS); 1769 checkStreamingEquality(MeasureFormat.getInstance(ULocale.FRANCE, FormatWidth.NARROW)); 1770 checkStreamingEquality(Currency.getInstance("EUR")); 1771 checkStreamingEquality(MeasureFormat.getInstance(ULocale.GERMAN, FormatWidth.SHORT)); 1772 checkStreamingEquality(MeasureFormat.getCurrencyFormat(ULocale.ITALIAN)); 1773 } 1774 1775 @Test 1776 public void TestSerialFormatWidthEnum() { 1777 // FormatWidth enum values must map to the same ordinal values for all time in order for 1778 // serialization to work. 1779 assertEquals("FormatWidth.WIDE", 0, FormatWidth.WIDE.ordinal()); 1780 assertEquals("FormatWidth.SHORT", 1, FormatWidth.SHORT.ordinal()); 1781 assertEquals("FormatWidth.NARROW", 2, FormatWidth.NARROW.ordinal()); 1782 assertEquals("FormatWidth.NUMERIC", 3, FormatWidth.NUMERIC.ordinal()); 1783 } 1784 1785 @Test 1786 public void testCurrencyFormatStandInForMeasureFormat() { 1787 MeasureFormat mf = MeasureFormat.getCurrencyFormat(ULocale.ENGLISH); 1788 assertEquals( 1789 "70 feet, 5.3 inches", 1790 "70 feet, 5.3 inches", 1791 mf.formatMeasures( 1792 new Measure(70, MeasureUnit.FOOT), 1793 new Measure(5.3, MeasureUnit.INCH))); 1794 assertEquals("getLocale", ULocale.ENGLISH, mf.getLocale()); 1795 assertEquals("getNumberFormat", ULocale.ENGLISH, mf.getNumberFormat().getLocale(ULocale.VALID_LOCALE)); 1796 assertEquals("getWidth", MeasureFormat.FormatWidth.WIDE, mf.getWidth()); 1797 } 1798 1799 @Test 1800 public void testCurrencyFormatLocale() { 1801 MeasureFormat mfu = MeasureFormat.getCurrencyFormat(ULocale.FRANCE); 1802 MeasureFormat mfj = MeasureFormat.getCurrencyFormat(Locale.FRANCE); 1803 1804 assertEquals("getCurrencyFormat ULocale/Locale", mfu, mfj); 1805 } 1806 1807 @Test 1808 public void testDoubleZero() { 1809 ULocale en = new ULocale("en"); 1810 NumberFormat nf = NumberFormat.getInstance(en); 1811 nf.setMinimumFractionDigits(2); 1812 nf.setMaximumFractionDigits(2); 1813 MeasureFormat mf = MeasureFormat.getInstance(en, FormatWidth.WIDE, nf); 1814 assertEquals( 1815 "Positive Rounding", 1816 "4 hours, 23 minutes, 16.00 seconds", 1817 mf.formatMeasures( 1818 new Measure(4.7, MeasureUnit.HOUR), 1819 new Measure(23, MeasureUnit.MINUTE), 1820 new Measure(16, MeasureUnit.SECOND))); 1821 assertEquals( 1822 "Negative Rounding", 1823 "-4 hours, 23 minutes, 16.00 seconds", 1824 mf.formatMeasures( 1825 new Measure(-4.7, MeasureUnit.HOUR), 1826 new Measure(23, MeasureUnit.MINUTE), 1827 new Measure(16, MeasureUnit.SECOND))); 1828 1829 } 1830 1831 @Test 1832 public void testIndividualPluralFallback() { 1833 // See ticket #11986 "incomplete fallback in MeasureFormat". 1834 // In CLDR 28, fr_CA temperature-generic/short has only the "one" form, 1835 // and falls back to fr for the "other" form. 1836 MeasureFormat mf = MeasureFormat.getInstance(new ULocale("fr_CA"), FormatWidth.SHORT); 1837 Measure twoDeg = new Measure(2, MeasureUnit.GENERIC_TEMPERATURE); 1838 assertEquals("2 deg temp in fr_CA", "2°", mf.format(twoDeg)); 1839 } 1840 1841 @Test 1842 public void testPopulateCache() { 1843 // Quick check that the lazily added additions to the MeasureUnit cache are present. 1844 assertTrue("MeasureUnit: unexpectedly few currencies defined", MeasureUnit.getAvailable("currency").size() > 50); 1845 } 1846 1847 @Test 1848 public void testParseObject() { 1849 MeasureFormat mf = MeasureFormat.getInstance(Locale.GERMAN, FormatWidth.NARROW); 1850 try { 1851 mf.parseObject("3m", null); 1852 fail("MeasureFormat.parseObject(String, ParsePosition) " + 1853 "should throw an UnsupportedOperationException"); 1854 } catch (UnsupportedOperationException expected) { 1855 } 1856 } 1857 1858 @Test 1859 public void testCLDRUnitAvailability() { 1860 Set<MeasureUnit> knownUnits = new HashSet<MeasureUnit>(); 1861 Class cMeasureUnit, cTimeUnit; 1862 try { 1863 cMeasureUnit = Class.forName("com.ibm.icu.util.MeasureUnit"); 1864 cTimeUnit = Class.forName("com.ibm.icu.util.TimeUnit"); 1865 } catch (ClassNotFoundException e) { 1866 fail("Count not load MeasureUnit or TimeUnit class: " + e.getMessage()); 1867 return; 1868 } 1869 for (Field field : cMeasureUnit.getFields()) { 1870 if (field.getGenericType() == cMeasureUnit || field.getGenericType() == cTimeUnit) { 1871 try { 1872 MeasureUnit unit = (MeasureUnit) field.get(cMeasureUnit); 1873 knownUnits.add(unit); 1874 } catch (IllegalArgumentException e) { 1875 fail(e.getMessage()); 1876 return; 1877 } catch (IllegalAccessException e) { 1878 fail(e.getMessage()); 1879 return; 1880 } 1881 } 1882 } 1883 for (String type : MeasureUnit.getAvailableTypes()) { 1884 if (type.equals("currency") || type.equals("compound")) { 1885 continue; 1886 } 1887 for (MeasureUnit unit : MeasureUnit.getAvailable(type)) { 1888 if (!knownUnits.contains(unit)) { 1889 fail("Unit present in CLDR but not available via constant in MeasureUnit: " + unit); 1890 } 1891 } 1892 } 1893 } 1894 1895 // DO NOT DELETE THIS FUNCTION! It may appear as dead code, but we use this to generate code 1896 // for MeasureFormat during the release process. 1897 static Map<MeasureUnit, Pair<MeasureUnit, MeasureUnit>> getUnitsToPerParts() { 1898 TreeMap<String, List<MeasureUnit>> allUnits = getAllUnits(); 1899 Map<MeasureUnit, Pair<String, String>> unitsToPerStrings = 1900 new HashMap<MeasureUnit, Pair<String, String>>(); 1901 Map<String, MeasureUnit> namesToUnits = new HashMap<String, MeasureUnit>(); 1902 for (Map.Entry<String, List<MeasureUnit>> entry : allUnits.entrySet()) { 1903 String type = entry.getKey(); 1904 // Currency types are always atomic units, so we can skip these 1905 if (type.equals("currency")) { 1906 continue; 1907 } 1908 for (MeasureUnit unit : entry.getValue()) { 1909 String javaName = toJAVAName(unit); 1910 String[] nameParts = javaName.split("_PER_"); 1911 if (nameParts.length == 1) { 1912 namesToUnits.put(nameParts[0], unit); 1913 } else if (nameParts.length == 2) { 1914 unitsToPerStrings.put(unit, Pair.of(nameParts[0], nameParts[1])); 1915 } 1916 } 1917 } 1918 Map<MeasureUnit, Pair<MeasureUnit, MeasureUnit>> unitsToPerUnits = 1919 new HashMap<MeasureUnit, Pair<MeasureUnit, MeasureUnit>>(); 1920 for (Map.Entry<MeasureUnit, Pair<String, String>> entry : unitsToPerStrings.entrySet()) { 1921 Pair<String, String> perStrings = entry.getValue(); 1922 MeasureUnit unit = namesToUnits.get(perStrings.first); 1923 MeasureUnit perUnit = namesToUnits.get(perStrings.second); 1924 if (unit != null && perUnit != null) { 1925 unitsToPerUnits.put(entry.getKey(), Pair.of(unit, perUnit)); 1926 } 1927 } 1928 return unitsToPerUnits; 1929 } 1930 1931 // DO NOT DELETE THIS FUNCTION! It may appear as dead code, but we use this to generate code 1932 // for MeasureFormat during the release process. 1933 static void generateCXXHConstants(String thisVersion) { 1934 Map<String, MeasureUnit> seen = new HashMap<String, MeasureUnit>(); 1935 System.out.println(); 1936 TreeMap<String, List<MeasureUnit>> allUnits = getAllUnits(); 1937 for (Map.Entry<String, List<MeasureUnit>> entry : allUnits.entrySet()) { 1938 String type = entry.getKey(); 1939 if (type.equals("currency")) { 1940 continue; 1941 } 1942 for (MeasureUnit unit : entry.getValue()) { 1943 String code = unit.getSubtype(); 1944 String name = toCamelCase(unit); 1945 String javaName = toJAVAName(unit); 1946 checkForDup(seen, name, unit); 1947 if (isDraft(javaName)) { 1948 System.out.println("#ifndef U_HIDE_DRAFT_API"); 1949 } 1950 System.out.println(" /**"); 1951 System.out.println(" * Returns unit of " + type + ": " + code + "."); 1952 System.out.println(" * Caller owns returned value and must free it."); 1953 System.out.println(" * @param status ICU error code."); 1954 if (isDraft(javaName)) { 1955 System.out.println(" * @draft ICU " + getVersion(javaName, thisVersion)); 1956 } else { 1957 System.out.println(" * @stable ICU " + getVersion(javaName, thisVersion)); 1958 } 1959 System.out.println(" */"); 1960 System.out.printf(" static MeasureUnit *create%s(UErrorCode &status);\n\n", name); 1961 if (isDraft(javaName)) { 1962 System.out.println("#endif /* U_HIDE_DRAFT_API */"); 1963 } 1964 } 1965 } 1966 } 1967 1968 private static void checkForDup( 1969 Map<String, MeasureUnit> seen, String name, MeasureUnit unit) { 1970 if (seen.containsKey(name)) { 1971 throw new RuntimeException("\nCollision!!" + unit + ", " + seen.get(name)); 1972 } else { 1973 seen.put(name, unit); 1974 } 1975 } 1976 1977 // DO NOT DELETE THIS FUNCTION! It may appear as dead code, but we use this to generate code 1978 // for MeasureFormat during the release process. 1979 static void updateJAVAVersions(String thisVersion) { 1980 System.out.println(); 1981 Map<String, MeasureUnit> seen = new HashMap<String, MeasureUnit>(); 1982 TreeMap<String, List<MeasureUnit>> allUnits = getAllUnits(); 1983 for (Map.Entry<String, List<MeasureUnit>> entry : allUnits.entrySet()) { 1984 String type = entry.getKey(); 1985 if (type.equals("currency")) { 1986 continue; 1987 } 1988 for (MeasureUnit unit : entry.getValue()) { 1989 String javaName = toJAVAName(unit); 1990 checkForDup(seen, javaName, unit); 1991 if (!JAVA_VERSION_MAP.containsKey(javaName)) { 1992 System.out.printf(" {\"%s\", \"%s\"},\n", javaName, thisVersion); 1993 } 1994 } 1995 } 1996 } 1997 1998 static TreeMap<String, List<MeasureUnit>> getAllUnits() { 1999 TreeMap<String, List<MeasureUnit>> allUnits = new TreeMap<String, List<MeasureUnit>>(); 2000 for (String type : MeasureUnit.getAvailableTypes()) { 2001 ArrayList<MeasureUnit> units = new ArrayList<MeasureUnit>(MeasureUnit.getAvailable(type)); 2002 Collections.sort( 2003 units, 2004 new Comparator<MeasureUnit>() { 2005 2006 @Override 2007 public int compare(MeasureUnit o1, MeasureUnit o2) { 2008 return o1.getSubtype().compareTo(o2.getSubtype()); 2009 } 2010 2011 }); 2012 allUnits.put(type, units); 2013 } 2014 return allUnits; 2015 } 2016 2017 // DO NOT DELETE THIS FUNCTION! It may appear as dead code, but we use this to generate code 2018 // for MeasureFormat during the release process. 2019 static void generateCXXConstants() { 2020 System.out.println(""); 2021 TreeMap<String, List<MeasureUnit>> allUnits = getAllUnits(); 2022 2023 System.out.println("static const int32_t gOffsets[] = {"); 2024 int index = 0; 2025 for (Map.Entry<String, List<MeasureUnit>> entry : allUnits.entrySet()) { 2026 System.out.printf(" %d,\n", index); 2027 index += entry.getValue().size(); 2028 } 2029 System.out.printf(" %d\n", index); 2030 System.out.println("};"); 2031 System.out.println(); 2032 System.out.println("static const int32_t gIndexes[] = {"); 2033 index = 0; 2034 for (Map.Entry<String, List<MeasureUnit>> entry : allUnits.entrySet()) { 2035 System.out.printf(" %d,\n", index); 2036 if (!entry.getKey().equals("currency")) { 2037 index += entry.getValue().size(); 2038 } 2039 } 2040 System.out.printf(" %d\n", index); 2041 System.out.println("};"); 2042 System.out.println(); 2043 System.out.println("// Must be sorted alphabetically."); 2044 System.out.println("static const char * const gTypes[] = {"); 2045 boolean first = true; 2046 for (Map.Entry<String, List<MeasureUnit>> entry : allUnits.entrySet()) { 2047 if (!first) { 2048 System.out.println(","); 2049 } 2050 System.out.print(" \"" + entry.getKey() + "\""); 2051 first = false; 2052 } 2053 System.out.println(); 2054 System.out.println("};"); 2055 System.out.println(); 2056 System.out.println("// Must be grouped by type and sorted alphabetically within each type."); 2057 System.out.println("static const char * const gSubTypes[] = {"); 2058 first = true; 2059 int offset = 0; 2060 int typeIdx = 0; 2061 Map<MeasureUnit, Integer> measureUnitToOffset = new HashMap<MeasureUnit, Integer>(); 2062 Map<MeasureUnit, Pair<Integer, Integer>> measureUnitToTypeSubType = 2063 new HashMap<MeasureUnit, Pair<Integer, Integer>>(); 2064 for (Map.Entry<String, List<MeasureUnit>> entry : allUnits.entrySet()) { 2065 int subTypeIdx = 0; 2066 for (MeasureUnit unit : entry.getValue()) { 2067 if (!first) { 2068 System.out.println(","); 2069 } 2070 System.out.print(" \"" + unit.getSubtype() + "\""); 2071 first = false; 2072 measureUnitToOffset.put(unit, offset); 2073 measureUnitToTypeSubType.put(unit, Pair.of(typeIdx, subTypeIdx)); 2074 offset++; 2075 subTypeIdx++; 2076 } 2077 typeIdx++; 2078 } 2079 System.out.println(); 2080 System.out.println("};"); 2081 System.out.println(); 2082 2083 // Build unit per unit offsets to corresponding type sub types sorted by 2084 // unit first and then per unit. 2085 TreeMap<OrderedPair<Integer, Integer>, Pair<Integer, Integer>> unitPerUnitOffsetsToTypeSubType 2086 = new TreeMap<OrderedPair<Integer, Integer>, Pair<Integer, Integer>>(); 2087 for (Map.Entry<MeasureUnit, Pair<MeasureUnit, MeasureUnit>> entry 2088 : getUnitsToPerParts().entrySet()) { 2089 Pair<MeasureUnit, MeasureUnit> unitPerUnit = entry.getValue(); 2090 unitPerUnitOffsetsToTypeSubType.put( 2091 OrderedPair.of( 2092 measureUnitToOffset.get(unitPerUnit.first), 2093 measureUnitToOffset.get(unitPerUnit.second)), 2094 measureUnitToTypeSubType.get(entry.getKey())); 2095 } 2096 2097 System.out.println("// Must be sorted by first value and then second value."); 2098 System.out.println("static int32_t unitPerUnitToSingleUnit[][4] = {"); 2099 first = true; 2100 for (Map.Entry<OrderedPair<Integer, Integer>, Pair<Integer, Integer>> entry 2101 : unitPerUnitOffsetsToTypeSubType.entrySet()) { 2102 if (!first) { 2103 System.out.println(","); 2104 } 2105 first = false; 2106 OrderedPair<Integer, Integer> unitPerUnitOffsets = entry.getKey(); 2107 Pair<Integer, Integer> typeSubType = entry.getValue(); 2108 System.out.printf(" {%d, %d, %d, %d}", 2109 unitPerUnitOffsets.first, 2110 unitPerUnitOffsets.second, 2111 typeSubType.first, 2112 typeSubType.second); 2113 } 2114 System.out.println(); 2115 System.out.println("};"); 2116 System.out.println(); 2117 2118 Map<String, MeasureUnit> seen = new HashMap<String, MeasureUnit>(); 2119 for (Map.Entry<String, List<MeasureUnit>> entry : allUnits.entrySet()) { 2120 2121 String type = entry.getKey(); 2122 if (type.equals("currency")) { 2123 continue; 2124 } 2125 for (MeasureUnit unit : entry.getValue()) { 2126 String name = toCamelCase(unit); 2127 Pair<Integer, Integer> typeSubType = measureUnitToTypeSubType.get(unit); 2128 if (typeSubType == null) { 2129 throw new IllegalStateException(); 2130 } 2131 checkForDup(seen, name, unit); 2132 System.out.printf("MeasureUnit *MeasureUnit::create%s(UErrorCode &status) {\n", name); 2133 System.out.printf(" return MeasureUnit::create(%d, %d, status);\n", 2134 typeSubType.first, typeSubType.second); 2135 System.out.println("}"); 2136 System.out.println(); 2137 } 2138 } 2139 } 2140 2141 private static String toCamelCase(MeasureUnit unit) { 2142 StringBuilder result = new StringBuilder(); 2143 boolean caps = true; 2144 String code = unit.getSubtype(); 2145 int len = code.length(); 2146 for (int i = 0; i < len; i++) { 2147 char ch = code.charAt(i); 2148 if (ch == '-') { 2149 caps = true; 2150 } else if (caps) { 2151 result.append(Character.toUpperCase(ch)); 2152 caps = false; 2153 } else { 2154 result.append(ch); 2155 } 2156 } 2157 return result.toString(); 2158 } 2159 2160 static boolean isTypeHidden(String type) { 2161 return "currency".equals(type); 2162 } 2163 2164 // DO NOT DELETE THIS FUNCTION! It may appear as dead code, but we use this to generate code 2165 // for MeasureFormat during the release process. 2166 static void generateBackwardCompatibilityTest(String version) { 2167 Map<String, MeasureUnit> seen = new HashMap<String, MeasureUnit>(); 2168 System.out.println(); 2169 System.out.printf(" public void TestCompatible%s() {\n", version.replace(".", "_")); 2170 System.out.println(" MeasureUnit[] units = {"); 2171 TreeMap<String, List<MeasureUnit>> allUnits = getAllUnits(); 2172 int count = 0; 2173 for (Map.Entry<String, List<MeasureUnit>> entry : allUnits.entrySet()) { 2174 if (isTypeHidden(entry.getKey())) { 2175 continue; 2176 } 2177 for (MeasureUnit unit : entry.getValue()) { 2178 String javaName = toJAVAName(unit); 2179 checkForDup(seen, javaName, unit); 2180 System.out.printf(" MeasureUnit.%s,\n", javaName); 2181 count++; 2182 } 2183 } 2184 System.out.println(" };"); 2185 System.out.printf(" assertEquals(\"\", %d, units.length);\n", count); 2186 System.out.println(" }"); 2187 } 2188 2189 // DO NOT DELETE THIS FUNCTION! It may appear as dead code, but we use this to generate code 2190 // for MeasureFormat during the release process. 2191 static void generateCXXBackwardCompatibilityTest(String version) { 2192 System.out.println(); 2193 Map<String, MeasureUnit> seen = new HashMap<String, MeasureUnit>(); 2194 System.out.printf("void MeasureFormatTest::TestCompatible%s() {\n", version.replace(".", "_")); 2195 System.out.println(" UErrorCode status = U_ZERO_ERROR;"); 2196 System.out.println(" LocalPointer<MeasureUnit> measureUnit;"); 2197 TreeMap<String, List<MeasureUnit>> allUnits = getAllUnits(); 2198 for (Map.Entry<String, List<MeasureUnit>> entry : allUnits.entrySet()) { 2199 if (isTypeHidden(entry.getKey())) { 2200 continue; 2201 } 2202 for (MeasureUnit unit : entry.getValue()) { 2203 String camelCase = toCamelCase(unit); 2204 checkForDup(seen, camelCase, unit); 2205 System.out.printf(" measureUnit.adoptInstead(MeasureUnit::create%s(status));\n", camelCase); 2206 } 2207 } 2208 System.out.println(" assertSuccess(\"\", status);"); 2209 System.out.println("}"); 2210 } 2211 2212 static String toJAVAName(MeasureUnit unit) { 2213 String code = unit.getSubtype(); 2214 String type = unit.getType(); 2215 String name = code.toUpperCase(Locale.ENGLISH).replace("-", "_"); 2216 if (type.equals("angle")) { 2217 if (code.equals("minute") || code.equals("second")) { 2218 name = "ARC_" + name; 2219 } 2220 } 2221 return name; 2222 } 2223 2224 // DO NOT DELETE THIS FUNCTION! It may appear as dead code, but we use this to generate code 2225 // for MeasureFormat during the release process. 2226 static void generateConstants(String thisVersion) { 2227 System.out.println(); 2228 Map<String, MeasureUnit> seen = new HashMap<String, MeasureUnit>(); 2229 TreeMap<String, List<MeasureUnit>> allUnits = getAllUnits(); 2230 for (Map.Entry<String, List<MeasureUnit>> entry : allUnits.entrySet()) { 2231 String type = entry.getKey(); 2232 if (isTypeHidden(type)) { 2233 continue; 2234 } 2235 for (MeasureUnit unit : entry.getValue()) { 2236 String name = toJAVAName(unit); 2237 String code = unit.getSubtype(); 2238 checkForDup(seen, name, unit); 2239 System.out.println(" /**"); 2240 System.out.println(" * Constant for unit of " + type + 2241 ": " + 2242 code); 2243 // Special case JAVA had old constants for time from before. 2244 if ("duration".equals(type) && TIME_CODES.contains(code)) { 2245 System.out.println(" * @stable ICU 4.0"); 2246 } 2247 else if (isDraft(name)) { 2248 System.out.println(" * @draft ICU " + getVersion(name, thisVersion)); 2249 System.out.println(" * @provisional This API might change or be removed in a future release."); 2250 } else { 2251 System.out.println(" * @stable ICU " + getVersion(name, thisVersion)); 2252 } 2253 System.out.println(" */"); 2254 if ("duration".equals(type) && TIME_CODES.contains(code)) { 2255 System.out.println(" public static final TimeUnit " + name + " = (TimeUnit) MeasureUnit.internalGetInstance(\"" + 2256 type + 2257 "\", \"" + 2258 code + 2259 "\");"); 2260 } else { 2261 System.out.println(" public static final MeasureUnit " + name + " = MeasureUnit.internalGetInstance(\"" + 2262 type + 2263 "\", \"" + 2264 code + 2265 "\");"); 2266 } 2267 System.out.println(); 2268 } 2269 } 2270 System.out.println(" private static HashMap<Pair<MeasureUnit, MeasureUnit>, MeasureUnit>unitPerUnitToSingleUnit ="); 2271 System.out.println(" new HashMap<Pair<MeasureUnit, MeasureUnit>, MeasureUnit>();"); 2272 System.out.println(); 2273 System.out.println(" static {"); 2274 for (Map.Entry<MeasureUnit, Pair<MeasureUnit, MeasureUnit>> unitPerUnitEntry 2275 : getUnitsToPerParts().entrySet()) { 2276 Pair<MeasureUnit, MeasureUnit> unitPerUnit = unitPerUnitEntry.getValue(); 2277 System.out.println(" unitPerUnitToSingleUnit.put(Pair.<MeasureUnit, MeasureUnit>of(MeasureUnit." + toJAVAName(unitPerUnit.first) + ", MeasureUnit." + toJAVAName(unitPerUnit.second) + "), MeasureUnit." + toJAVAName(unitPerUnitEntry.getKey()) + ");"); 2278 } 2279 System.out.println(" }"); 2280 } 2281 2282 private static String getVersion(String javaName, String thisVersion) { 2283 String version = JAVA_VERSION_MAP.get(javaName); 2284 if (version == null) { 2285 return thisVersion; 2286 } 2287 return version; 2288 } 2289 2290 private static boolean isDraft(String javaName) { 2291 String version = JAVA_VERSION_MAP.get(javaName); 2292 if (version == null) { 2293 return true; 2294 } 2295 return DRAFT_VERSION_SET.contains(version); 2296 } 2297 2298 public <T extends Serializable> void checkStreamingEquality(T item) { 2299 try { 2300 ByteArrayOutputStream byteOut = new ByteArrayOutputStream(); 2301 ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteOut); 2302 objectOutputStream.writeObject(item); 2303 objectOutputStream.close(); 2304 byte[] contents = byteOut.toByteArray(); 2305 logln("bytes: " + contents.length + "; " + item.getClass() + ": " + showBytes(contents)); 2306 ByteArrayInputStream byteIn = new ByteArrayInputStream(contents); 2307 ObjectInputStream objectInputStream = new ObjectInputStream(byteIn); 2308 Object obj = objectInputStream.readObject(); 2309 assertEquals("Streamed Object equals ", item, obj); 2310 } catch (IOException e) { 2311 e.printStackTrace(); 2312 assertNull("Test Serialization " + item.getClass(), e); 2313 } catch (ClassNotFoundException e) { 2314 assertNull("Test Serialization " + item.getClass(), e); 2315 } 2316 } 2317 2318 /** 2319 * @param contents 2320 * @return 2321 */ 2322 private String showBytes(byte[] contents) { 2323 StringBuilder b = new StringBuilder('['); 2324 for (int i = 0; i < contents.length; ++i) { 2325 int item = contents[i] & 0xFF; 2326 if (item >= 0x20 && item <= 0x7F) { 2327 b.append((char) item); 2328 } else { 2329 b.append('(').append(Utility.hex(item, 2)).append(')'); 2330 } 2331 } 2332 return b.append(']').toString(); 2333 } 2334 2335 private void verifyEqualsHashCode(Object o, Object eq, Object ne) { 2336 assertEquals("verifyEqualsHashCodeSame", o, o); 2337 assertEquals("verifyEqualsHashCodeEq", o, eq); 2338 assertNotEquals("verifyEqualsHashCodeNe", o, ne); 2339 assertNotEquals("verifyEqualsHashCodeEqTrans", eq, ne); 2340 assertEquals("verifyEqualsHashCodeHashEq", o.hashCode(), eq.hashCode()); 2341 2342 // May be a flaky test, but generally should be true. 2343 // May need to comment this out later. 2344 assertNotEquals("verifyEqualsHashCodeHashNe", o.hashCode(), ne.hashCode()); 2345 } 2346 2347 public static class MeasureUnitHandler implements SerializableTestUtility.Handler 2348 { 2349 @Override 2350 public Object[] getTestObjects() 2351 { 2352 MeasureUnit items[] = { 2353 MeasureUnit.CELSIUS, 2354 Currency.getInstance("EUR") 2355 }; 2356 return items; 2357 } 2358 @Override 2359 public boolean hasSameBehavior(Object a, Object b) 2360 { 2361 MeasureUnit a1 = (MeasureUnit) a; 2362 MeasureUnit b1 = (MeasureUnit) b; 2363 return a1.getType().equals(b1.getType()) 2364 && a1.getSubtype().equals(b1.getSubtype()); 2365 } 2366 } 2367 2368 public static class MeasureFormatHandler implements SerializableTestUtility.Handler 2369 { 2370 @Override 2371 public Object[] getTestObjects() 2372 { 2373 MeasureFormat items[] = { 2374 MeasureFormat.getInstance(ULocale.FRANCE, FormatWidth.SHORT), 2375 MeasureFormat.getInstance( 2376 ULocale.FRANCE, 2377 FormatWidth.WIDE, 2378 NumberFormat.getIntegerInstance(ULocale.CANADA_FRENCH)), 2379 }; 2380 return items; 2381 } 2382 @Override 2383 public boolean hasSameBehavior(Object a, Object b) 2384 { 2385 MeasureFormat a1 = (MeasureFormat) a; 2386 MeasureFormat b1 = (MeasureFormat) b; 2387 return a1.getLocale().equals(b1.getLocale()) 2388 && a1.getWidth().equals(b1.getWidth()) 2389 && a1.getNumberFormat().equals(b1.getNumberFormat()) 2390 ; 2391 } 2392 } 2393} 2394