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