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