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