• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // © 2016 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html
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.text.ParseException;
20 import java.util.ArrayList;
21 import java.util.Arrays;
22 import java.util.Collection;
23 import java.util.Collections;
24 import java.util.Comparator;
25 import java.util.HashMap;
26 import java.util.HashSet;
27 import java.util.List;
28 import java.util.Locale;
29 import java.util.Map;
30 import java.util.Set;
31 import java.util.TreeMap;
32 
33 import org.junit.Assert;
34 import org.junit.Test;
35 import org.junit.runner.RunWith;
36 import org.junit.runners.JUnit4;
37 
38 import com.ibm.icu.dev.test.TestFmwk;
39 import com.ibm.icu.dev.test.serializable.FormatHandler;
40 import com.ibm.icu.dev.test.serializable.SerializableTestUtility;
41 import com.ibm.icu.impl.Pair;
42 import com.ibm.icu.impl.Utility;
43 import com.ibm.icu.impl.units.MeasureUnitImpl;
44 import com.ibm.icu.math.BigDecimal;
45 import com.ibm.icu.text.MeasureFormat;
46 import com.ibm.icu.text.MeasureFormat.FormatWidth;
47 import com.ibm.icu.text.NumberFormat;
48 import com.ibm.icu.util.Currency;
49 import com.ibm.icu.util.CurrencyAmount;
50 import com.ibm.icu.util.Measure;
51 import com.ibm.icu.util.MeasureUnit;
52 import com.ibm.icu.util.NoUnit;
53 import com.ibm.icu.util.TimeUnit;
54 import com.ibm.icu.util.TimeUnitAmount;
55 import com.ibm.icu.util.ULocale;
56 
57 /**
58  * See https://sites.google.com/site/icusite/processes/release/tasks/standards?pli=1
59  * for information on how to update with each new release.
60  * @author markdavis
61  */
62 @RunWith(JUnit4.class)
63 public class MeasureUnitTest extends TestFmwk {
64 
65     static class OrderedPair<F extends Comparable, S extends Comparable> extends Pair<F, S> implements Comparable<OrderedPair<F, S>> {
66 
OrderedPair(F first, S second)67         OrderedPair(F first, S second) {
68             super(first, second);
69         }
70 
of(F first, S second)71         public static <F extends Comparable, S extends Comparable> OrderedPair<F, S> of(F first, S second) {
72             if (first == null || second == null) {
73                 throw new IllegalArgumentException("OrderedPair.of requires non null values.");
74             }
75             return new OrderedPair<>(first, second);
76         }
77 
78         @Override
compareTo(OrderedPair<F, S> other)79         public int compareTo(OrderedPair<F, S> other) {
80             int result = first.compareTo(other.first);
81             if (result != 0) {
82                 return result;
83             }
84             return second.compareTo(other.second);
85         }
86     }
87 
88     private static final String[] DRAFT_VERSIONS = {"68", "69"};
89 
90     private static final HashSet<String> DRAFT_VERSION_SET = new HashSet<>();
91 
92     private static final HashSet<String> TIME_CODES = new HashSet<>();
93 
94     private static final String[][] JAVA_VERSIONS = {
95         {"G_FORCE", "53"},
96         {"DEGREE", "53"},
97         {"ARC_MINUTE", "53"},
98         {"ARC_SECOND", "53"},
99         {"ACRE", "53"},
100         {"HECTARE", "53"},
101         {"SQUARE_FOOT", "53"},
102         {"SQUARE_KILOMETER", "53"},
103         {"SQUARE_METER", "53"},
104         {"SQUARE_MILE", "53"},
105         {"MILLISECOND", "53"},
106         {"CENTIMETER", "53"},
107         {"FOOT", "53"},
108         {"INCH", "53"},
109         {"KILOMETER", "53"},
110         {"LIGHT_YEAR", "53"},
111         {"METER", "53"},
112         {"MILE", "53"},
113         {"MILLIMETER", "53"},
114         {"PICOMETER", "53"},
115         {"YARD", "53"},
116         {"GRAM", "53"},
117         {"KILOGRAM", "53"},
118         {"OUNCE", "53"},
119         {"POUND", "53"},
120         {"HORSEPOWER", "53"},
121         {"KILOWATT", "53"},
122         {"WATT", "53"},
123         {"HECTOPASCAL", "53"},
124         {"INCH_HG", "53"},
125         {"MILLIBAR", "53"},
126         {"KILOMETER_PER_HOUR", "53"},
127         {"METER_PER_SECOND", "53"},
128         {"MILE_PER_HOUR", "53"},
129         {"CELSIUS", "53"},
130         {"FAHRENHEIT", "53"},
131         {"CUBIC_KILOMETER", "53"},
132         {"CUBIC_MILE", "53"},
133         {"LITER", "53"},
134         {"YEAR", "53"},
135         {"MONTH", "53"},
136         {"WEEK", "53"},
137         {"DAY", "53"},
138         {"HOUR", "53"},
139         {"MINUTE", "53"},
140         {"SECOND", "53"},
141         {"METER_PER_SECOND_SQUARED", "54"},
142         {"RADIAN", "54"},
143         {"SQUARE_CENTIMETER", "54"},
144         {"SQUARE_INCH", "54"},
145         {"SQUARE_YARD", "54"},
146         {"LITER_PER_KILOMETER", "54"},
147         {"MILE_PER_GALLON", "54"},
148         {"BIT", "54"},
149         {"BYTE", "54"},
150         {"GIGABIT", "54"},
151         {"GIGABYTE", "54"},
152         {"KILOBIT", "54"},
153         {"KILOBYTE", "54"},
154         {"MEGABIT", "54"},
155         {"MEGABYTE", "54"},
156         {"TERABIT", "54"},
157         {"TERABYTE", "54"},
158         {"MICROSECOND", "54"},
159         {"NANOSECOND", "54"},
160         {"AMPERE", "54"},
161         {"MILLIAMPERE", "54"},
162         {"OHM", "54"},
163         {"VOLT", "54"},
164         {"CALORIE", "54"},
165         {"FOODCALORIE", "54"},
166         {"JOULE", "54"},
167         {"KILOCALORIE", "54"},
168         {"KILOJOULE", "54"},
169         {"KILOWATT_HOUR", "54"},
170         {"GIGAHERTZ", "54"},
171         {"HERTZ", "54"},
172         {"KILOHERTZ", "54"},
173         {"MEGAHERTZ", "54"},
174         {"ASTRONOMICAL_UNIT", "54"},
175         {"DECIMETER", "54"},
176         {"FATHOM", "54"},
177         {"FURLONG", "54"},
178         {"MICROMETER", "54"},
179         {"NANOMETER", "54"},
180         {"NAUTICAL_MILE", "54"},
181         {"PARSEC", "54"},
182         {"LUX", "54"},
183         {"CARAT", "54"},
184         {"METRIC_TON", "54"},
185         {"MICROGRAM", "54"},
186         {"MILLIGRAM", "54"},
187         {"OUNCE_TROY", "54"},
188         {"STONE", "54"},
189         {"TON", "54"},
190         {"GIGAWATT", "54"},
191         {"MEGAWATT", "54"},
192         {"MILLIWATT", "54"},
193         {"MILLIMETER_OF_MERCURY", "54"},
194         {"POUND_PER_SQUARE_INCH", "54"},
195         {"KARAT", "54"},
196         {"KELVIN", "54"},
197         {"ACRE_FOOT", "54"},
198         {"BUSHEL", "54"},
199         {"CENTILITER", "54"},
200         {"CUBIC_CENTIMETER", "54"},
201         {"CUBIC_FOOT", "54"},
202         {"CUBIC_INCH", "54"},
203         {"CUBIC_METER", "54"},
204         {"CUBIC_YARD", "54"},
205         {"CUP", "54"},
206         {"DECILITER", "54"},
207         {"FLUID_OUNCE", "54"},
208         {"GALLON", "54"},
209         {"HECTOLITER", "54"},
210         {"MEGALITER", "54"},
211         {"MILLILITER", "54"},
212         {"PINT", "54"},
213         {"QUART", "54"},
214         {"TABLESPOON", "54"},
215         {"TEASPOON", "54"},
216         {"GENERIC_TEMPERATURE", "56"},
217         {"REVOLUTION_ANGLE", "56"},
218         {"LITER_PER_100KILOMETERS", "56"},
219         {"CENTURY", "56"},
220         {"MILE_SCANDINAVIAN", "56"},
221         {"KNOT", "56"},
222         {"CUP_METRIC", "56"},
223         {"PINT_METRIC", "56"},
224         {"MILLIGRAM_PER_DECILITER", "57"},
225         {"MILLIMOLE_PER_LITER", "57"},
226         {"PART_PER_MILLION", "57"},
227         {"MILE_PER_GALLON_IMPERIAL", "57"},
228         {"GALLON_IMPERIAL", "57"},
229         {"POINT", "59"},
230         {"PERCENT", "63"},
231         {"PERMILLE", "63"},
232         {"PETABYTE", "63"},
233         {"ATMOSPHERE", "63"},
234         {"DUNAM", "64"},
235         {"MOLE", "64"},
236         {"PERMYRIAD", "64"},
237         {"DAY_PERSON", "64"},
238         {"MONTH_PERSON", "64"},
239         {"WEEK_PERSON", "64"},
240         {"YEAR_PERSON", "64"},
241         {"BRITISH_THERMAL_UNIT", "64"},
242         {"ELECTRONVOLT", "64"},
243         {"NEWTON", "64"},
244         {"POUND_FORCE", "64"},
245         {"SOLAR_RADIUS", "64"},
246         {"SOLAR_LUMINOSITY", "64"},
247         {"DALTON", "64"},
248         {"EARTH_MASS", "64"},
249         {"SOLAR_MASS", "64"},
250         {"KILOPASCAL", "64"},
251         {"MEGAPASCAL", "64"},
252         {"NEWTON_METER", "64"},
253         {"POUND_FOOT", "64"},
254         {"BARREL", "64"},
255         {"FLUID_OUNCE_IMPERIAL", "64"},
256         {"DECADE", "65"},
257         {"THERM_US", "65"},
258         {"DOT_PER_CENTIMETER", "65"},
259         {"DOT_PER_INCH", "65"},
260         {"EM", "65"},
261         {"MEGAPIXEL", "65"},
262         {"PIXEL", "65"},
263         {"PIXEL_PER_CENTIMETER", "65"},
264         {"PIXEL_PER_INCH", "65"},
265         {"BAR", "65"},
266         {"PASCAL", "65"},
267         {"DOT", "68"},
268         {"EARTH_RADIUS", "68"},
269         {"CANDELA", "68"},
270         {"LUMEN", "68"},
271         {"GRAIN", "68"},
272         {"DESSERT_SPOON", "68"},
273         {"DESSERT_SPOON_IMPERIAL", "68"},
274         {"DRAM", "68"},
275         {"DROP", "68"},
276         {"JIGGER", "68"},
277         {"PINCH", "68"},
278         {"QUART_IMPERIAL", "68"},
279         {"MILLIGRAM_OFGLUCOSE_PER_DECILITER", "69"},
280     };
281 
282     private static final HashMap<String, String> JAVA_VERSION_MAP = new HashMap<>();
283 
284     // modify certain CLDR unit names before generating functions
285     // that create/get the corresponding MeasureUnit objects
286     private static final Map<String,String> CLDR_NAME_REMAP = new HashMap();
287 
288     static {
289         TIME_CODES.add("year");
290         TIME_CODES.add("month");
291         TIME_CODES.add("week");
292         TIME_CODES.add("day");
293         TIME_CODES.add("hour");
294         TIME_CODES.add("minute");
295         TIME_CODES.add("second");
296         for (String verNum : DRAFT_VERSIONS) {
297             DRAFT_VERSION_SET.add(verNum);
298         }
299         for (String[] funcNameAndVersion : JAVA_VERSIONS) {
JAVA_VERSION_MAP.put(funcNameAndVersion[0], funcNameAndVersion[1])300             JAVA_VERSION_MAP.put(funcNameAndVersion[0], funcNameAndVersion[1]);
301         }
302 
303         // CLDR_NAME_REMAP entries
304         // The first two fix overly-generic CLDR unit names
305         CLDR_NAME_REMAP.put("revolution", "revolution-angle");
306         CLDR_NAME_REMAP.put("generic",    "generic-temperature");
307         // The next seven map updated CLDR 37 names back to their
308         // old form in order to preserve the old function names
309         CLDR_NAME_REMAP.put("meter-per-square-second",     "meter-per-second-squared");
310         CLDR_NAME_REMAP.put("permillion",                  "part-per-million");
311         CLDR_NAME_REMAP.put("liter-per-100-kilometer",     "liter-per-100kilometers");
312         CLDR_NAME_REMAP.put("inch-ofhg",                   "inch-hg");
313         CLDR_NAME_REMAP.put("millimeter-ofhg",             "millimeter-of-mercury");
314         CLDR_NAME_REMAP.put("pound-force-per-square-inch", "pound-per-square-inch");
315         CLDR_NAME_REMAP.put("pound-force-foot",            "pound-foot");
316     }
317 
318     @Test
testZZZ()319     public void testZZZ() {
320         // various generateXXX calls go here, see
321         // docs/processes/release/tasks/updating-measure-unit.md
322         // use this test to run each of the ollowing in succession
323         //generateConstants("69"); // for MeasureUnit.java, update generated MeasureUnit constants
324         //generateBackwardCompatibilityTest("69"); // for MeasureUnitTest.java, create TestCompatible69
325         //generateCXXHConstants("69"); // for measunit.h, update generated createXXX methods
326         //generateCXXConstants(); // for measunit.cpp, update generated code
327         //generateCXXBackwardCompatibilityTest("69"); // for measfmttest.cpp, create TestCompatible69
328         //updateJAVAVersions("69"); // for MeasureUnitTest.java, JAVA_VERSIONS
329     }
330 
331     @Test
TestCompatible53()332     public void TestCompatible53() {
333         MeasureUnit[] units = {
334                 MeasureUnit.G_FORCE,
335                 MeasureUnit.DEGREE,
336                 MeasureUnit.ARC_MINUTE,
337                 MeasureUnit.ARC_SECOND,
338                 MeasureUnit.ACRE,
339                 MeasureUnit.HECTARE,
340                 MeasureUnit.SQUARE_FOOT,
341                 MeasureUnit.SQUARE_KILOMETER,
342                 MeasureUnit.SQUARE_METER,
343                 MeasureUnit.SQUARE_MILE,
344                 MeasureUnit.MILLISECOND,
345                 MeasureUnit.CENTIMETER,
346                 MeasureUnit.FOOT,
347                 MeasureUnit.INCH,
348                 MeasureUnit.KILOMETER,
349                 MeasureUnit.LIGHT_YEAR,
350                 MeasureUnit.METER,
351                 MeasureUnit.MILE,
352                 MeasureUnit.MILLIMETER,
353                 MeasureUnit.PICOMETER,
354                 MeasureUnit.YARD,
355                 MeasureUnit.GRAM,
356                 MeasureUnit.KILOGRAM,
357                 MeasureUnit.OUNCE,
358                 MeasureUnit.POUND,
359                 MeasureUnit.HORSEPOWER,
360                 MeasureUnit.KILOWATT,
361                 MeasureUnit.WATT,
362                 MeasureUnit.HECTOPASCAL,
363                 MeasureUnit.INCH_HG,
364                 MeasureUnit.MILLIBAR,
365                 MeasureUnit.KILOMETER_PER_HOUR,
366                 MeasureUnit.METER_PER_SECOND,
367                 MeasureUnit.MILE_PER_HOUR,
368                 MeasureUnit.CELSIUS,
369                 MeasureUnit.FAHRENHEIT,
370                 MeasureUnit.CUBIC_KILOMETER,
371                 MeasureUnit.CUBIC_MILE,
372                 MeasureUnit.LITER,
373                 MeasureUnit.YEAR,
374                 MeasureUnit.MONTH,
375                 MeasureUnit.WEEK,
376                 MeasureUnit.DAY,
377                 MeasureUnit.HOUR,
378                 MeasureUnit.MINUTE,
379                 MeasureUnit.SECOND,
380         };
381         assertEquals("", 46, units.length);
382     }
383 
384     @Test
TestCompatible54()385     public void TestCompatible54() {
386         MeasureUnit[] units = {
387                 MeasureUnit.G_FORCE,
388                 MeasureUnit.METER_PER_SECOND_SQUARED,
389                 MeasureUnit.ARC_MINUTE,
390                 MeasureUnit.ARC_SECOND,
391                 MeasureUnit.DEGREE,
392                 MeasureUnit.RADIAN,
393                 MeasureUnit.ACRE,
394                 MeasureUnit.HECTARE,
395                 MeasureUnit.SQUARE_CENTIMETER,
396                 MeasureUnit.SQUARE_FOOT,
397                 MeasureUnit.SQUARE_INCH,
398                 MeasureUnit.SQUARE_KILOMETER,
399                 MeasureUnit.SQUARE_METER,
400                 MeasureUnit.SQUARE_MILE,
401                 MeasureUnit.SQUARE_YARD,
402                 MeasureUnit.LITER_PER_KILOMETER,
403                 MeasureUnit.MILE_PER_GALLON,
404                 MeasureUnit.BIT,
405                 MeasureUnit.BYTE,
406                 MeasureUnit.GIGABIT,
407                 MeasureUnit.GIGABYTE,
408                 MeasureUnit.KILOBIT,
409                 MeasureUnit.KILOBYTE,
410                 MeasureUnit.MEGABIT,
411                 MeasureUnit.MEGABYTE,
412                 MeasureUnit.TERABIT,
413                 MeasureUnit.TERABYTE,
414                 MeasureUnit.DAY,
415                 MeasureUnit.HOUR,
416                 MeasureUnit.MICROSECOND,
417                 MeasureUnit.MILLISECOND,
418                 MeasureUnit.MINUTE,
419                 MeasureUnit.MONTH,
420                 MeasureUnit.NANOSECOND,
421                 MeasureUnit.SECOND,
422                 MeasureUnit.WEEK,
423                 MeasureUnit.YEAR,
424                 MeasureUnit.AMPERE,
425                 MeasureUnit.MILLIAMPERE,
426                 MeasureUnit.OHM,
427                 MeasureUnit.VOLT,
428                 MeasureUnit.CALORIE,
429                 MeasureUnit.FOODCALORIE,
430                 MeasureUnit.JOULE,
431                 MeasureUnit.KILOCALORIE,
432                 MeasureUnit.KILOJOULE,
433                 MeasureUnit.KILOWATT_HOUR,
434                 MeasureUnit.GIGAHERTZ,
435                 MeasureUnit.HERTZ,
436                 MeasureUnit.KILOHERTZ,
437                 MeasureUnit.MEGAHERTZ,
438                 MeasureUnit.ASTRONOMICAL_UNIT,
439                 MeasureUnit.CENTIMETER,
440                 MeasureUnit.DECIMETER,
441                 MeasureUnit.FATHOM,
442                 MeasureUnit.FOOT,
443                 MeasureUnit.FURLONG,
444                 MeasureUnit.INCH,
445                 MeasureUnit.KILOMETER,
446                 MeasureUnit.LIGHT_YEAR,
447                 MeasureUnit.METER,
448                 MeasureUnit.MICROMETER,
449                 MeasureUnit.MILE,
450                 MeasureUnit.MILLIMETER,
451                 MeasureUnit.NANOMETER,
452                 MeasureUnit.NAUTICAL_MILE,
453                 MeasureUnit.PARSEC,
454                 MeasureUnit.PICOMETER,
455                 MeasureUnit.YARD,
456                 MeasureUnit.LUX,
457                 MeasureUnit.CARAT,
458                 MeasureUnit.GRAM,
459                 MeasureUnit.KILOGRAM,
460                 MeasureUnit.METRIC_TON,
461                 MeasureUnit.MICROGRAM,
462                 MeasureUnit.MILLIGRAM,
463                 MeasureUnit.OUNCE,
464                 MeasureUnit.OUNCE_TROY,
465                 MeasureUnit.POUND,
466                 MeasureUnit.STONE,
467                 MeasureUnit.TON,
468                 MeasureUnit.GIGAWATT,
469                 MeasureUnit.HORSEPOWER,
470                 MeasureUnit.KILOWATT,
471                 MeasureUnit.MEGAWATT,
472                 MeasureUnit.MILLIWATT,
473                 MeasureUnit.WATT,
474                 MeasureUnit.HECTOPASCAL,
475                 MeasureUnit.INCH_HG,
476                 MeasureUnit.MILLIBAR,
477                 MeasureUnit.MILLIMETER_OF_MERCURY,
478                 MeasureUnit.POUND_PER_SQUARE_INCH,
479                 MeasureUnit.KARAT,
480                 MeasureUnit.KILOMETER_PER_HOUR,
481                 MeasureUnit.METER_PER_SECOND,
482                 MeasureUnit.MILE_PER_HOUR,
483                 MeasureUnit.CELSIUS,
484                 MeasureUnit.FAHRENHEIT,
485                 MeasureUnit.KELVIN,
486                 MeasureUnit.ACRE_FOOT,
487                 MeasureUnit.BUSHEL,
488                 MeasureUnit.CENTILITER,
489                 MeasureUnit.CUBIC_CENTIMETER,
490                 MeasureUnit.CUBIC_FOOT,
491                 MeasureUnit.CUBIC_INCH,
492                 MeasureUnit.CUBIC_KILOMETER,
493                 MeasureUnit.CUBIC_METER,
494                 MeasureUnit.CUBIC_MILE,
495                 MeasureUnit.CUBIC_YARD,
496                 MeasureUnit.CUP,
497                 MeasureUnit.DECILITER,
498                 MeasureUnit.FLUID_OUNCE,
499                 MeasureUnit.GALLON,
500                 MeasureUnit.HECTOLITER,
501                 MeasureUnit.LITER,
502                 MeasureUnit.MEGALITER,
503                 MeasureUnit.MILLILITER,
504                 MeasureUnit.PINT,
505                 MeasureUnit.QUART,
506                 MeasureUnit.TABLESPOON,
507                 MeasureUnit.TEASPOON,
508         };
509         assertEquals("",  121, units.length);
510     }
511 
512     @Test
TestCompatible55()513     public void TestCompatible55() {
514         MeasureUnit[] units = {
515                 MeasureUnit.G_FORCE,
516                 MeasureUnit.METER_PER_SECOND_SQUARED,
517                 MeasureUnit.ARC_MINUTE,
518                 MeasureUnit.ARC_SECOND,
519                 MeasureUnit.DEGREE,
520                 MeasureUnit.RADIAN,
521                 MeasureUnit.ACRE,
522                 MeasureUnit.HECTARE,
523                 MeasureUnit.SQUARE_CENTIMETER,
524                 MeasureUnit.SQUARE_FOOT,
525                 MeasureUnit.SQUARE_INCH,
526                 MeasureUnit.SQUARE_KILOMETER,
527                 MeasureUnit.SQUARE_METER,
528                 MeasureUnit.SQUARE_MILE,
529                 MeasureUnit.SQUARE_YARD,
530                 MeasureUnit.LITER_PER_KILOMETER,
531                 MeasureUnit.MILE_PER_GALLON,
532                 MeasureUnit.BIT,
533                 MeasureUnit.BYTE,
534                 MeasureUnit.GIGABIT,
535                 MeasureUnit.GIGABYTE,
536                 MeasureUnit.KILOBIT,
537                 MeasureUnit.KILOBYTE,
538                 MeasureUnit.MEGABIT,
539                 MeasureUnit.MEGABYTE,
540                 MeasureUnit.TERABIT,
541                 MeasureUnit.TERABYTE,
542                 MeasureUnit.DAY,
543                 MeasureUnit.HOUR,
544                 MeasureUnit.MICROSECOND,
545                 MeasureUnit.MILLISECOND,
546                 MeasureUnit.MINUTE,
547                 MeasureUnit.MONTH,
548                 MeasureUnit.NANOSECOND,
549                 MeasureUnit.SECOND,
550                 MeasureUnit.WEEK,
551                 MeasureUnit.YEAR,
552                 MeasureUnit.AMPERE,
553                 MeasureUnit.MILLIAMPERE,
554                 MeasureUnit.OHM,
555                 MeasureUnit.VOLT,
556                 MeasureUnit.CALORIE,
557                 MeasureUnit.FOODCALORIE,
558                 MeasureUnit.JOULE,
559                 MeasureUnit.KILOCALORIE,
560                 MeasureUnit.KILOJOULE,
561                 MeasureUnit.KILOWATT_HOUR,
562                 MeasureUnit.GIGAHERTZ,
563                 MeasureUnit.HERTZ,
564                 MeasureUnit.KILOHERTZ,
565                 MeasureUnit.MEGAHERTZ,
566                 MeasureUnit.ASTRONOMICAL_UNIT,
567                 MeasureUnit.CENTIMETER,
568                 MeasureUnit.DECIMETER,
569                 MeasureUnit.FATHOM,
570                 MeasureUnit.FOOT,
571                 MeasureUnit.FURLONG,
572                 MeasureUnit.INCH,
573                 MeasureUnit.KILOMETER,
574                 MeasureUnit.LIGHT_YEAR,
575                 MeasureUnit.METER,
576                 MeasureUnit.MICROMETER,
577                 MeasureUnit.MILE,
578                 MeasureUnit.MILLIMETER,
579                 MeasureUnit.NANOMETER,
580                 MeasureUnit.NAUTICAL_MILE,
581                 MeasureUnit.PARSEC,
582                 MeasureUnit.PICOMETER,
583                 MeasureUnit.YARD,
584                 MeasureUnit.LUX,
585                 MeasureUnit.CARAT,
586                 MeasureUnit.GRAM,
587                 MeasureUnit.KILOGRAM,
588                 MeasureUnit.METRIC_TON,
589                 MeasureUnit.MICROGRAM,
590                 MeasureUnit.MILLIGRAM,
591                 MeasureUnit.OUNCE,
592                 MeasureUnit.OUNCE_TROY,
593                 MeasureUnit.POUND,
594                 MeasureUnit.STONE,
595                 MeasureUnit.TON,
596                 MeasureUnit.GIGAWATT,
597                 MeasureUnit.HORSEPOWER,
598                 MeasureUnit.KILOWATT,
599                 MeasureUnit.MEGAWATT,
600                 MeasureUnit.MILLIWATT,
601                 MeasureUnit.WATT,
602                 MeasureUnit.HECTOPASCAL,
603                 MeasureUnit.INCH_HG,
604                 MeasureUnit.MILLIBAR,
605                 MeasureUnit.MILLIMETER_OF_MERCURY,
606                 MeasureUnit.POUND_PER_SQUARE_INCH,
607                 MeasureUnit.KARAT,
608                 MeasureUnit.KILOMETER_PER_HOUR,
609                 MeasureUnit.METER_PER_SECOND,
610                 MeasureUnit.MILE_PER_HOUR,
611                 MeasureUnit.CELSIUS,
612                 MeasureUnit.FAHRENHEIT,
613                 MeasureUnit.GENERIC_TEMPERATURE,
614                 MeasureUnit.KELVIN,
615                 MeasureUnit.ACRE_FOOT,
616                 MeasureUnit.BUSHEL,
617                 MeasureUnit.CENTILITER,
618                 MeasureUnit.CUBIC_CENTIMETER,
619                 MeasureUnit.CUBIC_FOOT,
620                 MeasureUnit.CUBIC_INCH,
621                 MeasureUnit.CUBIC_KILOMETER,
622                 MeasureUnit.CUBIC_METER,
623                 MeasureUnit.CUBIC_MILE,
624                 MeasureUnit.CUBIC_YARD,
625                 MeasureUnit.CUP,
626                 MeasureUnit.DECILITER,
627                 MeasureUnit.FLUID_OUNCE,
628                 MeasureUnit.GALLON,
629                 MeasureUnit.HECTOLITER,
630                 MeasureUnit.LITER,
631                 MeasureUnit.MEGALITER,
632                 MeasureUnit.MILLILITER,
633                 MeasureUnit.PINT,
634                 MeasureUnit.QUART,
635                 MeasureUnit.TABLESPOON,
636                 MeasureUnit.TEASPOON,
637         };
638         assertEquals("",  122, units.length);
639     }
640 
641     @Test
TestCompatible56()642     public void TestCompatible56() {
643         MeasureUnit[] units = {
644                 MeasureUnit.G_FORCE,
645                 MeasureUnit.METER_PER_SECOND_SQUARED,
646                 MeasureUnit.ARC_MINUTE,
647                 MeasureUnit.ARC_SECOND,
648                 MeasureUnit.DEGREE,
649                 MeasureUnit.RADIAN,
650                 MeasureUnit.REVOLUTION_ANGLE,
651                 MeasureUnit.ACRE,
652                 MeasureUnit.HECTARE,
653                 MeasureUnit.SQUARE_CENTIMETER,
654                 MeasureUnit.SQUARE_FOOT,
655                 MeasureUnit.SQUARE_INCH,
656                 MeasureUnit.SQUARE_KILOMETER,
657                 MeasureUnit.SQUARE_METER,
658                 MeasureUnit.SQUARE_MILE,
659                 MeasureUnit.SQUARE_YARD,
660                 MeasureUnit.LITER_PER_100KILOMETERS,
661                 MeasureUnit.LITER_PER_KILOMETER,
662                 MeasureUnit.MILE_PER_GALLON,
663                 MeasureUnit.BIT,
664                 MeasureUnit.BYTE,
665                 MeasureUnit.GIGABIT,
666                 MeasureUnit.GIGABYTE,
667                 MeasureUnit.KILOBIT,
668                 MeasureUnit.KILOBYTE,
669                 MeasureUnit.MEGABIT,
670                 MeasureUnit.MEGABYTE,
671                 MeasureUnit.TERABIT,
672                 MeasureUnit.TERABYTE,
673                 MeasureUnit.CENTURY,
674                 MeasureUnit.DAY,
675                 MeasureUnit.HOUR,
676                 MeasureUnit.MICROSECOND,
677                 MeasureUnit.MILLISECOND,
678                 MeasureUnit.MINUTE,
679                 MeasureUnit.MONTH,
680                 MeasureUnit.NANOSECOND,
681                 MeasureUnit.SECOND,
682                 MeasureUnit.WEEK,
683                 MeasureUnit.YEAR,
684                 MeasureUnit.AMPERE,
685                 MeasureUnit.MILLIAMPERE,
686                 MeasureUnit.OHM,
687                 MeasureUnit.VOLT,
688                 MeasureUnit.CALORIE,
689                 MeasureUnit.FOODCALORIE,
690                 MeasureUnit.JOULE,
691                 MeasureUnit.KILOCALORIE,
692                 MeasureUnit.KILOJOULE,
693                 MeasureUnit.KILOWATT_HOUR,
694                 MeasureUnit.GIGAHERTZ,
695                 MeasureUnit.HERTZ,
696                 MeasureUnit.KILOHERTZ,
697                 MeasureUnit.MEGAHERTZ,
698                 MeasureUnit.ASTRONOMICAL_UNIT,
699                 MeasureUnit.CENTIMETER,
700                 MeasureUnit.DECIMETER,
701                 MeasureUnit.FATHOM,
702                 MeasureUnit.FOOT,
703                 MeasureUnit.FURLONG,
704                 MeasureUnit.INCH,
705                 MeasureUnit.KILOMETER,
706                 MeasureUnit.LIGHT_YEAR,
707                 MeasureUnit.METER,
708                 MeasureUnit.MICROMETER,
709                 MeasureUnit.MILE,
710                 MeasureUnit.MILE_SCANDINAVIAN,
711                 MeasureUnit.MILLIMETER,
712                 MeasureUnit.NANOMETER,
713                 MeasureUnit.NAUTICAL_MILE,
714                 MeasureUnit.PARSEC,
715                 MeasureUnit.PICOMETER,
716                 MeasureUnit.YARD,
717                 MeasureUnit.LUX,
718                 MeasureUnit.CARAT,
719                 MeasureUnit.GRAM,
720                 MeasureUnit.KILOGRAM,
721                 MeasureUnit.METRIC_TON,
722                 MeasureUnit.MICROGRAM,
723                 MeasureUnit.MILLIGRAM,
724                 MeasureUnit.OUNCE,
725                 MeasureUnit.OUNCE_TROY,
726                 MeasureUnit.POUND,
727                 MeasureUnit.STONE,
728                 MeasureUnit.TON,
729                 MeasureUnit.GIGAWATT,
730                 MeasureUnit.HORSEPOWER,
731                 MeasureUnit.KILOWATT,
732                 MeasureUnit.MEGAWATT,
733                 MeasureUnit.MILLIWATT,
734                 MeasureUnit.WATT,
735                 MeasureUnit.HECTOPASCAL,
736                 MeasureUnit.INCH_HG,
737                 MeasureUnit.MILLIBAR,
738                 MeasureUnit.MILLIMETER_OF_MERCURY,
739                 MeasureUnit.POUND_PER_SQUARE_INCH,
740                 MeasureUnit.KARAT,
741                 MeasureUnit.KILOMETER_PER_HOUR,
742                 MeasureUnit.KNOT,
743                 MeasureUnit.METER_PER_SECOND,
744                 MeasureUnit.MILE_PER_HOUR,
745                 MeasureUnit.CELSIUS,
746                 MeasureUnit.FAHRENHEIT,
747                 MeasureUnit.GENERIC_TEMPERATURE,
748                 MeasureUnit.KELVIN,
749                 MeasureUnit.ACRE_FOOT,
750                 MeasureUnit.BUSHEL,
751                 MeasureUnit.CENTILITER,
752                 MeasureUnit.CUBIC_CENTIMETER,
753                 MeasureUnit.CUBIC_FOOT,
754                 MeasureUnit.CUBIC_INCH,
755                 MeasureUnit.CUBIC_KILOMETER,
756                 MeasureUnit.CUBIC_METER,
757                 MeasureUnit.CUBIC_MILE,
758                 MeasureUnit.CUBIC_YARD,
759                 MeasureUnit.CUP,
760                 MeasureUnit.CUP_METRIC,
761                 MeasureUnit.DECILITER,
762                 MeasureUnit.FLUID_OUNCE,
763                 MeasureUnit.GALLON,
764                 MeasureUnit.HECTOLITER,
765                 MeasureUnit.LITER,
766                 MeasureUnit.MEGALITER,
767                 MeasureUnit.MILLILITER,
768                 MeasureUnit.PINT,
769                 MeasureUnit.PINT_METRIC,
770                 MeasureUnit.QUART,
771                 MeasureUnit.TABLESPOON,
772                 MeasureUnit.TEASPOON,
773         };
774         assertEquals("",  129, units.length);
775     }
776 
777     @Test
TestCompatible57()778     public void TestCompatible57() {
779         MeasureUnit[] units = {
780                 MeasureUnit.G_FORCE,
781                 MeasureUnit.METER_PER_SECOND_SQUARED,
782                 MeasureUnit.ARC_MINUTE,
783                 MeasureUnit.ARC_SECOND,
784                 MeasureUnit.DEGREE,
785                 MeasureUnit.RADIAN,
786                 MeasureUnit.REVOLUTION_ANGLE,
787                 MeasureUnit.ACRE,
788                 MeasureUnit.HECTARE,
789                 MeasureUnit.SQUARE_CENTIMETER,
790                 MeasureUnit.SQUARE_FOOT,
791                 MeasureUnit.SQUARE_INCH,
792                 MeasureUnit.SQUARE_KILOMETER,
793                 MeasureUnit.SQUARE_METER,
794                 MeasureUnit.SQUARE_MILE,
795                 MeasureUnit.SQUARE_YARD,
796                 MeasureUnit.KARAT,
797                 MeasureUnit.MILLIGRAM_PER_DECILITER,
798                 MeasureUnit.MILLIMOLE_PER_LITER,
799                 MeasureUnit.PART_PER_MILLION,
800                 MeasureUnit.LITER_PER_100KILOMETERS,
801                 MeasureUnit.LITER_PER_KILOMETER,
802                 MeasureUnit.MILE_PER_GALLON,
803                 MeasureUnit.MILE_PER_GALLON_IMPERIAL,
804                 MeasureUnit.BIT,
805                 MeasureUnit.BYTE,
806                 MeasureUnit.GIGABIT,
807                 MeasureUnit.GIGABYTE,
808                 MeasureUnit.KILOBIT,
809                 MeasureUnit.KILOBYTE,
810                 MeasureUnit.MEGABIT,
811                 MeasureUnit.MEGABYTE,
812                 MeasureUnit.TERABIT,
813                 MeasureUnit.TERABYTE,
814                 MeasureUnit.CENTURY,
815                 MeasureUnit.DAY,
816                 MeasureUnit.HOUR,
817                 MeasureUnit.MICROSECOND,
818                 MeasureUnit.MILLISECOND,
819                 MeasureUnit.MINUTE,
820                 MeasureUnit.MONTH,
821                 MeasureUnit.NANOSECOND,
822                 MeasureUnit.SECOND,
823                 MeasureUnit.WEEK,
824                 MeasureUnit.YEAR,
825                 MeasureUnit.AMPERE,
826                 MeasureUnit.MILLIAMPERE,
827                 MeasureUnit.OHM,
828                 MeasureUnit.VOLT,
829                 MeasureUnit.CALORIE,
830                 MeasureUnit.FOODCALORIE,
831                 MeasureUnit.JOULE,
832                 MeasureUnit.KILOCALORIE,
833                 MeasureUnit.KILOJOULE,
834                 MeasureUnit.KILOWATT_HOUR,
835                 MeasureUnit.GIGAHERTZ,
836                 MeasureUnit.HERTZ,
837                 MeasureUnit.KILOHERTZ,
838                 MeasureUnit.MEGAHERTZ,
839                 MeasureUnit.ASTRONOMICAL_UNIT,
840                 MeasureUnit.CENTIMETER,
841                 MeasureUnit.DECIMETER,
842                 MeasureUnit.FATHOM,
843                 MeasureUnit.FOOT,
844                 MeasureUnit.FURLONG,
845                 MeasureUnit.INCH,
846                 MeasureUnit.KILOMETER,
847                 MeasureUnit.LIGHT_YEAR,
848                 MeasureUnit.METER,
849                 MeasureUnit.MICROMETER,
850                 MeasureUnit.MILE,
851                 MeasureUnit.MILE_SCANDINAVIAN,
852                 MeasureUnit.MILLIMETER,
853                 MeasureUnit.NANOMETER,
854                 MeasureUnit.NAUTICAL_MILE,
855                 MeasureUnit.PARSEC,
856                 MeasureUnit.PICOMETER,
857                 MeasureUnit.YARD,
858                 MeasureUnit.LUX,
859                 MeasureUnit.CARAT,
860                 MeasureUnit.GRAM,
861                 MeasureUnit.KILOGRAM,
862                 MeasureUnit.METRIC_TON,
863                 MeasureUnit.MICROGRAM,
864                 MeasureUnit.MILLIGRAM,
865                 MeasureUnit.OUNCE,
866                 MeasureUnit.OUNCE_TROY,
867                 MeasureUnit.POUND,
868                 MeasureUnit.STONE,
869                 MeasureUnit.TON,
870                 MeasureUnit.GIGAWATT,
871                 MeasureUnit.HORSEPOWER,
872                 MeasureUnit.KILOWATT,
873                 MeasureUnit.MEGAWATT,
874                 MeasureUnit.MILLIWATT,
875                 MeasureUnit.WATT,
876                 MeasureUnit.HECTOPASCAL,
877                 MeasureUnit.INCH_HG,
878                 MeasureUnit.MILLIBAR,
879                 MeasureUnit.MILLIMETER_OF_MERCURY,
880                 MeasureUnit.POUND_PER_SQUARE_INCH,
881                 MeasureUnit.KILOMETER_PER_HOUR,
882                 MeasureUnit.KNOT,
883                 MeasureUnit.METER_PER_SECOND,
884                 MeasureUnit.MILE_PER_HOUR,
885                 MeasureUnit.CELSIUS,
886                 MeasureUnit.FAHRENHEIT,
887                 MeasureUnit.GENERIC_TEMPERATURE,
888                 MeasureUnit.KELVIN,
889                 MeasureUnit.ACRE_FOOT,
890                 MeasureUnit.BUSHEL,
891                 MeasureUnit.CENTILITER,
892                 MeasureUnit.CUBIC_CENTIMETER,
893                 MeasureUnit.CUBIC_FOOT,
894                 MeasureUnit.CUBIC_INCH,
895                 MeasureUnit.CUBIC_KILOMETER,
896                 MeasureUnit.CUBIC_METER,
897                 MeasureUnit.CUBIC_MILE,
898                 MeasureUnit.CUBIC_YARD,
899                 MeasureUnit.CUP,
900                 MeasureUnit.CUP_METRIC,
901                 MeasureUnit.DECILITER,
902                 MeasureUnit.FLUID_OUNCE,
903                 MeasureUnit.GALLON,
904                 MeasureUnit.GALLON_IMPERIAL,
905                 MeasureUnit.HECTOLITER,
906                 MeasureUnit.LITER,
907                 MeasureUnit.MEGALITER,
908                 MeasureUnit.MILLILITER,
909                 MeasureUnit.PINT,
910                 MeasureUnit.PINT_METRIC,
911                 MeasureUnit.QUART,
912                 MeasureUnit.TABLESPOON,
913                 MeasureUnit.TEASPOON,
914         };
915         assertEquals("",  134, units.length);
916     }
917 
918     @Test
TestCompatible58()919     public void TestCompatible58() {
920         MeasureUnit[] units = {
921                 MeasureUnit.G_FORCE,
922                 MeasureUnit.METER_PER_SECOND_SQUARED,
923                 MeasureUnit.ARC_MINUTE,
924                 MeasureUnit.ARC_SECOND,
925                 MeasureUnit.DEGREE,
926                 MeasureUnit.RADIAN,
927                 MeasureUnit.REVOLUTION_ANGLE,
928                 MeasureUnit.ACRE,
929                 MeasureUnit.HECTARE,
930                 MeasureUnit.SQUARE_CENTIMETER,
931                 MeasureUnit.SQUARE_FOOT,
932                 MeasureUnit.SQUARE_INCH,
933                 MeasureUnit.SQUARE_KILOMETER,
934                 MeasureUnit.SQUARE_METER,
935                 MeasureUnit.SQUARE_MILE,
936                 MeasureUnit.SQUARE_YARD,
937                 MeasureUnit.KARAT,
938                 MeasureUnit.MILLIGRAM_PER_DECILITER,
939                 MeasureUnit.MILLIMOLE_PER_LITER,
940                 MeasureUnit.PART_PER_MILLION,
941                 MeasureUnit.LITER_PER_100KILOMETERS,
942                 MeasureUnit.LITER_PER_KILOMETER,
943                 MeasureUnit.MILE_PER_GALLON,
944                 MeasureUnit.MILE_PER_GALLON_IMPERIAL,
945                 // MeasureUnit.EAST,
946                 // MeasureUnit.NORTH,
947                 // MeasureUnit.SOUTH,
948                 // MeasureUnit.WEST,
949                 MeasureUnit.BIT,
950                 MeasureUnit.BYTE,
951                 MeasureUnit.GIGABIT,
952                 MeasureUnit.GIGABYTE,
953                 MeasureUnit.KILOBIT,
954                 MeasureUnit.KILOBYTE,
955                 MeasureUnit.MEGABIT,
956                 MeasureUnit.MEGABYTE,
957                 MeasureUnit.TERABIT,
958                 MeasureUnit.TERABYTE,
959                 MeasureUnit.CENTURY,
960                 MeasureUnit.DAY,
961                 MeasureUnit.HOUR,
962                 MeasureUnit.MICROSECOND,
963                 MeasureUnit.MILLISECOND,
964                 MeasureUnit.MINUTE,
965                 MeasureUnit.MONTH,
966                 MeasureUnit.NANOSECOND,
967                 MeasureUnit.SECOND,
968                 MeasureUnit.WEEK,
969                 MeasureUnit.YEAR,
970                 MeasureUnit.AMPERE,
971                 MeasureUnit.MILLIAMPERE,
972                 MeasureUnit.OHM,
973                 MeasureUnit.VOLT,
974                 MeasureUnit.CALORIE,
975                 MeasureUnit.FOODCALORIE,
976                 MeasureUnit.JOULE,
977                 MeasureUnit.KILOCALORIE,
978                 MeasureUnit.KILOJOULE,
979                 MeasureUnit.KILOWATT_HOUR,
980                 MeasureUnit.GIGAHERTZ,
981                 MeasureUnit.HERTZ,
982                 MeasureUnit.KILOHERTZ,
983                 MeasureUnit.MEGAHERTZ,
984                 MeasureUnit.ASTRONOMICAL_UNIT,
985                 MeasureUnit.CENTIMETER,
986                 MeasureUnit.DECIMETER,
987                 MeasureUnit.FATHOM,
988                 MeasureUnit.FOOT,
989                 MeasureUnit.FURLONG,
990                 MeasureUnit.INCH,
991                 MeasureUnit.KILOMETER,
992                 MeasureUnit.LIGHT_YEAR,
993                 MeasureUnit.METER,
994                 MeasureUnit.MICROMETER,
995                 MeasureUnit.MILE,
996                 MeasureUnit.MILE_SCANDINAVIAN,
997                 MeasureUnit.MILLIMETER,
998                 MeasureUnit.NANOMETER,
999                 MeasureUnit.NAUTICAL_MILE,
1000                 MeasureUnit.PARSEC,
1001                 MeasureUnit.PICOMETER,
1002                 MeasureUnit.YARD,
1003                 MeasureUnit.LUX,
1004                 MeasureUnit.CARAT,
1005                 MeasureUnit.GRAM,
1006                 MeasureUnit.KILOGRAM,
1007                 MeasureUnit.METRIC_TON,
1008                 MeasureUnit.MICROGRAM,
1009                 MeasureUnit.MILLIGRAM,
1010                 MeasureUnit.OUNCE,
1011                 MeasureUnit.OUNCE_TROY,
1012                 MeasureUnit.POUND,
1013                 MeasureUnit.STONE,
1014                 MeasureUnit.TON,
1015                 MeasureUnit.GIGAWATT,
1016                 MeasureUnit.HORSEPOWER,
1017                 MeasureUnit.KILOWATT,
1018                 MeasureUnit.MEGAWATT,
1019                 MeasureUnit.MILLIWATT,
1020                 MeasureUnit.WATT,
1021                 MeasureUnit.HECTOPASCAL,
1022                 MeasureUnit.INCH_HG,
1023                 MeasureUnit.MILLIBAR,
1024                 MeasureUnit.MILLIMETER_OF_MERCURY,
1025                 MeasureUnit.POUND_PER_SQUARE_INCH,
1026                 MeasureUnit.KILOMETER_PER_HOUR,
1027                 MeasureUnit.KNOT,
1028                 MeasureUnit.METER_PER_SECOND,
1029                 MeasureUnit.MILE_PER_HOUR,
1030                 MeasureUnit.CELSIUS,
1031                 MeasureUnit.FAHRENHEIT,
1032                 MeasureUnit.GENERIC_TEMPERATURE,
1033                 MeasureUnit.KELVIN,
1034                 MeasureUnit.ACRE_FOOT,
1035                 MeasureUnit.BUSHEL,
1036                 MeasureUnit.CENTILITER,
1037                 MeasureUnit.CUBIC_CENTIMETER,
1038                 MeasureUnit.CUBIC_FOOT,
1039                 MeasureUnit.CUBIC_INCH,
1040                 MeasureUnit.CUBIC_KILOMETER,
1041                 MeasureUnit.CUBIC_METER,
1042                 MeasureUnit.CUBIC_MILE,
1043                 MeasureUnit.CUBIC_YARD,
1044                 MeasureUnit.CUP,
1045                 MeasureUnit.CUP_METRIC,
1046                 MeasureUnit.DECILITER,
1047                 MeasureUnit.FLUID_OUNCE,
1048                 MeasureUnit.GALLON,
1049                 MeasureUnit.GALLON_IMPERIAL,
1050                 MeasureUnit.HECTOLITER,
1051                 MeasureUnit.LITER,
1052                 MeasureUnit.MEGALITER,
1053                 MeasureUnit.MILLILITER,
1054                 MeasureUnit.PINT,
1055                 MeasureUnit.PINT_METRIC,
1056                 MeasureUnit.QUART,
1057                 MeasureUnit.TABLESPOON,
1058                 MeasureUnit.TEASPOON,
1059         };
1060         assertEquals("",  134, units.length);
1061     }
1062 
1063     @Test
TestCompatible59()1064     public void TestCompatible59() {
1065         MeasureUnit[] units = {
1066                 MeasureUnit.G_FORCE,
1067                 MeasureUnit.METER_PER_SECOND_SQUARED,
1068                 MeasureUnit.ARC_MINUTE,
1069                 MeasureUnit.ARC_SECOND,
1070                 MeasureUnit.DEGREE,
1071                 MeasureUnit.RADIAN,
1072                 MeasureUnit.REVOLUTION_ANGLE,
1073                 MeasureUnit.ACRE,
1074                 MeasureUnit.HECTARE,
1075                 MeasureUnit.SQUARE_CENTIMETER,
1076                 MeasureUnit.SQUARE_FOOT,
1077                 MeasureUnit.SQUARE_INCH,
1078                 MeasureUnit.SQUARE_KILOMETER,
1079                 MeasureUnit.SQUARE_METER,
1080                 MeasureUnit.SQUARE_MILE,
1081                 MeasureUnit.SQUARE_YARD,
1082                 MeasureUnit.KARAT,
1083                 MeasureUnit.MILLIGRAM_PER_DECILITER,
1084                 MeasureUnit.MILLIMOLE_PER_LITER,
1085                 MeasureUnit.PART_PER_MILLION,
1086                 MeasureUnit.LITER_PER_100KILOMETERS,
1087                 MeasureUnit.LITER_PER_KILOMETER,
1088                 MeasureUnit.MILE_PER_GALLON,
1089                 MeasureUnit.MILE_PER_GALLON_IMPERIAL,
1090                 MeasureUnit.BIT,
1091                 MeasureUnit.BYTE,
1092                 MeasureUnit.GIGABIT,
1093                 MeasureUnit.GIGABYTE,
1094                 MeasureUnit.KILOBIT,
1095                 MeasureUnit.KILOBYTE,
1096                 MeasureUnit.MEGABIT,
1097                 MeasureUnit.MEGABYTE,
1098                 MeasureUnit.TERABIT,
1099                 MeasureUnit.TERABYTE,
1100                 MeasureUnit.CENTURY,
1101                 MeasureUnit.DAY,
1102                 MeasureUnit.HOUR,
1103                 MeasureUnit.MICROSECOND,
1104                 MeasureUnit.MILLISECOND,
1105                 MeasureUnit.MINUTE,
1106                 MeasureUnit.MONTH,
1107                 MeasureUnit.NANOSECOND,
1108                 MeasureUnit.SECOND,
1109                 MeasureUnit.WEEK,
1110                 MeasureUnit.YEAR,
1111                 MeasureUnit.AMPERE,
1112                 MeasureUnit.MILLIAMPERE,
1113                 MeasureUnit.OHM,
1114                 MeasureUnit.VOLT,
1115                 MeasureUnit.CALORIE,
1116                 MeasureUnit.FOODCALORIE,
1117                 MeasureUnit.JOULE,
1118                 MeasureUnit.KILOCALORIE,
1119                 MeasureUnit.KILOJOULE,
1120                 MeasureUnit.KILOWATT_HOUR,
1121                 MeasureUnit.GIGAHERTZ,
1122                 MeasureUnit.HERTZ,
1123                 MeasureUnit.KILOHERTZ,
1124                 MeasureUnit.MEGAHERTZ,
1125                 MeasureUnit.ASTRONOMICAL_UNIT,
1126                 MeasureUnit.CENTIMETER,
1127                 MeasureUnit.DECIMETER,
1128                 MeasureUnit.FATHOM,
1129                 MeasureUnit.FOOT,
1130                 MeasureUnit.FURLONG,
1131                 MeasureUnit.INCH,
1132                 MeasureUnit.KILOMETER,
1133                 MeasureUnit.LIGHT_YEAR,
1134                 MeasureUnit.METER,
1135                 MeasureUnit.MICROMETER,
1136                 MeasureUnit.MILE,
1137                 MeasureUnit.MILE_SCANDINAVIAN,
1138                 MeasureUnit.MILLIMETER,
1139                 MeasureUnit.NANOMETER,
1140                 MeasureUnit.NAUTICAL_MILE,
1141                 MeasureUnit.PARSEC,
1142                 MeasureUnit.PICOMETER,
1143                 MeasureUnit.POINT,
1144                 MeasureUnit.YARD,
1145                 MeasureUnit.LUX,
1146                 MeasureUnit.CARAT,
1147                 MeasureUnit.GRAM,
1148                 MeasureUnit.KILOGRAM,
1149                 MeasureUnit.METRIC_TON,
1150                 MeasureUnit.MICROGRAM,
1151                 MeasureUnit.MILLIGRAM,
1152                 MeasureUnit.OUNCE,
1153                 MeasureUnit.OUNCE_TROY,
1154                 MeasureUnit.POUND,
1155                 MeasureUnit.STONE,
1156                 MeasureUnit.TON,
1157                 MeasureUnit.GIGAWATT,
1158                 MeasureUnit.HORSEPOWER,
1159                 MeasureUnit.KILOWATT,
1160                 MeasureUnit.MEGAWATT,
1161                 MeasureUnit.MILLIWATT,
1162                 MeasureUnit.WATT,
1163                 MeasureUnit.HECTOPASCAL,
1164                 MeasureUnit.INCH_HG,
1165                 MeasureUnit.MILLIBAR,
1166                 MeasureUnit.MILLIMETER_OF_MERCURY,
1167                 MeasureUnit.POUND_PER_SQUARE_INCH,
1168                 MeasureUnit.KILOMETER_PER_HOUR,
1169                 MeasureUnit.KNOT,
1170                 MeasureUnit.METER_PER_SECOND,
1171                 MeasureUnit.MILE_PER_HOUR,
1172                 MeasureUnit.CELSIUS,
1173                 MeasureUnit.FAHRENHEIT,
1174                 MeasureUnit.GENERIC_TEMPERATURE,
1175                 MeasureUnit.KELVIN,
1176                 MeasureUnit.ACRE_FOOT,
1177                 MeasureUnit.BUSHEL,
1178                 MeasureUnit.CENTILITER,
1179                 MeasureUnit.CUBIC_CENTIMETER,
1180                 MeasureUnit.CUBIC_FOOT,
1181                 MeasureUnit.CUBIC_INCH,
1182                 MeasureUnit.CUBIC_KILOMETER,
1183                 MeasureUnit.CUBIC_METER,
1184                 MeasureUnit.CUBIC_MILE,
1185                 MeasureUnit.CUBIC_YARD,
1186                 MeasureUnit.CUP,
1187                 MeasureUnit.CUP_METRIC,
1188                 MeasureUnit.DECILITER,
1189                 MeasureUnit.FLUID_OUNCE,
1190                 MeasureUnit.GALLON,
1191                 MeasureUnit.GALLON_IMPERIAL,
1192                 MeasureUnit.HECTOLITER,
1193                 MeasureUnit.LITER,
1194                 MeasureUnit.MEGALITER,
1195                 MeasureUnit.MILLILITER,
1196                 MeasureUnit.PINT,
1197                 MeasureUnit.PINT_METRIC,
1198                 MeasureUnit.QUART,
1199                 MeasureUnit.TABLESPOON,
1200                 MeasureUnit.TEASPOON,
1201         };
1202         assertEquals("",  135, units.length);
1203     }
1204 
1205     // Note that TestCompatible60(), TestCompatible61(), TestCompatible62()
1206     // would be the same as TestCompatible59(), no need to add them.
1207 
1208     @Test
TestCompatible63()1209     public void TestCompatible63() {
1210         MeasureUnit[] units = {
1211                 MeasureUnit.G_FORCE,
1212                 MeasureUnit.METER_PER_SECOND_SQUARED,
1213                 MeasureUnit.ARC_MINUTE,
1214                 MeasureUnit.ARC_SECOND,
1215                 MeasureUnit.DEGREE,
1216                 MeasureUnit.RADIAN,
1217                 MeasureUnit.REVOLUTION_ANGLE,
1218                 MeasureUnit.ACRE,
1219                 MeasureUnit.HECTARE,
1220                 MeasureUnit.SQUARE_CENTIMETER,
1221                 MeasureUnit.SQUARE_FOOT,
1222                 MeasureUnit.SQUARE_INCH,
1223                 MeasureUnit.SQUARE_KILOMETER,
1224                 MeasureUnit.SQUARE_METER,
1225                 MeasureUnit.SQUARE_MILE,
1226                 MeasureUnit.SQUARE_YARD,
1227                 MeasureUnit.KARAT,
1228                 MeasureUnit.MILLIGRAM_PER_DECILITER,
1229                 MeasureUnit.MILLIMOLE_PER_LITER,
1230                 MeasureUnit.PART_PER_MILLION,
1231                 MeasureUnit.PERCENT,
1232                 MeasureUnit.PERMILLE,
1233                 MeasureUnit.LITER_PER_100KILOMETERS,
1234                 MeasureUnit.LITER_PER_KILOMETER,
1235                 MeasureUnit.MILE_PER_GALLON,
1236                 MeasureUnit.MILE_PER_GALLON_IMPERIAL,
1237                 MeasureUnit.BIT,
1238                 MeasureUnit.BYTE,
1239                 MeasureUnit.GIGABIT,
1240                 MeasureUnit.GIGABYTE,
1241                 MeasureUnit.KILOBIT,
1242                 MeasureUnit.KILOBYTE,
1243                 MeasureUnit.MEGABIT,
1244                 MeasureUnit.MEGABYTE,
1245                 MeasureUnit.PETABYTE,
1246                 MeasureUnit.TERABIT,
1247                 MeasureUnit.TERABYTE,
1248                 MeasureUnit.CENTURY,
1249                 MeasureUnit.DAY,
1250                 MeasureUnit.HOUR,
1251                 MeasureUnit.MICROSECOND,
1252                 MeasureUnit.MILLISECOND,
1253                 MeasureUnit.MINUTE,
1254                 MeasureUnit.MONTH,
1255                 MeasureUnit.NANOSECOND,
1256                 MeasureUnit.SECOND,
1257                 MeasureUnit.WEEK,
1258                 MeasureUnit.YEAR,
1259                 MeasureUnit.AMPERE,
1260                 MeasureUnit.MILLIAMPERE,
1261                 MeasureUnit.OHM,
1262                 MeasureUnit.VOLT,
1263                 MeasureUnit.CALORIE,
1264                 MeasureUnit.FOODCALORIE,
1265                 MeasureUnit.JOULE,
1266                 MeasureUnit.KILOCALORIE,
1267                 MeasureUnit.KILOJOULE,
1268                 MeasureUnit.KILOWATT_HOUR,
1269                 MeasureUnit.GIGAHERTZ,
1270                 MeasureUnit.HERTZ,
1271                 MeasureUnit.KILOHERTZ,
1272                 MeasureUnit.MEGAHERTZ,
1273                 MeasureUnit.ASTRONOMICAL_UNIT,
1274                 MeasureUnit.CENTIMETER,
1275                 MeasureUnit.DECIMETER,
1276                 MeasureUnit.FATHOM,
1277                 MeasureUnit.FOOT,
1278                 MeasureUnit.FURLONG,
1279                 MeasureUnit.INCH,
1280                 MeasureUnit.KILOMETER,
1281                 MeasureUnit.LIGHT_YEAR,
1282                 MeasureUnit.METER,
1283                 MeasureUnit.MICROMETER,
1284                 MeasureUnit.MILE,
1285                 MeasureUnit.MILE_SCANDINAVIAN,
1286                 MeasureUnit.MILLIMETER,
1287                 MeasureUnit.NANOMETER,
1288                 MeasureUnit.NAUTICAL_MILE,
1289                 MeasureUnit.PARSEC,
1290                 MeasureUnit.PICOMETER,
1291                 MeasureUnit.POINT,
1292                 MeasureUnit.YARD,
1293                 MeasureUnit.LUX,
1294                 MeasureUnit.CARAT,
1295                 MeasureUnit.GRAM,
1296                 MeasureUnit.KILOGRAM,
1297                 MeasureUnit.METRIC_TON,
1298                 MeasureUnit.MICROGRAM,
1299                 MeasureUnit.MILLIGRAM,
1300                 MeasureUnit.OUNCE,
1301                 MeasureUnit.OUNCE_TROY,
1302                 MeasureUnit.POUND,
1303                 MeasureUnit.STONE,
1304                 MeasureUnit.TON,
1305                 MeasureUnit.GIGAWATT,
1306                 MeasureUnit.HORSEPOWER,
1307                 MeasureUnit.KILOWATT,
1308                 MeasureUnit.MEGAWATT,
1309                 MeasureUnit.MILLIWATT,
1310                 MeasureUnit.WATT,
1311                 MeasureUnit.ATMOSPHERE,
1312                 MeasureUnit.HECTOPASCAL,
1313                 MeasureUnit.INCH_HG,
1314                 MeasureUnit.MILLIBAR,
1315                 MeasureUnit.MILLIMETER_OF_MERCURY,
1316                 MeasureUnit.POUND_PER_SQUARE_INCH,
1317                 MeasureUnit.KILOMETER_PER_HOUR,
1318                 MeasureUnit.KNOT,
1319                 MeasureUnit.METER_PER_SECOND,
1320                 MeasureUnit.MILE_PER_HOUR,
1321                 MeasureUnit.CELSIUS,
1322                 MeasureUnit.FAHRENHEIT,
1323                 MeasureUnit.GENERIC_TEMPERATURE,
1324                 MeasureUnit.KELVIN,
1325                 MeasureUnit.ACRE_FOOT,
1326                 MeasureUnit.BUSHEL,
1327                 MeasureUnit.CENTILITER,
1328                 MeasureUnit.CUBIC_CENTIMETER,
1329                 MeasureUnit.CUBIC_FOOT,
1330                 MeasureUnit.CUBIC_INCH,
1331                 MeasureUnit.CUBIC_KILOMETER,
1332                 MeasureUnit.CUBIC_METER,
1333                 MeasureUnit.CUBIC_MILE,
1334                 MeasureUnit.CUBIC_YARD,
1335                 MeasureUnit.CUP,
1336                 MeasureUnit.CUP_METRIC,
1337                 MeasureUnit.DECILITER,
1338                 MeasureUnit.FLUID_OUNCE,
1339                 MeasureUnit.GALLON,
1340                 MeasureUnit.GALLON_IMPERIAL,
1341                 MeasureUnit.HECTOLITER,
1342                 MeasureUnit.LITER,
1343                 MeasureUnit.MEGALITER,
1344                 MeasureUnit.MILLILITER,
1345                 MeasureUnit.PINT,
1346                 MeasureUnit.PINT_METRIC,
1347                 MeasureUnit.QUART,
1348                 MeasureUnit.TABLESPOON,
1349                 MeasureUnit.TEASPOON,
1350         };
1351         assertEquals("",  139, units.length);
1352     }
1353 
1354     @Test
TestCompatible64()1355     public void TestCompatible64() {
1356         MeasureUnit[] units = {
1357                 MeasureUnit.G_FORCE,
1358                 MeasureUnit.METER_PER_SECOND_SQUARED,
1359                 MeasureUnit.ARC_MINUTE,
1360                 MeasureUnit.ARC_SECOND,
1361                 MeasureUnit.DEGREE,
1362                 MeasureUnit.RADIAN,
1363                 MeasureUnit.REVOLUTION_ANGLE,
1364                 MeasureUnit.ACRE,
1365                 MeasureUnit.DUNAM,
1366                 MeasureUnit.HECTARE,
1367                 MeasureUnit.SQUARE_CENTIMETER,
1368                 MeasureUnit.SQUARE_FOOT,
1369                 MeasureUnit.SQUARE_INCH,
1370                 MeasureUnit.SQUARE_KILOMETER,
1371                 MeasureUnit.SQUARE_METER,
1372                 MeasureUnit.SQUARE_MILE,
1373                 MeasureUnit.SQUARE_YARD,
1374                 MeasureUnit.KARAT,
1375                 MeasureUnit.MILLIGRAM_PER_DECILITER,
1376                 MeasureUnit.MILLIMOLE_PER_LITER,
1377                 MeasureUnit.MOLE,
1378                 MeasureUnit.PART_PER_MILLION,
1379                 MeasureUnit.PERCENT,
1380                 MeasureUnit.PERMILLE,
1381                 MeasureUnit.PERMYRIAD,
1382                 MeasureUnit.LITER_PER_100KILOMETERS,
1383                 MeasureUnit.LITER_PER_KILOMETER,
1384                 MeasureUnit.MILE_PER_GALLON,
1385                 MeasureUnit.MILE_PER_GALLON_IMPERIAL,
1386                 MeasureUnit.BIT,
1387                 MeasureUnit.BYTE,
1388                 MeasureUnit.GIGABIT,
1389                 MeasureUnit.GIGABYTE,
1390                 MeasureUnit.KILOBIT,
1391                 MeasureUnit.KILOBYTE,
1392                 MeasureUnit.MEGABIT,
1393                 MeasureUnit.MEGABYTE,
1394                 MeasureUnit.PETABYTE,
1395                 MeasureUnit.TERABIT,
1396                 MeasureUnit.TERABYTE,
1397                 MeasureUnit.CENTURY,
1398                 MeasureUnit.DAY,
1399                 MeasureUnit.DAY_PERSON,
1400                 MeasureUnit.HOUR,
1401                 MeasureUnit.MICROSECOND,
1402                 MeasureUnit.MILLISECOND,
1403                 MeasureUnit.MINUTE,
1404                 MeasureUnit.MONTH,
1405                 MeasureUnit.MONTH_PERSON,
1406                 MeasureUnit.NANOSECOND,
1407                 MeasureUnit.SECOND,
1408                 MeasureUnit.WEEK,
1409                 MeasureUnit.WEEK_PERSON,
1410                 MeasureUnit.YEAR,
1411                 MeasureUnit.YEAR_PERSON,
1412                 MeasureUnit.AMPERE,
1413                 MeasureUnit.MILLIAMPERE,
1414                 MeasureUnit.OHM,
1415                 MeasureUnit.VOLT,
1416                 MeasureUnit.BRITISH_THERMAL_UNIT,
1417                 MeasureUnit.CALORIE,
1418                 MeasureUnit.ELECTRONVOLT,
1419                 MeasureUnit.FOODCALORIE,
1420                 MeasureUnit.JOULE,
1421                 MeasureUnit.KILOCALORIE,
1422                 MeasureUnit.KILOJOULE,
1423                 MeasureUnit.KILOWATT_HOUR,
1424                 MeasureUnit.NEWTON,
1425                 MeasureUnit.POUND_FORCE,
1426                 MeasureUnit.GIGAHERTZ,
1427                 MeasureUnit.HERTZ,
1428                 MeasureUnit.KILOHERTZ,
1429                 MeasureUnit.MEGAHERTZ,
1430                 MeasureUnit.ASTRONOMICAL_UNIT,
1431                 MeasureUnit.CENTIMETER,
1432                 MeasureUnit.DECIMETER,
1433                 MeasureUnit.FATHOM,
1434                 MeasureUnit.FOOT,
1435                 MeasureUnit.FURLONG,
1436                 MeasureUnit.INCH,
1437                 MeasureUnit.KILOMETER,
1438                 MeasureUnit.LIGHT_YEAR,
1439                 MeasureUnit.METER,
1440                 MeasureUnit.MICROMETER,
1441                 MeasureUnit.MILE,
1442                 MeasureUnit.MILE_SCANDINAVIAN,
1443                 MeasureUnit.MILLIMETER,
1444                 MeasureUnit.NANOMETER,
1445                 MeasureUnit.NAUTICAL_MILE,
1446                 MeasureUnit.PARSEC,
1447                 MeasureUnit.PICOMETER,
1448                 MeasureUnit.POINT,
1449                 MeasureUnit.SOLAR_RADIUS,
1450                 MeasureUnit.YARD,
1451                 MeasureUnit.LUX,
1452                 MeasureUnit.SOLAR_LUMINOSITY,
1453                 MeasureUnit.CARAT,
1454                 MeasureUnit.DALTON,
1455                 MeasureUnit.EARTH_MASS,
1456                 MeasureUnit.GRAM,
1457                 MeasureUnit.KILOGRAM,
1458                 MeasureUnit.METRIC_TON,
1459                 MeasureUnit.MICROGRAM,
1460                 MeasureUnit.MILLIGRAM,
1461                 MeasureUnit.OUNCE,
1462                 MeasureUnit.OUNCE_TROY,
1463                 MeasureUnit.POUND,
1464                 MeasureUnit.SOLAR_MASS,
1465                 MeasureUnit.STONE,
1466                 MeasureUnit.TON,
1467                 MeasureUnit.GIGAWATT,
1468                 MeasureUnit.HORSEPOWER,
1469                 MeasureUnit.KILOWATT,
1470                 MeasureUnit.MEGAWATT,
1471                 MeasureUnit.MILLIWATT,
1472                 MeasureUnit.WATT,
1473                 MeasureUnit.ATMOSPHERE,
1474                 MeasureUnit.HECTOPASCAL,
1475                 MeasureUnit.INCH_HG,
1476                 MeasureUnit.KILOPASCAL,
1477                 MeasureUnit.MEGAPASCAL,
1478                 MeasureUnit.MILLIBAR,
1479                 MeasureUnit.MILLIMETER_OF_MERCURY,
1480                 MeasureUnit.POUND_PER_SQUARE_INCH,
1481                 MeasureUnit.KILOMETER_PER_HOUR,
1482                 MeasureUnit.KNOT,
1483                 MeasureUnit.METER_PER_SECOND,
1484                 MeasureUnit.MILE_PER_HOUR,
1485                 MeasureUnit.CELSIUS,
1486                 MeasureUnit.FAHRENHEIT,
1487                 MeasureUnit.GENERIC_TEMPERATURE,
1488                 MeasureUnit.KELVIN,
1489                 MeasureUnit.NEWTON_METER,
1490                 MeasureUnit.POUND_FOOT,
1491                 MeasureUnit.ACRE_FOOT,
1492                 MeasureUnit.BARREL,
1493                 MeasureUnit.BUSHEL,
1494                 MeasureUnit.CENTILITER,
1495                 MeasureUnit.CUBIC_CENTIMETER,
1496                 MeasureUnit.CUBIC_FOOT,
1497                 MeasureUnit.CUBIC_INCH,
1498                 MeasureUnit.CUBIC_KILOMETER,
1499                 MeasureUnit.CUBIC_METER,
1500                 MeasureUnit.CUBIC_MILE,
1501                 MeasureUnit.CUBIC_YARD,
1502                 MeasureUnit.CUP,
1503                 MeasureUnit.CUP_METRIC,
1504                 MeasureUnit.DECILITER,
1505                 MeasureUnit.FLUID_OUNCE,
1506                 MeasureUnit.FLUID_OUNCE_IMPERIAL,
1507                 MeasureUnit.GALLON,
1508                 MeasureUnit.GALLON_IMPERIAL,
1509                 MeasureUnit.HECTOLITER,
1510                 MeasureUnit.LITER,
1511                 MeasureUnit.MEGALITER,
1512                 MeasureUnit.MILLILITER,
1513                 MeasureUnit.PINT,
1514                 MeasureUnit.PINT_METRIC,
1515                 MeasureUnit.QUART,
1516                 MeasureUnit.TABLESPOON,
1517                 MeasureUnit.TEASPOON,
1518         };
1519         assertEquals("",  161, units.length);
1520     }
1521 
1522     @Test
TestCompatible65()1523     public void TestCompatible65() {
1524         MeasureUnit[] units = {
1525                 MeasureUnit.G_FORCE,
1526                 MeasureUnit.METER_PER_SECOND_SQUARED,
1527                 MeasureUnit.ARC_MINUTE,
1528                 MeasureUnit.ARC_SECOND,
1529                 MeasureUnit.DEGREE,
1530                 MeasureUnit.RADIAN,
1531                 MeasureUnit.REVOLUTION_ANGLE,
1532                 MeasureUnit.ACRE,
1533                 MeasureUnit.DUNAM,
1534                 MeasureUnit.HECTARE,
1535                 MeasureUnit.SQUARE_CENTIMETER,
1536                 MeasureUnit.SQUARE_FOOT,
1537                 MeasureUnit.SQUARE_INCH,
1538                 MeasureUnit.SQUARE_KILOMETER,
1539                 MeasureUnit.SQUARE_METER,
1540                 MeasureUnit.SQUARE_MILE,
1541                 MeasureUnit.SQUARE_YARD,
1542                 MeasureUnit.KARAT,
1543                 MeasureUnit.MILLIGRAM_PER_DECILITER,
1544                 MeasureUnit.MILLIMOLE_PER_LITER,
1545                 MeasureUnit.MOLE,
1546                 MeasureUnit.PART_PER_MILLION,
1547                 MeasureUnit.PERCENT,
1548                 MeasureUnit.PERMILLE,
1549                 MeasureUnit.PERMYRIAD,
1550                 MeasureUnit.LITER_PER_100KILOMETERS,
1551                 MeasureUnit.LITER_PER_KILOMETER,
1552                 MeasureUnit.MILE_PER_GALLON,
1553                 MeasureUnit.MILE_PER_GALLON_IMPERIAL,
1554                 MeasureUnit.BIT,
1555                 MeasureUnit.BYTE,
1556                 MeasureUnit.GIGABIT,
1557                 MeasureUnit.GIGABYTE,
1558                 MeasureUnit.KILOBIT,
1559                 MeasureUnit.KILOBYTE,
1560                 MeasureUnit.MEGABIT,
1561                 MeasureUnit.MEGABYTE,
1562                 MeasureUnit.PETABYTE,
1563                 MeasureUnit.TERABIT,
1564                 MeasureUnit.TERABYTE,
1565                 MeasureUnit.CENTURY,
1566                 MeasureUnit.DAY,
1567                 MeasureUnit.DAY_PERSON,
1568                 MeasureUnit.DECADE,
1569                 MeasureUnit.HOUR,
1570                 MeasureUnit.MICROSECOND,
1571                 MeasureUnit.MILLISECOND,
1572                 MeasureUnit.MINUTE,
1573                 MeasureUnit.MONTH,
1574                 MeasureUnit.MONTH_PERSON,
1575                 MeasureUnit.NANOSECOND,
1576                 MeasureUnit.SECOND,
1577                 MeasureUnit.WEEK,
1578                 MeasureUnit.WEEK_PERSON,
1579                 MeasureUnit.YEAR,
1580                 MeasureUnit.YEAR_PERSON,
1581                 MeasureUnit.AMPERE,
1582                 MeasureUnit.MILLIAMPERE,
1583                 MeasureUnit.OHM,
1584                 MeasureUnit.VOLT,
1585                 MeasureUnit.BRITISH_THERMAL_UNIT,
1586                 MeasureUnit.CALORIE,
1587                 MeasureUnit.ELECTRONVOLT,
1588                 MeasureUnit.FOODCALORIE,
1589                 MeasureUnit.JOULE,
1590                 MeasureUnit.KILOCALORIE,
1591                 MeasureUnit.KILOJOULE,
1592                 MeasureUnit.KILOWATT_HOUR,
1593                 MeasureUnit.THERM_US,
1594                 MeasureUnit.NEWTON,
1595                 MeasureUnit.POUND_FORCE,
1596                 MeasureUnit.GIGAHERTZ,
1597                 MeasureUnit.HERTZ,
1598                 MeasureUnit.KILOHERTZ,
1599                 MeasureUnit.MEGAHERTZ,
1600                 MeasureUnit.DOT_PER_CENTIMETER,
1601                 MeasureUnit.DOT_PER_INCH,
1602                 MeasureUnit.EM,
1603                 MeasureUnit.MEGAPIXEL,
1604                 MeasureUnit.PIXEL,
1605                 MeasureUnit.PIXEL_PER_CENTIMETER,
1606                 MeasureUnit.PIXEL_PER_INCH,
1607                 MeasureUnit.ASTRONOMICAL_UNIT,
1608                 MeasureUnit.CENTIMETER,
1609                 MeasureUnit.DECIMETER,
1610                 MeasureUnit.FATHOM,
1611                 MeasureUnit.FOOT,
1612                 MeasureUnit.FURLONG,
1613                 MeasureUnit.INCH,
1614                 MeasureUnit.KILOMETER,
1615                 MeasureUnit.LIGHT_YEAR,
1616                 MeasureUnit.METER,
1617                 MeasureUnit.MICROMETER,
1618                 MeasureUnit.MILE,
1619                 MeasureUnit.MILE_SCANDINAVIAN,
1620                 MeasureUnit.MILLIMETER,
1621                 MeasureUnit.NANOMETER,
1622                 MeasureUnit.NAUTICAL_MILE,
1623                 MeasureUnit.PARSEC,
1624                 MeasureUnit.PICOMETER,
1625                 MeasureUnit.POINT,
1626                 MeasureUnit.SOLAR_RADIUS,
1627                 MeasureUnit.YARD,
1628                 MeasureUnit.LUX,
1629                 MeasureUnit.SOLAR_LUMINOSITY,
1630                 MeasureUnit.CARAT,
1631                 MeasureUnit.DALTON,
1632                 MeasureUnit.EARTH_MASS,
1633                 MeasureUnit.GRAM,
1634                 MeasureUnit.KILOGRAM,
1635                 MeasureUnit.METRIC_TON,
1636                 MeasureUnit.MICROGRAM,
1637                 MeasureUnit.MILLIGRAM,
1638                 MeasureUnit.OUNCE,
1639                 MeasureUnit.OUNCE_TROY,
1640                 MeasureUnit.POUND,
1641                 MeasureUnit.SOLAR_MASS,
1642                 MeasureUnit.STONE,
1643                 MeasureUnit.TON,
1644                 MeasureUnit.GIGAWATT,
1645                 MeasureUnit.HORSEPOWER,
1646                 MeasureUnit.KILOWATT,
1647                 MeasureUnit.MEGAWATT,
1648                 MeasureUnit.MILLIWATT,
1649                 MeasureUnit.WATT,
1650                 MeasureUnit.ATMOSPHERE,
1651                 MeasureUnit.BAR,
1652                 MeasureUnit.HECTOPASCAL,
1653                 MeasureUnit.INCH_HG,
1654                 MeasureUnit.KILOPASCAL,
1655                 MeasureUnit.MEGAPASCAL,
1656                 MeasureUnit.MILLIBAR,
1657                 MeasureUnit.MILLIMETER_OF_MERCURY,
1658                 MeasureUnit.PASCAL,
1659                 MeasureUnit.POUND_PER_SQUARE_INCH,
1660                 MeasureUnit.KILOMETER_PER_HOUR,
1661                 MeasureUnit.KNOT,
1662                 MeasureUnit.METER_PER_SECOND,
1663                 MeasureUnit.MILE_PER_HOUR,
1664                 MeasureUnit.CELSIUS,
1665                 MeasureUnit.FAHRENHEIT,
1666                 MeasureUnit.GENERIC_TEMPERATURE,
1667                 MeasureUnit.KELVIN,
1668                 MeasureUnit.NEWTON_METER,
1669                 MeasureUnit.POUND_FOOT,
1670                 MeasureUnit.ACRE_FOOT,
1671                 MeasureUnit.BARREL,
1672                 MeasureUnit.BUSHEL,
1673                 MeasureUnit.CENTILITER,
1674                 MeasureUnit.CUBIC_CENTIMETER,
1675                 MeasureUnit.CUBIC_FOOT,
1676                 MeasureUnit.CUBIC_INCH,
1677                 MeasureUnit.CUBIC_KILOMETER,
1678                 MeasureUnit.CUBIC_METER,
1679                 MeasureUnit.CUBIC_MILE,
1680                 MeasureUnit.CUBIC_YARD,
1681                 MeasureUnit.CUP,
1682                 MeasureUnit.CUP_METRIC,
1683                 MeasureUnit.DECILITER,
1684                 MeasureUnit.FLUID_OUNCE,
1685                 MeasureUnit.FLUID_OUNCE_IMPERIAL,
1686                 MeasureUnit.GALLON,
1687                 MeasureUnit.GALLON_IMPERIAL,
1688                 MeasureUnit.HECTOLITER,
1689                 MeasureUnit.LITER,
1690                 MeasureUnit.MEGALITER,
1691                 MeasureUnit.MILLILITER,
1692                 MeasureUnit.PINT,
1693                 MeasureUnit.PINT_METRIC,
1694                 MeasureUnit.QUART,
1695                 MeasureUnit.TABLESPOON,
1696                 MeasureUnit.TEASPOON,
1697         };
1698         assertEquals("",  172, units.length);
1699     }
1700 
1701     @Test
TestCompatible68()1702     public void TestCompatible68() {
1703         MeasureUnit[] units = {
1704                 MeasureUnit.G_FORCE,
1705                 MeasureUnit.METER_PER_SECOND_SQUARED,
1706                 MeasureUnit.ARC_MINUTE,
1707                 MeasureUnit.ARC_SECOND,
1708                 MeasureUnit.DEGREE,
1709                 MeasureUnit.RADIAN,
1710                 MeasureUnit.REVOLUTION_ANGLE,
1711                 MeasureUnit.ACRE,
1712                 MeasureUnit.DUNAM,
1713                 MeasureUnit.HECTARE,
1714                 MeasureUnit.SQUARE_CENTIMETER,
1715                 MeasureUnit.SQUARE_FOOT,
1716                 MeasureUnit.SQUARE_INCH,
1717                 MeasureUnit.SQUARE_KILOMETER,
1718                 MeasureUnit.SQUARE_METER,
1719                 MeasureUnit.SQUARE_MILE,
1720                 MeasureUnit.SQUARE_YARD,
1721                 MeasureUnit.KARAT,
1722                 MeasureUnit.MILLIGRAM_PER_DECILITER,
1723                 MeasureUnit.MILLIMOLE_PER_LITER,
1724                 MeasureUnit.MOLE,
1725                 MeasureUnit.PERCENT,
1726                 MeasureUnit.PERMILLE,
1727                 MeasureUnit.PART_PER_MILLION,
1728                 MeasureUnit.PERMYRIAD,
1729                 MeasureUnit.LITER_PER_100KILOMETERS,
1730                 MeasureUnit.LITER_PER_KILOMETER,
1731                 MeasureUnit.MILE_PER_GALLON,
1732                 MeasureUnit.MILE_PER_GALLON_IMPERIAL,
1733                 MeasureUnit.BIT,
1734                 MeasureUnit.BYTE,
1735                 MeasureUnit.GIGABIT,
1736                 MeasureUnit.GIGABYTE,
1737                 MeasureUnit.KILOBIT,
1738                 MeasureUnit.KILOBYTE,
1739                 MeasureUnit.MEGABIT,
1740                 MeasureUnit.MEGABYTE,
1741                 MeasureUnit.PETABYTE,
1742                 MeasureUnit.TERABIT,
1743                 MeasureUnit.TERABYTE,
1744                 MeasureUnit.CENTURY,
1745                 MeasureUnit.DAY,
1746                 MeasureUnit.DAY_PERSON,
1747                 MeasureUnit.DECADE,
1748                 MeasureUnit.HOUR,
1749                 MeasureUnit.MICROSECOND,
1750                 MeasureUnit.MILLISECOND,
1751                 MeasureUnit.MINUTE,
1752                 MeasureUnit.MONTH,
1753                 MeasureUnit.MONTH_PERSON,
1754                 MeasureUnit.NANOSECOND,
1755                 MeasureUnit.SECOND,
1756                 MeasureUnit.WEEK,
1757                 MeasureUnit.WEEK_PERSON,
1758                 MeasureUnit.YEAR,
1759                 MeasureUnit.YEAR_PERSON,
1760                 MeasureUnit.AMPERE,
1761                 MeasureUnit.MILLIAMPERE,
1762                 MeasureUnit.OHM,
1763                 MeasureUnit.VOLT,
1764                 MeasureUnit.BRITISH_THERMAL_UNIT,
1765                 MeasureUnit.CALORIE,
1766                 MeasureUnit.ELECTRONVOLT,
1767                 MeasureUnit.FOODCALORIE,
1768                 MeasureUnit.JOULE,
1769                 MeasureUnit.KILOCALORIE,
1770                 MeasureUnit.KILOJOULE,
1771                 MeasureUnit.KILOWATT_HOUR,
1772                 MeasureUnit.THERM_US,
1773                 MeasureUnit.NEWTON,
1774                 MeasureUnit.POUND_FORCE,
1775                 MeasureUnit.GIGAHERTZ,
1776                 MeasureUnit.HERTZ,
1777                 MeasureUnit.KILOHERTZ,
1778                 MeasureUnit.MEGAHERTZ,
1779                 MeasureUnit.DOT,
1780                 MeasureUnit.DOT_PER_CENTIMETER,
1781                 MeasureUnit.DOT_PER_INCH,
1782                 MeasureUnit.EM,
1783                 MeasureUnit.MEGAPIXEL,
1784                 MeasureUnit.PIXEL,
1785                 MeasureUnit.PIXEL_PER_CENTIMETER,
1786                 MeasureUnit.PIXEL_PER_INCH,
1787                 MeasureUnit.ASTRONOMICAL_UNIT,
1788                 MeasureUnit.CENTIMETER,
1789                 MeasureUnit.DECIMETER,
1790                 MeasureUnit.EARTH_RADIUS,
1791                 MeasureUnit.FATHOM,
1792                 MeasureUnit.FOOT,
1793                 MeasureUnit.FURLONG,
1794                 MeasureUnit.INCH,
1795                 MeasureUnit.KILOMETER,
1796                 MeasureUnit.LIGHT_YEAR,
1797                 MeasureUnit.METER,
1798                 MeasureUnit.MICROMETER,
1799                 MeasureUnit.MILE,
1800                 MeasureUnit.MILE_SCANDINAVIAN,
1801                 MeasureUnit.MILLIMETER,
1802                 MeasureUnit.NANOMETER,
1803                 MeasureUnit.NAUTICAL_MILE,
1804                 MeasureUnit.PARSEC,
1805                 MeasureUnit.PICOMETER,
1806                 MeasureUnit.POINT,
1807                 MeasureUnit.SOLAR_RADIUS,
1808                 MeasureUnit.YARD,
1809                 MeasureUnit.CANDELA,
1810                 MeasureUnit.LUMEN,
1811                 MeasureUnit.LUX,
1812                 MeasureUnit.SOLAR_LUMINOSITY,
1813                 MeasureUnit.CARAT,
1814                 MeasureUnit.DALTON,
1815                 MeasureUnit.EARTH_MASS,
1816                 MeasureUnit.GRAIN,
1817                 MeasureUnit.GRAM,
1818                 MeasureUnit.KILOGRAM,
1819                 MeasureUnit.METRIC_TON,
1820                 MeasureUnit.MICROGRAM,
1821                 MeasureUnit.MILLIGRAM,
1822                 MeasureUnit.OUNCE,
1823                 MeasureUnit.OUNCE_TROY,
1824                 MeasureUnit.POUND,
1825                 MeasureUnit.SOLAR_MASS,
1826                 MeasureUnit.STONE,
1827                 MeasureUnit.TON,
1828                 MeasureUnit.GIGAWATT,
1829                 MeasureUnit.HORSEPOWER,
1830                 MeasureUnit.KILOWATT,
1831                 MeasureUnit.MEGAWATT,
1832                 MeasureUnit.MILLIWATT,
1833                 MeasureUnit.WATT,
1834                 MeasureUnit.ATMOSPHERE,
1835                 MeasureUnit.BAR,
1836                 MeasureUnit.HECTOPASCAL,
1837                 MeasureUnit.INCH_HG,
1838                 MeasureUnit.KILOPASCAL,
1839                 MeasureUnit.MEGAPASCAL,
1840                 MeasureUnit.MILLIBAR,
1841                 MeasureUnit.MILLIMETER_OF_MERCURY,
1842                 MeasureUnit.PASCAL,
1843                 MeasureUnit.POUND_PER_SQUARE_INCH,
1844                 MeasureUnit.KILOMETER_PER_HOUR,
1845                 MeasureUnit.KNOT,
1846                 MeasureUnit.METER_PER_SECOND,
1847                 MeasureUnit.MILE_PER_HOUR,
1848                 MeasureUnit.CELSIUS,
1849                 MeasureUnit.FAHRENHEIT,
1850                 MeasureUnit.GENERIC_TEMPERATURE,
1851                 MeasureUnit.KELVIN,
1852                 MeasureUnit.NEWTON_METER,
1853                 MeasureUnit.POUND_FOOT,
1854                 MeasureUnit.ACRE_FOOT,
1855                 MeasureUnit.BARREL,
1856                 MeasureUnit.BUSHEL,
1857                 MeasureUnit.CENTILITER,
1858                 MeasureUnit.CUBIC_CENTIMETER,
1859                 MeasureUnit.CUBIC_FOOT,
1860                 MeasureUnit.CUBIC_INCH,
1861                 MeasureUnit.CUBIC_KILOMETER,
1862                 MeasureUnit.CUBIC_METER,
1863                 MeasureUnit.CUBIC_MILE,
1864                 MeasureUnit.CUBIC_YARD,
1865                 MeasureUnit.CUP,
1866                 MeasureUnit.CUP_METRIC,
1867                 MeasureUnit.DECILITER,
1868                 MeasureUnit.DESSERT_SPOON,
1869                 MeasureUnit.DESSERT_SPOON_IMPERIAL,
1870                 MeasureUnit.DRAM,
1871                 MeasureUnit.DROP,
1872                 MeasureUnit.FLUID_OUNCE,
1873                 MeasureUnit.FLUID_OUNCE_IMPERIAL,
1874                 MeasureUnit.GALLON,
1875                 MeasureUnit.GALLON_IMPERIAL,
1876                 MeasureUnit.HECTOLITER,
1877                 MeasureUnit.JIGGER,
1878                 MeasureUnit.LITER,
1879                 MeasureUnit.MEGALITER,
1880                 MeasureUnit.MILLILITER,
1881                 MeasureUnit.PINCH,
1882                 MeasureUnit.PINT,
1883                 MeasureUnit.PINT_METRIC,
1884                 MeasureUnit.QUART,
1885                 MeasureUnit.QUART_IMPERIAL,
1886                 MeasureUnit.TABLESPOON,
1887                 MeasureUnit.TEASPOON,
1888         };
1889         assertEquals("",  184, units.length);
1890     }
1891 
1892     @Test
TestCompatible69()1893     public void TestCompatible69() {
1894         MeasureUnit[] units = {
1895                 MeasureUnit.G_FORCE,
1896                 MeasureUnit.METER_PER_SECOND_SQUARED,
1897                 MeasureUnit.ARC_MINUTE,
1898                 MeasureUnit.ARC_SECOND,
1899                 MeasureUnit.DEGREE,
1900                 MeasureUnit.RADIAN,
1901                 MeasureUnit.REVOLUTION_ANGLE,
1902                 MeasureUnit.ACRE,
1903                 MeasureUnit.DUNAM,
1904                 MeasureUnit.HECTARE,
1905                 MeasureUnit.SQUARE_CENTIMETER,
1906                 MeasureUnit.SQUARE_FOOT,
1907                 MeasureUnit.SQUARE_INCH,
1908                 MeasureUnit.SQUARE_KILOMETER,
1909                 MeasureUnit.SQUARE_METER,
1910                 MeasureUnit.SQUARE_MILE,
1911                 MeasureUnit.SQUARE_YARD,
1912                 MeasureUnit.KARAT,
1913                 MeasureUnit.MILLIGRAM_OFGLUCOSE_PER_DECILITER,
1914                 MeasureUnit.MILLIGRAM_PER_DECILITER,
1915                 MeasureUnit.MILLIMOLE_PER_LITER,
1916                 MeasureUnit.MOLE,
1917                 MeasureUnit.PERCENT,
1918                 MeasureUnit.PERMILLE,
1919                 MeasureUnit.PART_PER_MILLION,
1920                 MeasureUnit.PERMYRIAD,
1921                 MeasureUnit.LITER_PER_100KILOMETERS,
1922                 MeasureUnit.LITER_PER_KILOMETER,
1923                 MeasureUnit.MILE_PER_GALLON,
1924                 MeasureUnit.MILE_PER_GALLON_IMPERIAL,
1925                 MeasureUnit.BIT,
1926                 MeasureUnit.BYTE,
1927                 MeasureUnit.GIGABIT,
1928                 MeasureUnit.GIGABYTE,
1929                 MeasureUnit.KILOBIT,
1930                 MeasureUnit.KILOBYTE,
1931                 MeasureUnit.MEGABIT,
1932                 MeasureUnit.MEGABYTE,
1933                 MeasureUnit.PETABYTE,
1934                 MeasureUnit.TERABIT,
1935                 MeasureUnit.TERABYTE,
1936                 MeasureUnit.CENTURY,
1937                 MeasureUnit.DAY,
1938                 MeasureUnit.DAY_PERSON,
1939                 MeasureUnit.DECADE,
1940                 MeasureUnit.HOUR,
1941                 MeasureUnit.MICROSECOND,
1942                 MeasureUnit.MILLISECOND,
1943                 MeasureUnit.MINUTE,
1944                 MeasureUnit.MONTH,
1945                 MeasureUnit.MONTH_PERSON,
1946                 MeasureUnit.NANOSECOND,
1947                 MeasureUnit.SECOND,
1948                 MeasureUnit.WEEK,
1949                 MeasureUnit.WEEK_PERSON,
1950                 MeasureUnit.YEAR,
1951                 MeasureUnit.YEAR_PERSON,
1952                 MeasureUnit.AMPERE,
1953                 MeasureUnit.MILLIAMPERE,
1954                 MeasureUnit.OHM,
1955                 MeasureUnit.VOLT,
1956                 MeasureUnit.BRITISH_THERMAL_UNIT,
1957                 MeasureUnit.CALORIE,
1958                 MeasureUnit.ELECTRONVOLT,
1959                 MeasureUnit.FOODCALORIE,
1960                 MeasureUnit.JOULE,
1961                 MeasureUnit.KILOCALORIE,
1962                 MeasureUnit.KILOJOULE,
1963                 MeasureUnit.KILOWATT_HOUR,
1964                 MeasureUnit.THERM_US,
1965                 MeasureUnit.NEWTON,
1966                 MeasureUnit.POUND_FORCE,
1967                 MeasureUnit.GIGAHERTZ,
1968                 MeasureUnit.HERTZ,
1969                 MeasureUnit.KILOHERTZ,
1970                 MeasureUnit.MEGAHERTZ,
1971                 MeasureUnit.DOT,
1972                 MeasureUnit.DOT_PER_CENTIMETER,
1973                 MeasureUnit.DOT_PER_INCH,
1974                 MeasureUnit.EM,
1975                 MeasureUnit.MEGAPIXEL,
1976                 MeasureUnit.PIXEL,
1977                 MeasureUnit.PIXEL_PER_CENTIMETER,
1978                 MeasureUnit.PIXEL_PER_INCH,
1979                 MeasureUnit.ASTRONOMICAL_UNIT,
1980                 MeasureUnit.CENTIMETER,
1981                 MeasureUnit.DECIMETER,
1982                 MeasureUnit.EARTH_RADIUS,
1983                 MeasureUnit.FATHOM,
1984                 MeasureUnit.FOOT,
1985                 MeasureUnit.FURLONG,
1986                 MeasureUnit.INCH,
1987                 MeasureUnit.KILOMETER,
1988                 MeasureUnit.LIGHT_YEAR,
1989                 MeasureUnit.METER,
1990                 MeasureUnit.MICROMETER,
1991                 MeasureUnit.MILE,
1992                 MeasureUnit.MILE_SCANDINAVIAN,
1993                 MeasureUnit.MILLIMETER,
1994                 MeasureUnit.NANOMETER,
1995                 MeasureUnit.NAUTICAL_MILE,
1996                 MeasureUnit.PARSEC,
1997                 MeasureUnit.PICOMETER,
1998                 MeasureUnit.POINT,
1999                 MeasureUnit.SOLAR_RADIUS,
2000                 MeasureUnit.YARD,
2001                 MeasureUnit.CANDELA,
2002                 MeasureUnit.LUMEN,
2003                 MeasureUnit.LUX,
2004                 MeasureUnit.SOLAR_LUMINOSITY,
2005                 MeasureUnit.CARAT,
2006                 MeasureUnit.DALTON,
2007                 MeasureUnit.EARTH_MASS,
2008                 MeasureUnit.GRAIN,
2009                 MeasureUnit.GRAM,
2010                 MeasureUnit.KILOGRAM,
2011                 MeasureUnit.METRIC_TON,
2012                 MeasureUnit.MICROGRAM,
2013                 MeasureUnit.MILLIGRAM,
2014                 MeasureUnit.OUNCE,
2015                 MeasureUnit.OUNCE_TROY,
2016                 MeasureUnit.POUND,
2017                 MeasureUnit.SOLAR_MASS,
2018                 MeasureUnit.STONE,
2019                 MeasureUnit.TON,
2020                 MeasureUnit.GIGAWATT,
2021                 MeasureUnit.HORSEPOWER,
2022                 MeasureUnit.KILOWATT,
2023                 MeasureUnit.MEGAWATT,
2024                 MeasureUnit.MILLIWATT,
2025                 MeasureUnit.WATT,
2026                 MeasureUnit.ATMOSPHERE,
2027                 MeasureUnit.BAR,
2028                 MeasureUnit.HECTOPASCAL,
2029                 MeasureUnit.INCH_HG,
2030                 MeasureUnit.KILOPASCAL,
2031                 MeasureUnit.MEGAPASCAL,
2032                 MeasureUnit.MILLIBAR,
2033                 MeasureUnit.MILLIMETER_OF_MERCURY,
2034                 MeasureUnit.PASCAL,
2035                 MeasureUnit.POUND_PER_SQUARE_INCH,
2036                 MeasureUnit.KILOMETER_PER_HOUR,
2037                 MeasureUnit.KNOT,
2038                 MeasureUnit.METER_PER_SECOND,
2039                 MeasureUnit.MILE_PER_HOUR,
2040                 MeasureUnit.CELSIUS,
2041                 MeasureUnit.FAHRENHEIT,
2042                 MeasureUnit.GENERIC_TEMPERATURE,
2043                 MeasureUnit.KELVIN,
2044                 MeasureUnit.NEWTON_METER,
2045                 MeasureUnit.POUND_FOOT,
2046                 MeasureUnit.ACRE_FOOT,
2047                 MeasureUnit.BARREL,
2048                 MeasureUnit.BUSHEL,
2049                 MeasureUnit.CENTILITER,
2050                 MeasureUnit.CUBIC_CENTIMETER,
2051                 MeasureUnit.CUBIC_FOOT,
2052                 MeasureUnit.CUBIC_INCH,
2053                 MeasureUnit.CUBIC_KILOMETER,
2054                 MeasureUnit.CUBIC_METER,
2055                 MeasureUnit.CUBIC_MILE,
2056                 MeasureUnit.CUBIC_YARD,
2057                 MeasureUnit.CUP,
2058                 MeasureUnit.CUP_METRIC,
2059                 MeasureUnit.DECILITER,
2060                 MeasureUnit.DESSERT_SPOON,
2061                 MeasureUnit.DESSERT_SPOON_IMPERIAL,
2062                 MeasureUnit.DRAM,
2063                 MeasureUnit.DROP,
2064                 MeasureUnit.FLUID_OUNCE,
2065                 MeasureUnit.FLUID_OUNCE_IMPERIAL,
2066                 MeasureUnit.GALLON,
2067                 MeasureUnit.GALLON_IMPERIAL,
2068                 MeasureUnit.HECTOLITER,
2069                 MeasureUnit.JIGGER,
2070                 MeasureUnit.LITER,
2071                 MeasureUnit.MEGALITER,
2072                 MeasureUnit.MILLILITER,
2073                 MeasureUnit.PINCH,
2074                 MeasureUnit.PINT,
2075                 MeasureUnit.PINT_METRIC,
2076                 MeasureUnit.QUART,
2077                 MeasureUnit.QUART_IMPERIAL,
2078                 MeasureUnit.TABLESPOON,
2079                 MeasureUnit.TEASPOON,
2080         };
2081         assertEquals("",  185, units.length);
2082     }
2083 
2084     @Test
TestExamplesInDocs()2085     public void TestExamplesInDocs() {
2086         MeasureFormat fmtFr = MeasureFormat.getInstance(
2087                 ULocale.FRENCH, FormatWidth.SHORT);
2088         Measure measure = new Measure(23, MeasureUnit.CELSIUS);
2089         assertEquals("23\u202F°C", "23\u202F°C", fmtFr.format(measure));
2090         Measure measureF = new Measure(70, MeasureUnit.FAHRENHEIT);
2091         assertEquals("70\u202F°F", "70\u202F°F", fmtFr.format(measureF));
2092         MeasureFormat fmtFrFull = MeasureFormat.getInstance(
2093                 ULocale.FRENCH, FormatWidth.WIDE);
2094         assertEquals(
2095                 "70 pied et 5,3 pouces",
2096                 "70 pieds et 5,3 pouces",
2097                 fmtFrFull.formatMeasures(
2098                         new Measure(70, MeasureUnit.FOOT),
2099                         new Measure(5.3, MeasureUnit.INCH)));
2100         assertEquals(
2101                 "1\u00A0pied et 1\u00A0pouce",
2102                 "1\u00A0pied et 1\u00A0pouce",
2103                 fmtFrFull.formatMeasures(
2104                         new Measure(1, MeasureUnit.FOOT),
2105                         new Measure(1, MeasureUnit.INCH)));
2106         MeasureFormat fmtFrNarrow = MeasureFormat.getInstance(
2107                 ULocale.FRENCH, FormatWidth.NARROW);
2108         assertEquals(
2109                 "1′ 1″",
2110                 "1′ 1″",
2111                 fmtFrNarrow.formatMeasures(
2112                         new Measure(1, MeasureUnit.FOOT),
2113                         new Measure(1, MeasureUnit.INCH)));
2114         MeasureFormat fmtEn = MeasureFormat.getInstance(ULocale.ENGLISH, FormatWidth.WIDE);
2115         assertEquals(
2116                 "1 inch, 2 feet",
2117                 "1 inch, 2 feet",
2118                 fmtEn.formatMeasures(
2119                         new Measure(1, MeasureUnit.INCH),
2120                         new Measure(2, MeasureUnit.FOOT)));
2121     }
2122 
2123     @Test
TestFormatPeriodEn()2124     public void TestFormatPeriodEn() {
2125         TimeUnitAmount[] _19m = {new TimeUnitAmount(19.0, TimeUnit.MINUTE)};
2126         TimeUnitAmount[] _1h_23_5s = {
2127                 new TimeUnitAmount(1.0, TimeUnit.HOUR),
2128                 new TimeUnitAmount(23.5, TimeUnit.SECOND)};
2129         TimeUnitAmount[] _1h_23_5m = {
2130                 new TimeUnitAmount(1.0, TimeUnit.HOUR),
2131                 new TimeUnitAmount(23.5, TimeUnit.MINUTE)};
2132         TimeUnitAmount[] _1h_0m_23s = {
2133                 new TimeUnitAmount(1.0, TimeUnit.HOUR),
2134                 new TimeUnitAmount(0.0, TimeUnit.MINUTE),
2135                 new TimeUnitAmount(23.0, TimeUnit.SECOND)};
2136         TimeUnitAmount[] _2y_5M_3w_4d = {
2137                 new TimeUnitAmount(2.0, TimeUnit.YEAR),
2138                 new TimeUnitAmount(5.0, TimeUnit.MONTH),
2139                 new TimeUnitAmount(3.0, TimeUnit.WEEK),
2140                 new TimeUnitAmount(4.0, TimeUnit.DAY)};
2141         TimeUnitAmount[] _1m_59_9996s = {
2142                 new TimeUnitAmount(1.0, TimeUnit.MINUTE),
2143                 new TimeUnitAmount(59.9996, TimeUnit.SECOND)};
2144         TimeUnitAmount[] _5h_17m = {
2145                 new TimeUnitAmount(5.0, TimeUnit.HOUR),
2146                 new TimeUnitAmount(17.0, TimeUnit.MINUTE)};
2147         TimeUnitAmount[] _neg5h_17m = {
2148                 new TimeUnitAmount(-5.0, TimeUnit.HOUR),
2149                 new TimeUnitAmount(17.0, TimeUnit.MINUTE)};
2150         TimeUnitAmount[] _19m_28s = {
2151                 new TimeUnitAmount(19.0, TimeUnit.MINUTE),
2152                 new TimeUnitAmount(28.0, TimeUnit.SECOND)};
2153         TimeUnitAmount[] _0h_0m_9s = {
2154                 new TimeUnitAmount(0.0, TimeUnit.HOUR),
2155                 new TimeUnitAmount(0.0, TimeUnit.MINUTE),
2156                 new TimeUnitAmount(9.0, TimeUnit.SECOND)};
2157         TimeUnitAmount[] _0h_0m_17s = {
2158                 new TimeUnitAmount(0.0, TimeUnit.HOUR),
2159                 new TimeUnitAmount(0.0, TimeUnit.MINUTE),
2160                 new TimeUnitAmount(17.0, TimeUnit.SECOND)};
2161         TimeUnitAmount[] _6h_56_92m = {
2162                 new TimeUnitAmount(6.0, TimeUnit.HOUR),
2163                 new TimeUnitAmount(56.92, TimeUnit.MINUTE)};
2164         TimeUnitAmount[] _3h_4s_5m = {
2165                 new TimeUnitAmount(3.0, TimeUnit.HOUR),
2166                 new TimeUnitAmount(4.0, TimeUnit.SECOND),
2167                 new TimeUnitAmount(5.0, TimeUnit.MINUTE)};
2168         TimeUnitAmount[] _6_7h_56_92m = {
2169                 new TimeUnitAmount(6.7, TimeUnit.HOUR),
2170                 new TimeUnitAmount(56.92, TimeUnit.MINUTE)};
2171         TimeUnitAmount[] _3h_5h = {
2172                 new TimeUnitAmount(3.0, TimeUnit.HOUR),
2173                 new TimeUnitAmount(5.0, TimeUnit.HOUR)};
2174 
2175         Object[][] fullData = {
2176                 {_1m_59_9996s, "1 minute, 59.9996 seconds"},
2177                 {_19m, "19 minutes"},
2178                 {_1h_23_5s, "1 hour, 23.5 seconds"},
2179                 {_1h_23_5m, "1 hour, 23.5 minutes"},
2180                 {_1h_0m_23s, "1 hour, 0 minutes, 23 seconds"},
2181                 {_2y_5M_3w_4d, "2 years, 5 months, 3 weeks, 4 days"}};
2182         Object[][] abbrevData = {
2183                 {_1m_59_9996s, "1 min, 59.9996 sec"},
2184                 {_19m, "19 min"},
2185                 {_1h_23_5s, "1 hr, 23.5 sec"},
2186                 {_1h_23_5m, "1 hr, 23.5 min"},
2187                 {_1h_0m_23s, "1 hr, 0 min, 23 sec"},
2188                 {_2y_5M_3w_4d, "2 yrs, 5 mths, 3 wks, 4 days"}};
2189         Object[][] narrowData = {
2190                 {_1m_59_9996s, "1m 59.9996s"},
2191                 {_19m, "19m"},
2192                 {_1h_23_5s, "1h 23.5s"},
2193                 {_1h_23_5m, "1h 23.5m"},
2194                 {_1h_0m_23s, "1h 0m 23s"},
2195                 {_2y_5M_3w_4d, "2y 5m 3w 4d"}};
2196 
2197 
2198         Object[][] numericData = {
2199                 {_1m_59_9996s, "1:59.9996"},
2200                 {_19m, "19m"},
2201                 {_1h_23_5s, "1:00:23.5"},
2202                 {_1h_0m_23s, "1:00:23"},
2203                 {_1h_23_5m, "1:23.5"},
2204                 {_5h_17m, "5:17"},
2205                 {_neg5h_17m, "-5h 17m"},
2206                 {_19m_28s, "19:28"},
2207                 {_2y_5M_3w_4d, "2y 5m 3w 4d"},
2208                 {_0h_0m_9s, "0:00:09"},
2209                 {_6h_56_92m, "6:56.92"},
2210                 {_6_7h_56_92m, "6:56.92"},
2211                 {_3h_4s_5m, "3h 4s 5m"},
2212                 {_3h_5h, "3h 5h"}};
2213         Object[][] fullDataDe = {
2214                 {_1m_59_9996s, "1 Minute, 59,9996 Sekunden"},
2215                 {_19m, "19 Minuten"},
2216                 {_1h_23_5s, "1 Stunde, 23,5 Sekunden"},
2217                 {_1h_23_5m, "1 Stunde, 23,5 Minuten"},
2218                 {_1h_0m_23s, "1 Stunde, 0 Minuten und 23 Sekunden"},
2219                 {_2y_5M_3w_4d, "2 Jahre, 5 Monate, 3 Wochen und 4 Tage"}};
2220         Object[][] numericDataDe = {
2221                 {_1m_59_9996s, "1:59,9996"},
2222                 {_19m, "19 Min."},
2223                 {_1h_23_5s, "1:00:23,5"},
2224                 {_1h_0m_23s, "1:00:23"},
2225                 {_1h_23_5m, "1:23,5"},
2226                 {_5h_17m, "5:17"},
2227                 {_19m_28s, "19:28"},
2228                 {_2y_5M_3w_4d, "2 J, 5 M, 3 W und 4 T"},
2229                 {_0h_0m_17s, "0:00:17"},
2230                 {_6h_56_92m, "6:56,92"},
2231                 {_3h_5h, "3 Std., 5 Std."}};
2232         Object[][] numericDataBn = {
2233                 {_1m_59_9996s, "১:৫৯.৯৯৯৬"},
2234                 {_19m, "১৯ মিঃ"},
2235                 {_1h_23_5s, "১:০০:২৩.৫"},
2236                 {_1h_0m_23s, "১:০০:২৩"},
2237                 {_1h_23_5m, "১:২৩.৫"},
2238                 {_5h_17m, "৫:১৭"},
2239                 {_19m_28s, "১৯:২৮"},
2240                 {_2y_5M_3w_4d, "২ বছর, ৫ মাস, ৩ সপ্তাহ, ৪ দিন"},
2241                 {_0h_0m_17s, "০:০০:১৭"},
2242                 {_6h_56_92m, "৬:৫৬.৯২"},
2243                 {_3h_5h, "৩ ঘঃ, ৫ ঘঃ"}};
2244         Object[][] numericDataBnLatn = {
2245                 {_1m_59_9996s, "1:59.9996"},
2246                 {_19m, "19 মিঃ"},
2247                 {_1h_23_5s, "1:00:23.5"},
2248                 {_1h_0m_23s, "1:00:23"},
2249                 {_1h_23_5m, "1:23.5"},
2250                 {_5h_17m, "5:17"},
2251                 {_19m_28s, "19:28"},
2252                 {_2y_5M_3w_4d, "2 বছর, 5 মাস, 3 সপ্তাহ, 4 দিন"},
2253                 {_0h_0m_17s, "0:00:17"},
2254                 {_6h_56_92m, "6:56.92"},
2255                 {_3h_5h, "3 ঘঃ, 5 ঘঃ"}};
2256 
2257         NumberFormat nf = NumberFormat.getNumberInstance(ULocale.ENGLISH);
2258         nf.setMaximumFractionDigits(4);
2259         MeasureFormat mf = MeasureFormat.getInstance(ULocale.ENGLISH, FormatWidth.WIDE, nf);
2260         verifyFormatPeriod("en FULL", mf, fullData);
2261         mf = MeasureFormat.getInstance(ULocale.ENGLISH, FormatWidth.SHORT, nf);
2262         verifyFormatPeriod("en SHORT", mf, abbrevData);
2263         mf = MeasureFormat.getInstance(ULocale.ENGLISH, FormatWidth.NARROW, nf);
2264         verifyFormatPeriod("en NARROW", mf, narrowData);
2265         mf = MeasureFormat.getInstance(ULocale.ENGLISH, FormatWidth.NUMERIC, nf);
2266         verifyFormatPeriod("en NUMERIC", mf, numericData);
2267 
2268         nf = NumberFormat.getNumberInstance(ULocale.GERMAN);
2269         nf.setMaximumFractionDigits(4);
2270         mf = MeasureFormat.getInstance(ULocale.GERMAN, FormatWidth.WIDE, nf);
2271         verifyFormatPeriod("de FULL", mf, fullDataDe);
2272         mf = MeasureFormat.getInstance(ULocale.GERMAN, FormatWidth.NUMERIC, nf);
2273         verifyFormatPeriod("de NUMERIC", mf, numericDataDe);
2274 
2275         // Same tests, with Java Locale
2276         nf = NumberFormat.getNumberInstance(Locale.GERMAN);
2277         nf.setMaximumFractionDigits(4);
2278         mf = MeasureFormat.getInstance(Locale.GERMAN, FormatWidth.WIDE, nf);
2279         verifyFormatPeriod("de FULL(Java Locale)", mf, fullDataDe);
2280         mf = MeasureFormat.getInstance(Locale.GERMAN, FormatWidth.NUMERIC, nf);
2281         verifyFormatPeriod("de NUMERIC(Java Locale)", mf, numericDataDe);
2282 
2283         ULocale bengali = ULocale.forLanguageTag("bn");
2284         nf = NumberFormat.getNumberInstance(bengali);
2285         nf.setMaximumFractionDigits(4);
2286         mf = MeasureFormat.getInstance(bengali, FormatWidth.NUMERIC, nf);
2287         verifyFormatPeriod("bn NUMERIC(Java Locale)", mf, numericDataBn);
2288 
2289         bengali = ULocale.forLanguageTag("bn-u-nu-latn");
2290         nf = NumberFormat.getNumberInstance(bengali);
2291         nf.setMaximumFractionDigits(4);
2292         mf = MeasureFormat.getInstance(bengali, FormatWidth.NUMERIC, nf);
2293         verifyFormatPeriod("bn NUMERIC(Java Locale)", mf, numericDataBnLatn);
2294     }
2295 
verifyFormatPeriod(String desc, MeasureFormat mf, Object[][] testData)2296     private void verifyFormatPeriod(String desc, MeasureFormat mf, Object[][] testData) {
2297         StringBuilder builder = new StringBuilder();
2298         boolean failure = false;
2299         for (Object[] testCase : testData) {
2300             String actual = mf.format(testCase[0]);
2301             if (!testCase[1].equals(actual)) {
2302                 builder.append(String.format("%s: Expected: '%s', got: '%s'\n", desc, testCase[1], actual));
2303                 failure = true;
2304             }
2305         }
2306         if (failure) {
2307             errln(builder.toString());
2308         }
2309     }
2310 
2311     @Test
Test10219FractionalPlurals()2312     public void Test10219FractionalPlurals() {
2313         double[] values = {1.588, 1.011};
2314         String[][] expected = {
2315                 {"1 minute", "1.5 minutes", "1.58 minutes"},
2316                 {"1 minute", "1.0 minutes", "1.01 minutes"}
2317         };
2318         for (int j = 0; j < values.length; j++) {
2319             for (int i = 0; i < expected[j].length; i++) {
2320                 NumberFormat nf = NumberFormat.getNumberInstance(ULocale.ENGLISH);
2321                 nf.setRoundingMode(BigDecimal.ROUND_DOWN);
2322                 nf.setMinimumFractionDigits(i);
2323                 nf.setMaximumFractionDigits(i);
2324                 MeasureFormat mf = MeasureFormat.getInstance(
2325                         ULocale.ENGLISH, FormatWidth.WIDE, nf);
2326                 assertEquals("Test10219", expected[j][i], mf.format(new Measure(values[j], MeasureUnit.MINUTE)));
2327             }
2328         }
2329     }
2330 
2331     @Test
TestGreek()2332     public void TestGreek() {
2333         String[] locales = {"el_GR", "el"};
2334         final MeasureUnit[] units = new MeasureUnit[]{
2335                 MeasureUnit.SECOND,
2336                 MeasureUnit.MINUTE,
2337                 MeasureUnit.HOUR,
2338                 MeasureUnit.DAY,
2339                 MeasureUnit.WEEK,
2340                 MeasureUnit.MONTH,
2341                 MeasureUnit.YEAR};
2342         FormatWidth[] styles = new FormatWidth[] {FormatWidth.WIDE, FormatWidth.SHORT};
2343         int[] numbers = new int[] {1, 7};
2344         String[] expected = {
2345                 // "el_GR" 1 wide
2346                 "1 δευτερόλεπτο",
2347                 "1 λεπτό",
2348                 "1 ώρα",
2349                 "1 ημέρα",
2350                 "1 εβδομάδα",
2351                 "1 μήνας",
2352                 "1 έτος",
2353                 // "el_GR" 1 short
2354                 "1 δευτ.",
2355                 "1 λεπ.",
2356                 "1 ώρα",
2357                 "1 ημέρα",
2358                 "1 εβδ.",
2359                 "1 μήν.",
2360                 "1 έτ.",	        // year (one)
2361                 // "el_GR" 7 wide
2362                 "7 δευτερόλεπτα",
2363                 "7 λεπτά",
2364                 "7 ώρες",
2365                 "7 ημέρες",
2366                 "7 εβδομάδες",
2367                 "7 μήνες",
2368                 "7 έτη",
2369                 // "el_GR" 7 short
2370                 "7 δευτ.",
2371                 "7 λεπ.",
2372                 "7 ώρ.",		    // hour (other)
2373                 "7 ημέρες",
2374                 "7 εβδ.",
2375                 "7 μήν.",
2376                 "7 έτ.",            // year (other)
2377                 // "el" 1 wide
2378                 "1 δευτερόλεπτο",
2379                 "1 λεπτό",
2380                 "1 ώρα",
2381                 "1 ημέρα",
2382                 "1 εβδομάδα",
2383                 "1 μήνας",
2384                 "1 έτος",
2385                 // "el" 1 short
2386                 "1 δευτ.",
2387                 "1 λεπ.",
2388                 "1 ώρα",
2389                 "1 ημέρα",
2390                 "1 εβδ.",
2391                 "1 μήν.",
2392                 "1 έτ.",	        // year (one)
2393                 // "el" 7 wide
2394                 "7 δευτερόλεπτα",
2395                 "7 λεπτά",
2396                 "7 ώρες",
2397                 "7 ημέρες",
2398                 "7 εβδομάδες",
2399                 "7 μήνες",
2400                 "7 έτη",
2401                 // "el" 7 short
2402                 "7 δευτ.",
2403                 "7 λεπ.",
2404                 "7 ώρ.",		    // hour (other)
2405                 "7 ημέρες",
2406                 "7 εβδ.",
2407                 "7 μήν.",
2408                 "7 έτ."};           // year (other
2409         int counter = 0;
2410         String formatted;
2411         for ( int locIndex = 0; locIndex < locales.length; ++locIndex ) {
2412             for( int numIndex = 0; numIndex < numbers.length; ++numIndex ) {
2413                 for ( int styleIndex = 0; styleIndex < styles.length; ++styleIndex ) {
2414                     for ( int unitIndex = 0; unitIndex < units.length; ++unitIndex ) {
2415                         Measure m = new Measure(numbers[numIndex], units[unitIndex]);
2416                         MeasureFormat fmt = MeasureFormat.getInstance(new ULocale(locales[locIndex]), styles[styleIndex]);
2417                         formatted = fmt.format(m);
2418                         assertEquals(
2419                                 "locale: " + locales[locIndex]
2420                                         + ", style: " + styles[styleIndex]
2421                                                 + ", units: " + units[unitIndex]
2422                                                         + ", value: " + numbers[numIndex],
2423                                                 expected[counter], formatted);
2424                         ++counter;
2425                     }
2426                 }
2427             }
2428         }
2429     }
2430 
2431     @Test
testAUnit()2432     public void testAUnit() {
2433         String lastType = null;
2434         for (MeasureUnit expected : MeasureUnit.getAvailable()) {
2435             String type = expected.getType();
2436             String code = expected.getSubtype();
2437             if (!type.equals(lastType)) {
2438                 logln(type);
2439                 lastType = type;
2440             }
2441             MeasureUnit actual = MeasureUnit.internalGetInstance(type, code);
2442             assertSame("Identity check", expected, actual);
2443         }
2444 
2445         // The return value should contain only unique elements
2446         assertUnique(MeasureUnit.getAvailable());
2447     }
2448 
assertUnique(Collection<?> coll)2449     static void assertUnique(Collection<?> coll) {
2450         int expectedSize = new HashSet<>(coll).size();
2451         int actualSize = coll.size();
2452         assertEquals("Collection should contain only unique elements", expectedSize, actualSize);
2453     }
2454 
2455     @Test
testFormatSingleArg()2456     public void testFormatSingleArg() {
2457         MeasureFormat mf = MeasureFormat.getInstance(ULocale.ENGLISH, FormatWidth.WIDE);
2458         assertEquals("", "5 meters", mf.format(new Measure(5, MeasureUnit.METER)));
2459     }
2460 
2461     @Test
testFormatMeasuresZeroArg()2462     public void testFormatMeasuresZeroArg() {
2463         MeasureFormat mf = MeasureFormat.getInstance(ULocale.ENGLISH, FormatWidth.WIDE);
2464         assertEquals("", "", mf.formatMeasures());
2465     }
2466 
2467     @Test
testFormatMeasuresOneArg()2468     public void testFormatMeasuresOneArg() {
2469         MeasureFormat mf = MeasureFormat.getInstance(ULocale.ENGLISH, FormatWidth.WIDE);
2470         assertEquals("", "5 meters", mf.formatMeasures(new Measure(5, MeasureUnit.METER)));
2471     }
2472 
2473 
2474 
2475     @Test
testMultiples()2476     public void testMultiples() {
2477         ULocale russia = new ULocale("ru");
2478         Object[][] data = new Object[][] {
2479                 {ULocale.ENGLISH, FormatWidth.WIDE, "2 miles, 1 foot, 2.3 inches"},
2480                 {ULocale.ENGLISH, FormatWidth.SHORT, "2 mi, 1 ft, 2.3 in"},
2481                 {ULocale.ENGLISH, FormatWidth.NARROW, "2mi 1\u2032 2.3\u2033"},
2482                 {russia, FormatWidth.WIDE,   "2 \u043C\u0438\u043B\u0438 1 \u0444\u0443\u0442 2,3 \u0434\u044E\u0439\u043C\u0430"},
2483                 {russia, FormatWidth.SHORT,  "2 \u043C\u0438 1 \u0444\u0442 2,3 \u0434\u044E\u0439\u043C."},
2484                 {russia, FormatWidth.NARROW, "2 \u043C\u0438\u043B\u044C 1 \u0444\u0442 2,3 \u0434\u044E\u0439\u043C\u0430"},
2485    };
2486         for (Object[] row : data) {
2487             MeasureFormat mf = MeasureFormat.getInstance(
2488                     (ULocale) row[0], (FormatWidth) row[1]);
2489             assertEquals(
2490                     "testMultiples",
2491                     row[2],
2492                     mf.formatMeasures(
2493                             new Measure(2, MeasureUnit.MILE),
2494                             new Measure(1, MeasureUnit.FOOT),
2495                             new Measure(2.3, MeasureUnit.INCH)));
2496         }
2497     }
2498 
2499     @Test
testManyLocaleDurations()2500     public void testManyLocaleDurations() {
2501         Measure hours   = new Measure(5, MeasureUnit.HOUR);
2502         Measure minutes = new Measure(37, MeasureUnit.MINUTE);
2503         ULocale ulocDanish       = new ULocale("da");
2504         ULocale ulocSpanish      = new ULocale("es");
2505         ULocale ulocFinnish      = new ULocale("fi");
2506         ULocale ulocIcelandic    = new ULocale("is");
2507         ULocale ulocNorwegianBok = new ULocale("nb");
2508         ULocale ulocNorwegianNyn = new ULocale("nn");
2509         ULocale ulocDutch        = new ULocale("nl");
2510         ULocale ulocSwedish      = new ULocale("sv");
2511         Object[][] data = new Object[][] {
2512             { ulocDanish,       FormatWidth.NARROW,  "5 t og 37 m" },
2513             { ulocDanish,       FormatWidth.NUMERIC, "5.37" },
2514             { ULocale.GERMAN,   FormatWidth.NARROW,  "5 Std., 37 Min." },
2515             { ULocale.GERMAN,   FormatWidth.NUMERIC, "5:37" },
2516             { ULocale.ENGLISH,  FormatWidth.NARROW,  "5h 37m" },
2517             { ULocale.ENGLISH,  FormatWidth.NUMERIC, "5:37" },
2518             { ulocSpanish,      FormatWidth.NARROW,  "5h 37min" },
2519             { ulocSpanish,      FormatWidth.NUMERIC, "5:37" },
2520             { ulocFinnish,      FormatWidth.NARROW,  "5t 37min" },
2521             { ulocFinnish,      FormatWidth.NUMERIC, "5.37" },
2522             { ULocale.FRENCH,   FormatWidth.NARROW,  "5h 37min" },
2523             { ULocale.FRENCH,   FormatWidth.NUMERIC, "5:37" },
2524             { ulocIcelandic,    FormatWidth.NARROW,  "5 klst. og 37 m\u00EDn." },
2525             { ulocIcelandic,    FormatWidth.NUMERIC, "5:37" },
2526             { ULocale.JAPANESE, FormatWidth.NARROW,  "5h37m" },
2527             { ULocale.JAPANESE, FormatWidth.NUMERIC, "5:37" },
2528             { ulocNorwegianBok, FormatWidth.NARROW,  "5t, 37m" },
2529             { ulocNorwegianBok, FormatWidth.NUMERIC, "5:37" },
2530             { ulocDutch,        FormatWidth.NARROW,  "5 u, 37 m" },
2531             { ulocDutch,        FormatWidth.NUMERIC, "5:37" },
2532             { ulocNorwegianNyn, FormatWidth.NARROW,  "5t 37m" },
2533             { ulocNorwegianNyn, FormatWidth.NUMERIC, "5:37" },
2534             { ulocSwedish,      FormatWidth.NARROW,  "5h 37m" },
2535             { ulocSwedish,      FormatWidth.NUMERIC, "5:37" },
2536             { ULocale.CHINESE,  FormatWidth.NARROW,  "5\u5C0F\u65F637\u5206\u949F" },
2537             { ULocale.CHINESE,  FormatWidth.NUMERIC, "5:37" },
2538         };
2539         for (Object[] row : data) {
2540             MeasureFormat mf = null;
2541             try{
2542                 mf = MeasureFormat.getInstance( (ULocale)row[0], (FormatWidth)row[1] );
2543             } catch(Exception e) {
2544                 errln("Exception creating MeasureFormat for locale " + row[0] + ", width " +
2545                         row[1] + ": " + e);
2546                 continue;
2547             }
2548             String result = mf.formatMeasures(hours, minutes);
2549             if (!result.equals(row[2])) {
2550                 errln("MeasureFormat.formatMeasures for locale " + row[0] + ", width " +
2551                         row[1] + ", expected \"" + (String)row[2] + "\", got \"" + result + "\"" );
2552             }
2553         }
2554     }
2555 
2556     @Test
testSimplePer()2557     public void testSimplePer() {
2558         Object DONT_CARE = null;
2559         Object[][] data = new Object[][] {
2560                 // per unit pattern
2561                 {FormatWidth.WIDE, 1.0, MeasureUnit.SECOND, "1 pound per second", DONT_CARE, 0, 0},
2562                 {FormatWidth.WIDE, 2.0, MeasureUnit.SECOND, "2 pounds per second", DONT_CARE, 0, 0},
2563                 // compound pattern
2564                 {FormatWidth.WIDE, 1.0, MeasureUnit.MINUTE, "1 pound per minute", DONT_CARE, 0, 0},
2565                 {FormatWidth.WIDE, 2.0, MeasureUnit.MINUTE, "2 pounds per minute", DONT_CARE, 0, 0},
2566                 // per unit
2567                 {FormatWidth.SHORT, 1.0, MeasureUnit.SECOND, "1 lb/s", DONT_CARE, 0, 0},
2568                 {FormatWidth.SHORT, 2.0, MeasureUnit.SECOND, "2 lb/s", DONT_CARE, 0, 0},
2569                 // compound
2570                 {FormatWidth.SHORT, 1.0, MeasureUnit.MINUTE, "1 lb/min", DONT_CARE, 0, 0},
2571                 {FormatWidth.SHORT, 2.0, MeasureUnit.MINUTE, "2 lb/min", DONT_CARE, 0, 0},
2572                 // per unit
2573                 {FormatWidth.NARROW, 1.0, MeasureUnit.SECOND, "1#/s", DONT_CARE, 0, 0},
2574                 {FormatWidth.NARROW, 2.0, MeasureUnit.SECOND, "2#/s", DONT_CARE, 0, 0},
2575                 // compound
2576                 {FormatWidth.NARROW, 1.0, MeasureUnit.MINUTE, "1#/min", DONT_CARE, 0, 0},
2577                 {FormatWidth.NARROW, 2.0, MeasureUnit.MINUTE, "2#/min", DONT_CARE, 0, 0},
2578                 // field positions
2579                 {FormatWidth.SHORT, 23.3, MeasureUnit.SECOND, "23.3 lb/s", NumberFormat.Field.DECIMAL_SEPARATOR, 2, 3},
2580                 {FormatWidth.SHORT, 23.3, MeasureUnit.SECOND, "23.3 lb/s", NumberFormat.Field.INTEGER, 0, 2},
2581                 {FormatWidth.SHORT, 23.3, MeasureUnit.MINUTE, "23.3 lb/min", NumberFormat.Field.DECIMAL_SEPARATOR, 2, 3},
2582                 {FormatWidth.SHORT, 23.3, MeasureUnit.MINUTE, "23.3 lb/min", NumberFormat.Field.INTEGER, 0, 2},
2583 
2584         };
2585 
2586         for (Object[] row : data) {
2587             FormatWidth formatWidth = (FormatWidth) row[0];
2588             Number amount = (Number) row[1];
2589             MeasureUnit perUnit = (MeasureUnit) row[2];
2590             String expected = row[3].toString();
2591             NumberFormat.Field field = (NumberFormat.Field) row[4];
2592             int startOffset = ((Integer) row[5]).intValue();
2593             int endOffset = ((Integer) row[6]).intValue();
2594             MeasureFormat mf = MeasureFormat.getInstance(
2595                     ULocale.ENGLISH, formatWidth);
2596             FieldPosition pos = field != null ? new FieldPosition(field) : new FieldPosition(0);
2597             String prefix = "Prefix: ";
2598             assertEquals(
2599                     "",
2600                     prefix + expected,
2601                     mf.formatMeasurePerUnit(
2602                             new Measure(amount, MeasureUnit.POUND),
2603                             perUnit,
2604                             new StringBuilder(prefix),
2605                             pos).toString());
2606             if (field != DONT_CARE) {
2607                 assertEquals("startOffset", startOffset, pos.getBeginIndex() - prefix.length());
2608                 assertEquals("endOffset", endOffset, pos.getEndIndex() - prefix.length());
2609             }
2610         }
2611     }
2612 
2613     @Test
testNumeratorPlurals()2614     public void testNumeratorPlurals() {
2615         ULocale polish = new ULocale("pl");
2616         Object[][] data = new Object[][] {
2617                 {1, "1 stopa na sekundę"},
2618                 {2, "2 stopy na sekundę"},
2619                 {5, "5 stóp na sekundę"},
2620                 {1.5, "1,5 stopy na sekundę"}};
2621 
2622         for (Object[] row : data) {
2623             MeasureFormat mf = MeasureFormat.getInstance(polish, FormatWidth.WIDE);
2624             assertEquals(
2625                     "",
2626                     row[1],
2627                     mf.formatMeasurePerUnit(
2628                             new Measure((Number) row[0], MeasureUnit.FOOT),
2629                             MeasureUnit.SECOND,
2630                             new StringBuilder(),
2631                             new FieldPosition(0)).toString());
2632         }
2633     }
2634 
2635     @Test
testGram()2636     public void testGram() {
2637         MeasureFormat mf = MeasureFormat.getInstance(ULocale.ENGLISH, FormatWidth.SHORT);
2638         assertEquals(
2639                 "testGram",
2640                 "1 g",
2641                 mf.format(new Measure(1, MeasureUnit.GRAM)));
2642         assertEquals(
2643                 "testGram",
2644                 "1 G",
2645                 mf.format(new Measure(1, MeasureUnit.G_FORCE)));
2646     }
2647 
2648     @Test
testCurrencies()2649     public void testCurrencies() {
2650         Measure USD_1 = new Measure(1.0, Currency.getInstance("USD"));
2651         Measure USD_2 = new Measure(2.0, Currency.getInstance("USD"));
2652         Measure USD_NEG_1 = new Measure(-1.0, Currency.getInstance("USD"));
2653         MeasureFormat mf = MeasureFormat.getInstance(ULocale.ENGLISH, FormatWidth.WIDE);
2654         assertEquals("Wide currency", "-1.00 US dollars", mf.format(USD_NEG_1));
2655         assertEquals("Wide currency", "1.00 US dollars", mf.format(USD_1));
2656         assertEquals("Wide currency", "2.00 US dollars", mf.format(USD_2));
2657         mf = MeasureFormat.getInstance(ULocale.ENGLISH, FormatWidth.SHORT);
2658         assertEquals("short currency", "-USD 1.00", mf.format(USD_NEG_1));
2659         assertEquals("short currency", "USD 1.00", mf.format(USD_1));
2660         assertEquals("short currency", "USD 2.00", mf.format(USD_2));
2661         mf = MeasureFormat.getInstance(ULocale.ENGLISH, FormatWidth.NARROW);
2662         assertEquals("narrow currency", "-$1.00", mf.format(USD_NEG_1));
2663         assertEquals("narrow currency", "$1.00", mf.format(USD_1));
2664         assertEquals("narrow currency", "$2.00", mf.format(USD_2));
2665         mf = MeasureFormat.getInstance(ULocale.ENGLISH, FormatWidth.NUMERIC);
2666         assertEquals("numeric currency", "-$1.00", mf.format(USD_NEG_1));
2667         assertEquals("numeric currency", "$1.00", mf.format(USD_1));
2668         assertEquals("numeric currency", "$2.00", mf.format(USD_2));
2669 
2670         mf = MeasureFormat.getInstance(ULocale.JAPAN, FormatWidth.WIDE);
2671         // Locale jp does NOT put a space between the number and the currency long name:
2672         // https://unicode.org/cldr/trac/browser/tags/release-32-0-1/common/main/ja.xml?rev=13805#L7046
2673         assertEquals("Wide currency", "-1.00\u7C73\u30C9\u30EB", mf.format(USD_NEG_1));
2674         assertEquals("Wide currency", "1.00\u7C73\u30C9\u30EB", mf.format(USD_1));
2675         assertEquals("Wide currency", "2.00\u7C73\u30C9\u30EB", mf.format(USD_2));
2676 
2677         Measure CAD_1 = new Measure(1.0, Currency.getInstance("CAD"));
2678         mf = MeasureFormat.getInstance(ULocale.CANADA, FormatWidth.SHORT);
2679         assertEquals("short currency", "CAD 1.00", mf.format(CAD_1));
2680     }
2681 
2682     @Test
testDisplayNames()2683     public void testDisplayNames() {
2684         Object[][] data = new Object[][] {
2685             // Unit, locale, width, expected result
2686             { MeasureUnit.YEAR, "en", FormatWidth.WIDE, "years" },
2687             { MeasureUnit.YEAR, "ja", FormatWidth.WIDE, "年" },
2688             { MeasureUnit.YEAR, "es", FormatWidth.WIDE, "años" },
2689             { MeasureUnit.YEAR, "pt", FormatWidth.WIDE, "anos" },
2690             { MeasureUnit.YEAR, "pt-PT", FormatWidth.WIDE, "anos" },
2691             { MeasureUnit.AMPERE, "en", FormatWidth.WIDE, "amperes" },
2692             { MeasureUnit.AMPERE, "ja", FormatWidth.WIDE, "アンペア" },
2693             { MeasureUnit.AMPERE, "es", FormatWidth.WIDE, "amperios" },
2694             { MeasureUnit.AMPERE, "pt", FormatWidth.WIDE, "amperes" },
2695             { MeasureUnit.AMPERE, "pt-PT", FormatWidth.WIDE, "amperes" },
2696             { MeasureUnit.METER_PER_SECOND_SQUARED, "pt", FormatWidth.WIDE, "metros por segundo ao quadrado" },
2697             { MeasureUnit.METER_PER_SECOND_SQUARED, "pt-PT", FormatWidth.WIDE, "metros por segundo quadrado" },
2698             { MeasureUnit.SQUARE_KILOMETER, "pt", FormatWidth.NARROW, "km²" },
2699             { MeasureUnit.SQUARE_KILOMETER, "pt", FormatWidth.SHORT, "km²" },
2700             { MeasureUnit.SQUARE_KILOMETER, "pt", FormatWidth.WIDE, "quilômetros quadrados" },
2701             { MeasureUnit.SECOND, "pt-PT", FormatWidth.NARROW, "s" },
2702             { MeasureUnit.SECOND, "pt-PT", FormatWidth.SHORT, "s" },
2703             { MeasureUnit.SECOND, "pt-PT", FormatWidth.WIDE, "segundos" },
2704             { MeasureUnit.SECOND, "pt", FormatWidth.NARROW, "seg" },
2705             { MeasureUnit.SECOND, "pt", FormatWidth.SHORT, "seg" },
2706             { MeasureUnit.SECOND, "pt", FormatWidth.WIDE, "segundos" },
2707         };
2708 
2709         for (Object[] test : data) {
2710             MeasureUnit unit = (MeasureUnit) test[0];
2711             ULocale locale = ULocale.forLanguageTag((String) test[1]);
2712             FormatWidth formatWidth = (FormatWidth) test[2];
2713             String expected = (String) test[3];
2714 
2715             MeasureFormat mf = MeasureFormat.getInstance(locale, formatWidth);
2716             String actual = mf.getUnitDisplayName(unit);
2717             assertEquals(String.format("Unit Display Name for %s, %s, %s", unit, locale, formatWidth),
2718                     expected, actual);
2719         }
2720     }
2721 
2722     @Test
testFieldPosition()2723     public void testFieldPosition() {
2724         MeasureFormat fmt = MeasureFormat.getInstance(
2725                 ULocale.ENGLISH, FormatWidth.SHORT);
2726         FieldPosition pos = new FieldPosition(NumberFormat.Field.DECIMAL_SEPARATOR);
2727         fmt.format(new Measure(43.5, MeasureUnit.FOOT), new StringBuffer("123456: "), pos);
2728         assertEquals("beginIndex", 10, pos.getBeginIndex());
2729         assertEquals("endIndex", 11, pos.getEndIndex());
2730 
2731         pos = new FieldPosition(NumberFormat.Field.DECIMAL_SEPARATOR);
2732         fmt.format(new Measure(43, MeasureUnit.FOOT), new StringBuffer(), pos);
2733         assertEquals("beginIndex", 0, pos.getBeginIndex());
2734         assertEquals("endIndex", 0, pos.getEndIndex());
2735     }
2736 
2737     @Test
testFieldPositionMultiple()2738     public void testFieldPositionMultiple() {
2739         MeasureFormat fmt = MeasureFormat.getInstance(
2740                 ULocale.ENGLISH, FormatWidth.SHORT);
2741         FieldPosition pos = new FieldPosition(NumberFormat.Field.INTEGER);
2742         String result = fmt.formatMeasures(
2743                 new StringBuilder(),
2744                 pos,
2745                 new Measure(354, MeasureUnit.METER),
2746                 new Measure(23, MeasureUnit.CENTIMETER)).toString();
2747         assertEquals("result", "354 m, 23 cm", result);
2748 
2749         // According to javadocs for {@link Format#format} FieldPosition is set to
2750         // beginning and end of first such field encountered instead of the last
2751         // such field encountered.
2752         assertEquals("beginIndex", 0, pos.getBeginIndex());
2753         assertEquals("endIndex", 3, pos.getEndIndex());
2754 
2755         pos = new FieldPosition(NumberFormat.Field.DECIMAL_SEPARATOR);
2756         result = fmt.formatMeasures(
2757                 new StringBuilder("123456: "),
2758                 pos,
2759                 new Measure(354, MeasureUnit.METER),
2760                 new Measure(23, MeasureUnit.CENTIMETER),
2761                 new Measure(5.4, MeasureUnit.MILLIMETER)).toString();
2762         assertEquals("result", "123456: 354 m, 23 cm, 5.4 mm", result);
2763         assertEquals("beginIndex", 23, pos.getBeginIndex());
2764         assertEquals("endIndex", 24, pos.getEndIndex());
2765 
2766         result = fmt.formatMeasures(
2767                 new StringBuilder(),
2768                 pos,
2769                 new Measure(3, MeasureUnit.METER),
2770                 new Measure(23, MeasureUnit.CENTIMETER),
2771                 new Measure(5.4, MeasureUnit.MILLIMETER)).toString();
2772         assertEquals("result", "3 m, 23 cm, 5.4 mm", result);
2773         assertEquals("beginIndex", 13, pos.getBeginIndex());
2774         assertEquals("endIndex", 14, pos.getEndIndex());
2775 
2776         pos = new FieldPosition(NumberFormat.Field.DECIMAL_SEPARATOR);
2777         result = fmt.formatMeasures(
2778                 new StringBuilder("123456: "),
2779                 pos,
2780                 new Measure(3, MeasureUnit.METER),
2781                 new Measure(23, MeasureUnit.CENTIMETER),
2782                 new Measure(5, MeasureUnit.MILLIMETER)).toString();
2783         assertEquals("result", "123456: 3 m, 23 cm, 5 mm", result);
2784         assertEquals("beginIndex", 0, pos.getBeginIndex());
2785         assertEquals("endIndex", 0, pos.getEndIndex());
2786 
2787         pos = new FieldPosition(NumberFormat.Field.INTEGER);
2788         result = fmt.formatMeasures(
2789                 new StringBuilder("123456: "),
2790                 pos,
2791                 new Measure(57, MeasureUnit.MILLIMETER)).toString();
2792         assertEquals("result", "123456: 57 mm", result);
2793         assertEquals("beginIndex", 8, pos.getBeginIndex());
2794         assertEquals("endIndex", 10, pos.getEndIndex());
2795 
2796     }
2797 
2798     @Test
testOldFormatWithList()2799     public void testOldFormatWithList() {
2800         List<Measure> measures = new ArrayList<>(2);
2801         measures.add(new Measure(5, MeasureUnit.ACRE));
2802         measures.add(new Measure(3000, MeasureUnit.SQUARE_FOOT));
2803         MeasureFormat fmt = MeasureFormat.getInstance(
2804                 ULocale.ENGLISH, FormatWidth.WIDE);
2805         assertEquals("", "5 acres, 3,000 square feet", fmt.format(measures));
2806         assertEquals("", "5 acres", fmt.format(measures.subList(0, 1)));
2807         List<String> badList = new ArrayList<>();
2808         badList.add("be");
2809         badList.add("you");
2810         try {
2811             fmt.format(badList);
2812             fail("Expected IllegalArgumentException.");
2813         } catch (IllegalArgumentException expected) {
2814            // Expected
2815         }
2816     }
2817 
2818     @Test
testOldFormatWithArray()2819     public void testOldFormatWithArray() {
2820         Measure[] measures = new Measure[] {
2821                 new Measure(5, MeasureUnit.ACRE),
2822                 new Measure(3000, MeasureUnit.SQUARE_FOOT),
2823         };
2824         MeasureFormat fmt = MeasureFormat.getInstance(
2825                 ULocale.ENGLISH, FormatWidth.WIDE);
2826         assertEquals("", "5 acres, 3,000 square feet", fmt.format(measures));
2827     }
2828 
2829     @Test
testOldFormatBadArg()2830     public void testOldFormatBadArg() {
2831         MeasureFormat fmt = MeasureFormat.getInstance(
2832                 ULocale.ENGLISH, FormatWidth.WIDE);
2833         try {
2834             fmt.format("be");
2835             fail("Expected IllegalArgumentExceptino.");
2836         } catch (IllegalArgumentException e) {
2837             // Expected
2838         }
2839     }
2840 
2841     @Test
testUnitPerUnitResolution()2842     public void testUnitPerUnitResolution() {
2843         // Ticket 11274
2844         MeasureFormat fmt = MeasureFormat.getInstance(Locale.ENGLISH, FormatWidth.SHORT);
2845 
2846         // This fails unless we resolve to MeasureUnit.POUND_PER_SQUARE_INCH
2847         assertEquals("", "50 psi",
2848                 fmt.formatMeasurePerUnit(
2849                         new Measure(50, MeasureUnit.POUND_FORCE),
2850                         MeasureUnit.SQUARE_INCH,
2851                         new StringBuilder(),
2852                         new FieldPosition(0)).toString());
2853     }
2854 
2855     @Test
testEqHashCode()2856     public void testEqHashCode() {
2857         MeasureFormat mf = MeasureFormat.getInstance(ULocale.CANADA, FormatWidth.SHORT);
2858         MeasureFormat mfeq = MeasureFormat.getInstance(ULocale.CANADA, FormatWidth.SHORT);
2859         MeasureFormat mfne = MeasureFormat.getInstance(ULocale.CANADA, FormatWidth.WIDE);
2860         MeasureFormat mfne2 = MeasureFormat.getInstance(ULocale.ENGLISH, FormatWidth.SHORT);
2861         verifyEqualsHashCode(mf, mfeq, mfne);
2862         verifyEqualsHashCode(mf, mfeq, mfne2);
2863     }
2864 
2865     @Test
testEqHashCodeOfMeasure()2866     public void testEqHashCodeOfMeasure() {
2867         Measure _3feetDouble = new Measure(3.0, MeasureUnit.FOOT);
2868         Measure _3feetInt = new Measure(3, MeasureUnit.FOOT);
2869         Measure _4feetInt = new Measure(4, MeasureUnit.FOOT);
2870         verifyEqualsHashCode(_3feetDouble, _3feetInt, _4feetInt);
2871     }
2872 
2873     @Test
testGetLocale()2874     public void testGetLocale() {
2875         MeasureFormat mf = MeasureFormat.getInstance(ULocale.GERMAN, FormatWidth.SHORT);
2876         assertEquals("", ULocale.GERMAN, mf.getLocale(ULocale.VALID_LOCALE));
2877     }
2878 
2879     @Test
TestSerial()2880     public void TestSerial() {
2881         checkStreamingEquality(MeasureUnit.CELSIUS);
2882         checkStreamingEquality(MeasureFormat.getInstance(ULocale.FRANCE, FormatWidth.NARROW));
2883         checkStreamingEquality(Currency.getInstance("EUR"));
2884         checkStreamingEquality(MeasureFormat.getInstance(ULocale.GERMAN, FormatWidth.SHORT));
2885         checkStreamingEquality(MeasureFormat.getCurrencyFormat(ULocale.ITALIAN));
2886     }
2887 
2888     @Test
TestSerialFormatWidthEnum()2889     public void TestSerialFormatWidthEnum() {
2890         // FormatWidth enum values must map to the same ordinal values for all time in order for
2891         // serialization to work.
2892         assertEquals("FormatWidth.WIDE", 0, FormatWidth.WIDE.ordinal());
2893         assertEquals("FormatWidth.SHORT", 1, FormatWidth.SHORT.ordinal());
2894         assertEquals("FormatWidth.NARROW", 2, FormatWidth.NARROW.ordinal());
2895         assertEquals("FormatWidth.NUMERIC", 3, FormatWidth.NUMERIC.ordinal());
2896     }
2897 
2898     @Test
testCurrencyFormatStandInForMeasureFormat()2899     public void testCurrencyFormatStandInForMeasureFormat() {
2900         MeasureFormat mf = MeasureFormat.getCurrencyFormat(ULocale.ENGLISH);
2901         assertEquals(
2902                 "70 feet, 5.3 inches",
2903                 "70 feet, 5.3 inches",
2904                 mf.formatMeasures(
2905                         new Measure(70, MeasureUnit.FOOT),
2906                         new Measure(5.3, MeasureUnit.INCH)));
2907         assertEquals("getLocale", ULocale.ENGLISH, mf.getLocale());
2908         assertEquals("getNumberFormat", ULocale.ENGLISH, mf.getNumberFormat().getLocale(ULocale.VALID_LOCALE));
2909         assertEquals("getWidth", MeasureFormat.FormatWidth.WIDE, mf.getWidth());
2910     }
2911 
2912     @Test
testCurrencyFormatLocale()2913     public void testCurrencyFormatLocale() {
2914         MeasureFormat mfu = MeasureFormat.getCurrencyFormat(ULocale.FRANCE);
2915         MeasureFormat mfj = MeasureFormat.getCurrencyFormat(Locale.FRANCE);
2916 
2917         assertEquals("getCurrencyFormat ULocale/Locale", mfu, mfj);
2918     }
2919 
2920     @Test
testCurrencyFormatParseIsoCode()2921     public void testCurrencyFormatParseIsoCode() throws ParseException {
2922         MeasureFormat mf = MeasureFormat.getCurrencyFormat(ULocale.ENGLISH);
2923         CurrencyAmount result = (CurrencyAmount) mf.parseObject("GTQ 34.56");
2924         assertEquals("Parse should succeed", result.getNumber().doubleValue(), 34.56, 0.0);
2925         assertEquals("Should parse ISO code GTQ even though the currency is USD",
2926                 "GTQ", result.getCurrency().getCurrencyCode());
2927     }
2928 
2929     @Test
testDoubleZero()2930     public void testDoubleZero() {
2931         ULocale en = new ULocale("en");
2932         NumberFormat nf = NumberFormat.getInstance(en);
2933         nf.setMinimumFractionDigits(2);
2934         nf.setMaximumFractionDigits(2);
2935         MeasureFormat mf = MeasureFormat.getInstance(en, FormatWidth.WIDE, nf);
2936         assertEquals(
2937                 "Positive Rounding",
2938                 "4 hours, 23 minutes, 16.00 seconds",
2939                 mf.formatMeasures(
2940                         new Measure(4.7, MeasureUnit.HOUR),
2941                         new Measure(23, MeasureUnit.MINUTE),
2942                         new Measure(16, MeasureUnit.SECOND)));
2943         assertEquals(
2944                 "Negative Rounding",
2945                 "-4 hours, 23 minutes, 16.00 seconds",
2946                 mf.formatMeasures(
2947                         new Measure(-4.7, MeasureUnit.HOUR),
2948                         new Measure(23, MeasureUnit.MINUTE),
2949                         new Measure(16, MeasureUnit.SECOND)));
2950 
2951     }
2952 
2953     @Test
testIndividualPluralFallback()2954     public void testIndividualPluralFallback() {
2955         // See ticket #11986 "incomplete fallback in MeasureFormat".
2956         // In CLDR 28, fr_CA temperature-generic/short has only the "one" form,
2957         // and falls back to fr for the "other" form.
2958         MeasureFormat mf = MeasureFormat.getInstance(new ULocale("fr_CA"), FormatWidth.SHORT);
2959         Measure twoDeg = new Measure(2, MeasureUnit.GENERIC_TEMPERATURE);
2960         assertEquals("2 deg temp in fr_CA", "2°", mf.format(twoDeg));
2961     }
2962 
2963     @Test
testPopulateCache()2964     public void testPopulateCache() {
2965         // Quick check that the lazily added additions to the MeasureUnit cache are present.
2966         assertTrue("MeasureUnit: unexpectedly few currencies defined", MeasureUnit.getAvailable("currency").size() > 50);
2967     }
2968 
2969     @Test
testParseObject()2970     public void testParseObject() {
2971         MeasureFormat mf = MeasureFormat.getInstance(Locale.GERMAN, FormatWidth.NARROW);
2972         try {
2973             mf.parseObject("3m", null);
2974             fail("MeasureFormat.parseObject(String, ParsePosition) " +
2975                     "should throw an UnsupportedOperationException");
2976         } catch (UnsupportedOperationException expected) {
2977         }
2978     }
2979 
2980     @Test
testCLDRUnitAvailability()2981     public void testCLDRUnitAvailability() {
2982         Set<MeasureUnit> knownUnits = new HashSet<>();
2983         Class cMeasureUnit, cTimeUnit;
2984         try {
2985             cMeasureUnit = Class.forName("com.ibm.icu.util.MeasureUnit");
2986             cTimeUnit = Class.forName("com.ibm.icu.util.TimeUnit");
2987         } catch (ClassNotFoundException e) {
2988             fail("Count not load MeasureUnit or TimeUnit class: " + e.getMessage());
2989             return;
2990         }
2991         for (Field field : cMeasureUnit.getFields()) {
2992             if (field.getGenericType() == cMeasureUnit || field.getGenericType() == cTimeUnit) {
2993                 try {
2994                     MeasureUnit unit = (MeasureUnit) field.get(cMeasureUnit);
2995                     knownUnits.add(unit);
2996                 } catch (IllegalArgumentException e) {
2997                     fail(e.getMessage());
2998                     return;
2999                 } catch (IllegalAccessException e) {
3000                     fail(e.getMessage());
3001                     return;
3002                 }
3003             }
3004         }
3005         for (String type : MeasureUnit.getAvailableTypes()) {
3006             if (type.equals("currency")
3007                     || type.equals("compound")
3008                     || type.equals("coordinate")
3009                     || type.equals("none")) {
3010                 continue;
3011             }
3012             for (MeasureUnit unit : MeasureUnit.getAvailable(type)) {
3013                 if (!knownUnits.contains(unit)) {
3014                     fail("Unit present in CLDR but not available via constant in MeasureUnit: " + unit);
3015                 }
3016             }
3017         }
3018     }
3019 
3020     @Test
testBug11966()3021     public void testBug11966() {
3022         Locale locale = new Locale("en", "AU");
3023         MeasureFormat.getInstance(locale, MeasureFormat.FormatWidth.WIDE);
3024         // Should not throw an exception.
3025     }
3026 
3027     @Test
test20332_PersonUnits()3028     public void test20332_PersonUnits() {
3029         Object[][] cases = new Object[][] {
3030             {ULocale.US, MeasureUnit.YEAR_PERSON, MeasureFormat.FormatWidth.NARROW, "25y"},
3031             {ULocale.US, MeasureUnit.YEAR_PERSON, MeasureFormat.FormatWidth.SHORT, "25 yrs"},
3032             {ULocale.US, MeasureUnit.YEAR_PERSON, MeasureFormat.FormatWidth.WIDE, "25 years"},
3033             {ULocale.US, MeasureUnit.MONTH_PERSON, MeasureFormat.FormatWidth.NARROW, "25m"},
3034             {ULocale.US, MeasureUnit.MONTH_PERSON, MeasureFormat.FormatWidth.SHORT, "25 mths"},
3035             {ULocale.US, MeasureUnit.MONTH_PERSON, MeasureFormat.FormatWidth.WIDE, "25 months"},
3036             {ULocale.US, MeasureUnit.WEEK_PERSON, MeasureFormat.FormatWidth.NARROW, "25w"},
3037             {ULocale.US, MeasureUnit.WEEK_PERSON, MeasureFormat.FormatWidth.SHORT, "25 wks"},
3038             {ULocale.US, MeasureUnit.WEEK_PERSON, MeasureFormat.FormatWidth.WIDE, "25 weeks"},
3039             {ULocale.US, MeasureUnit.DAY_PERSON, MeasureFormat.FormatWidth.NARROW, "25d"},
3040             {ULocale.US, MeasureUnit.DAY_PERSON, MeasureFormat.FormatWidth.SHORT, "25 days"},
3041             {ULocale.US, MeasureUnit.DAY_PERSON, MeasureFormat.FormatWidth.WIDE, "25 days"}
3042         };
3043         for (Object[] cas : cases) {
3044             ULocale locale = (ULocale) cas[0];
3045             MeasureUnit unit = (MeasureUnit) cas[1];
3046             MeasureFormat.FormatWidth width = (MeasureFormat.FormatWidth) cas[2];
3047             String expected = (String) cas[3];
3048 
3049             MeasureFormat fmt = MeasureFormat.getInstance(locale, width);
3050             String result = fmt.formatMeasures(new Measure(25, unit));
3051             assertEquals("" + locale + " " + unit + " " + width, expected, result);
3052         }
3053     }
3054 
3055     // DO NOT DELETE THIS FUNCTION! It may appear as dead code, but we use this to generate code
3056     // for MeasureFormat during the release process.
getUnitsToPerParts()3057     static Map<MeasureUnit, Pair<MeasureUnit, MeasureUnit>> getUnitsToPerParts() {
3058         TreeMap<String, List<MeasureUnit>> allUnits = getAllUnits();
3059         Map<MeasureUnit, Pair<String, String>> unitsToPerStrings =
3060                 new HashMap<>();
3061         Map<String, MeasureUnit> namesToUnits = new HashMap<>();
3062         for (Map.Entry<String, List<MeasureUnit>> entry : allUnits.entrySet()) {
3063             String type = entry.getKey();
3064             // Currency types are always atomic units, so we can skip these
3065             if (type.equals("currency")) {
3066                 continue;
3067             }
3068             for (MeasureUnit unit : entry.getValue()) {
3069                 String javaName = toJAVAName(unit);
3070                 String[] nameParts = javaName.split("_PER_");
3071                 if (nameParts.length == 1) {
3072                     namesToUnits.put(nameParts[0], unit);
3073                 } else if (nameParts.length == 2) {
3074                     unitsToPerStrings.put(unit, Pair.of(nameParts[0], nameParts[1]));
3075                 }
3076             }
3077         }
3078         Map<MeasureUnit, Pair<MeasureUnit, MeasureUnit>> unitsToPerUnits =
3079                 new HashMap<>();
3080         for (Map.Entry<MeasureUnit, Pair<String, String>> entry : unitsToPerStrings.entrySet()) {
3081             Pair<String, String> perStrings = entry.getValue();
3082             MeasureUnit unit = namesToUnits.get(perStrings.first);
3083             MeasureUnit perUnit = namesToUnits.get(perStrings.second);
3084             if (unit != null && perUnit != null) {
3085                 unitsToPerUnits.put(entry.getKey(), Pair.of(unit, perUnit));
3086             }
3087         }
3088         return unitsToPerUnits;
3089     }
3090 
3091     // DO NOT DELETE THIS FUNCTION! It may appear as dead code, but we use this to generate code
3092     // for MeasureFormat during the release process.
generateCXXHConstants(String thisVersion)3093     static void generateCXXHConstants(String thisVersion) {
3094         Map<String, MeasureUnit> seen = new HashMap<>();
3095         System.out.println("// Start generated createXXX methods");
3096         System.out.println();
3097         TreeMap<String, List<MeasureUnit>> allUnits = getAllUnits();
3098         for (Map.Entry<String, List<MeasureUnit>> entry : allUnits.entrySet()) {
3099             String type = entry.getKey();
3100             if (type.equals("currency")) {
3101                 continue;
3102             }
3103             for (MeasureUnit unit : entry.getValue()) {
3104                 String code = unit.getSubtype();
3105                 String name = toCamelCase(unit);
3106                 String javaName = toJAVAName(unit);
3107                 checkForDup(seen, name, unit);
3108                 if (isDraft(javaName)) {
3109                     System.out.println("#ifndef U_HIDE_DRAFT_API");
3110                 }
3111                 System.out.println("    /**");
3112                 System.out.println("     * Returns by pointer, unit of " + type + ": " + code + ".");
3113                 System.out.println("     * Caller owns returned value and must free it.");
3114                 System.out.printf("     * Also see {@link #get%s()}.\n", name);
3115                 System.out.println("     * @param status ICU error code.");
3116                 if (isDraft(javaName)) {
3117                     System.out.println("     * @draft ICU " + getVersion(javaName, thisVersion));
3118                 } else {
3119                     System.out.println("     * @stable ICU " + getVersion(javaName, thisVersion));
3120                 }
3121                 System.out.println("     */");
3122                 System.out.printf("    static MeasureUnit *create%s(UErrorCode &status);\n", name);
3123                 System.out.println();
3124                 System.out.println("    /**");
3125                 System.out.println("     * Returns by value, unit of " + type + ": " + code + ".");
3126                 System.out.printf("     * Also see {@link #create%s()}.\n", name);
3127                 String getterVersion = getVersion(javaName, thisVersion);
3128                 if (Integer.valueOf(getterVersion) < 64) {
3129                     getterVersion = "64";
3130                 }
3131                 if (isDraft(javaName)) {
3132                     System.out.println("     * @draft ICU " + getterVersion);
3133                 } else {
3134                     System.out.println("     * @stable ICU " + getterVersion);
3135                 }
3136                 System.out.println("     */");
3137                 System.out.printf("    static MeasureUnit get%s();\n", name);
3138                 if (isDraft(javaName)) {
3139                     System.out.println("#endif /* U_HIDE_DRAFT_API */");
3140                 }
3141                 System.out.println("");
3142             }
3143         }
3144         System.out.println("// End generated createXXX methods");
3145     }
3146 
checkForDup( Map<String, MeasureUnit> seen, String name, MeasureUnit unit)3147     private static void checkForDup(
3148             Map<String, MeasureUnit> seen, String name, MeasureUnit unit) {
3149         if (seen.containsKey(name)) {
3150             throw new RuntimeException("\nCollision!!" + unit + ", " + seen.get(name));
3151         } else {
3152             seen.put(name, unit);
3153         }
3154     }
3155 
3156     // DO NOT DELETE THIS FUNCTION! It may appear as dead code, but we use this to generate code
3157     // for MeasureFormat during the release process.
updateJAVAVersions(String thisVersion)3158     static void updateJAVAVersions(String thisVersion) {
3159         System.out.println();
3160         Map<String, MeasureUnit> seen = new HashMap<>();
3161         TreeMap<String, List<MeasureUnit>> allUnits = getAllUnits();
3162         for (Map.Entry<String, List<MeasureUnit>> entry : allUnits.entrySet()) {
3163             String type = entry.getKey();
3164             if (type.equals("currency")) {
3165                 continue;
3166             }
3167             for (MeasureUnit unit : entry.getValue()) {
3168                 String javaName = toJAVAName(unit);
3169                 checkForDup(seen, javaName, unit);
3170                 if (!JAVA_VERSION_MAP.containsKey(javaName)) {
3171                     System.out.printf("        {\"%s\", \"%s\"},\n", javaName, thisVersion);
3172                 }
3173             }
3174         }
3175     }
3176 
getAllUnits()3177     static TreeMap<String, List<MeasureUnit>> getAllUnits() {
3178         TreeMap<String, List<MeasureUnit>> allUnits = new TreeMap<>();
3179         for (String type : MeasureUnit.getAvailableTypes()) {
3180             ArrayList<MeasureUnit> units = new ArrayList<>(MeasureUnit.getAvailable(type));
3181             Collections.sort(
3182                     units,
3183                     new Comparator<MeasureUnit>() {
3184 
3185                         @Override
3186                         public int compare(MeasureUnit o1, MeasureUnit o2) {
3187                             return o1.getSubtype().compareTo(o2.getSubtype());
3188                         }
3189 
3190                     });
3191             allUnits.put(type, units);
3192         }
3193         return allUnits;
3194     }
3195 
3196     // DO NOT DELETE THIS FUNCTION! It may appear as dead code, but we use this to generate code
3197     // for MeasureFormat during the release process.
generateCXXConstants()3198     static void generateCXXConstants() {
3199         System.out.println("// Start generated code for measunit.cpp");
3200         System.out.println("");
3201         TreeMap<String, List<MeasureUnit>> allUnits = getAllUnits();
3202 
3203         // Hack: for C++, add base unit here, but ignore them when printing the create methods.
3204         // Also keep track of the base unit offset to make the C++ default constructor faster.
3205         allUnits.put("none", Arrays.asList(new MeasureUnit[] {NoUnit.BASE}));
3206         int baseTypeIdx = -1;
3207         int baseSubTypeIdx = -1;
3208 
3209         System.out.println("// Maps from Type ID to offset in gSubTypes.");
3210         System.out.println("static const int32_t gOffsets[] = {");
3211         int index = 0;
3212         int typeCount = 0;
3213         int currencyIndex = -1;
3214         for (Map.Entry<String, List<MeasureUnit>> entry : allUnits.entrySet()) {
3215             System.out.printf("    %d,\n", index);
3216             if (entry.getKey() == "currency") {
3217                 currencyIndex = typeCount;
3218             }
3219             typeCount++;
3220             index += entry.getValue().size();
3221         }
3222         assertTrue("currency present", currencyIndex >= 0);
3223         System.out.printf("    %d\n", index);
3224         System.out.println("};");
3225         System.out.println();
3226         System.out.println("static const int32_t kCurrencyOffset = " + currencyIndex + ";");
3227         System.out.println();
3228         System.out.println("// Must be sorted alphabetically.");
3229         System.out.println("static const char * const gTypes[] = {");
3230         boolean first = true;
3231         for (Map.Entry<String, List<MeasureUnit>> entry : allUnits.entrySet()) {
3232             if (!first) {
3233                 System.out.println(",");
3234             }
3235             System.out.print("    \"" + entry.getKey() + "\"");
3236             first = false;
3237         }
3238         System.out.println();
3239         System.out.println("};");
3240         System.out.println();
3241         System.out.println("// Must be grouped by type and sorted alphabetically within each type.");
3242         System.out.println("static const char * const gSubTypes[] = {");
3243         first = true;
3244         int offset = 0;
3245         int typeIdx = 0;
3246         Map<MeasureUnit, Integer> measureUnitToOffset = new HashMap<>();
3247         Map<MeasureUnit, Pair<Integer, Integer>> measureUnitToTypeSubType =
3248                 new HashMap<>();
3249         for (Map.Entry<String, List<MeasureUnit>> entry : allUnits.entrySet()) {
3250             int subTypeIdx = 0;
3251             for (MeasureUnit unit : entry.getValue()) {
3252                 if (!first) {
3253                     System.out.println(",");
3254                 }
3255                 if (unit != null) {
3256                     System.out.print("    \"" + unit.getSubtype() + "\"");
3257                 } else {
3258                     assertEquals("unit only null for \"none\" type", "none", entry.getKey());
3259                     System.out.print("    \"\"");
3260                 }
3261                 first = false;
3262                 measureUnitToOffset.put(unit, offset);
3263                 measureUnitToTypeSubType.put(unit, Pair.of(typeIdx, subTypeIdx));
3264                 if (unit == NoUnit.BASE) {
3265                     baseTypeIdx = typeIdx;
3266                     baseSubTypeIdx = subTypeIdx;
3267                 }
3268                 offset++;
3269                 subTypeIdx++;
3270             }
3271             typeIdx++;
3272         }
3273         System.out.println();
3274         System.out.println("};");
3275         System.out.println();
3276 
3277         // Build unit per unit offsets to corresponding type sub types sorted by
3278         // unit first and then per unit.
3279         TreeMap<OrderedPair<Integer, Integer>, Pair<Integer, Integer>> unitPerUnitOffsetsToTypeSubType
3280                 = new TreeMap<>();
3281         for (Map.Entry<MeasureUnit, Pair<MeasureUnit, MeasureUnit>> entry
3282                 : getUnitsToPerParts().entrySet()) {
3283             Pair<MeasureUnit, MeasureUnit> unitPerUnit = entry.getValue();
3284             unitPerUnitOffsetsToTypeSubType.put(
3285                     OrderedPair.of(
3286                             measureUnitToOffset.get(unitPerUnit.first),
3287                             measureUnitToOffset.get(unitPerUnit.second)),
3288                     measureUnitToTypeSubType.get(entry.getKey()));
3289         }
3290 
3291         // Print out the fast-path for the default constructor
3292         System.out.println("// Shortcuts to the base unit in order to make the default constructor fast");
3293         System.out.println("static const int32_t kBaseTypeIdx = " + baseTypeIdx + ";");
3294         System.out.println("static const int32_t kBaseSubTypeIdx = " + baseSubTypeIdx + ";");
3295         System.out.println();
3296 
3297         Map<String, MeasureUnit> seen = new HashMap<>();
3298         for (Map.Entry<String, List<MeasureUnit>> entry : allUnits.entrySet()) {
3299 
3300             String type = entry.getKey();
3301             if (type.equals("currency") || type.equals("none")) {
3302                 continue;
3303             }
3304             for (MeasureUnit unit : entry.getValue()) {
3305                 String name = toCamelCase(unit);
3306                 Pair<Integer, Integer> typeSubType = measureUnitToTypeSubType.get(unit);
3307                 if (typeSubType == null) {
3308                     throw new IllegalStateException();
3309                 }
3310                 checkForDup(seen, name, unit);
3311                 System.out.printf("MeasureUnit *MeasureUnit::create%s(UErrorCode &status) {\n", name);
3312                 System.out.printf("    return MeasureUnit::create(%d, %d, status);\n",
3313                         typeSubType.first, typeSubType.second);
3314                 System.out.println("}");
3315                 System.out.println();
3316                 System.out.printf("MeasureUnit MeasureUnit::get%s() {\n", name);
3317                 System.out.printf("    return MeasureUnit(%d, %d);\n",
3318                         typeSubType.first, typeSubType.second);
3319                 System.out.println("}");
3320                 System.out.println();
3321             }
3322         }
3323         System.out.println("// End generated code for measunit.cpp");
3324     }
3325 
toCamelCase(MeasureUnit unit)3326     private static String toCamelCase(MeasureUnit unit) {
3327         StringBuilder result = new StringBuilder();
3328         boolean caps = true;
3329         String code = unit.getSubtype();
3330 
3331         String replacement = CLDR_NAME_REMAP.get(code);
3332         if (replacement != null) {
3333             code = replacement;
3334         }
3335 
3336         int len = code.length();
3337         for (int i = 0; i < len; i++) {
3338             char ch = code.charAt(i);
3339             if (ch == '-') {
3340                 caps = true;
3341             } else if (Character.isDigit(ch)) {
3342                 caps = true;
3343                 result.append(ch);
3344             } else if (caps) {
3345                 result.append(Character.toUpperCase(ch));
3346                 caps = false;
3347             } else {
3348                 result.append(ch);
3349             }
3350         }
3351         return result.toString();
3352     }
3353 
isTypeHidden(String type)3354     static boolean isTypeHidden(String type) {
3355         return "currency".equals(type);
3356     }
3357 
3358     // DO NOT DELETE THIS FUNCTION! It may appear as dead code, but we use this to generate code
3359     // for MeasureFormat during the release process.
generateBackwardCompatibilityTest(String version)3360     static void generateBackwardCompatibilityTest(String version) {
3361         Map<String, MeasureUnit> seen = new HashMap<>();
3362         System.out.println();
3363         System.out.printf("    public void TestCompatible%s() {\n", version.replace(".", "_"));
3364         System.out.println("        MeasureUnit[] units = {");
3365         TreeMap<String, List<MeasureUnit>> allUnits = getAllUnits();
3366         int count = 0;
3367         for (Map.Entry<String, List<MeasureUnit>> entry : allUnits.entrySet()) {
3368             if (isTypeHidden(entry.getKey())) {
3369                 continue;
3370             }
3371             for (MeasureUnit unit : entry.getValue()) {
3372                 String javaName = toJAVAName(unit);
3373                 checkForDup(seen, javaName, unit);
3374                 System.out.printf("                MeasureUnit.%s,\n", javaName);
3375                 count++;
3376             }
3377         }
3378         System.out.println("        };");
3379         System.out.printf("        assertEquals(\"\",  %d, units.length);\n", count);
3380         System.out.println("    }");
3381     }
3382 
3383     // DO NOT DELETE THIS FUNCTION! It may appear as dead code, but we use this to generate code
3384     // for MeasureFormat during the release process.
generateCXXBackwardCompatibilityTest(String version)3385     static void generateCXXBackwardCompatibilityTest(String version) {
3386         System.out.println();
3387         Map<String, MeasureUnit> seen = new HashMap<>();
3388         System.out.printf("void MeasureFormatTest::TestCompatible%s() {\n", version.replace(".", "_"));
3389         System.out.println("    UErrorCode status = U_ZERO_ERROR;");
3390         System.out.println("    LocalPointer<MeasureUnit> measureUnit;");
3391         System.out.println("    MeasureUnit measureUnitValue;");
3392         TreeMap<String, List<MeasureUnit>> allUnits = getAllUnits();
3393         for (Map.Entry<String, List<MeasureUnit>> entry : allUnits.entrySet()) {
3394             if (isTypeHidden(entry.getKey())) {
3395                 continue;
3396             }
3397             for (MeasureUnit unit : entry.getValue()) {
3398                 String camelCase = toCamelCase(unit);
3399                 checkForDup(seen, camelCase, unit);
3400                 System.out.printf("    measureUnit.adoptInstead(MeasureUnit::create%s(status));\n", camelCase);
3401                 System.out.printf("    measureUnitValue = MeasureUnit::get%s();\n", camelCase);
3402             }
3403         }
3404         System.out.println("    assertSuccess(\"\", status);");
3405         System.out.println("}");
3406     }
3407 
toJAVAName(MeasureUnit unit)3408     static String toJAVAName(MeasureUnit unit) {
3409         String code = unit.getSubtype();
3410         String type = unit.getType();
3411 
3412         String replacement = CLDR_NAME_REMAP.get(code);
3413          if (replacement != null) {
3414             code = replacement;
3415         }
3416 
3417         String name = code.toUpperCase(Locale.ENGLISH).replace("-", "_");
3418         if (type.equals("angle")) {
3419             if (code.equals("minute") || code.equals("second")) {
3420                 name = "ARC_" + name;
3421             }
3422         }
3423         return name;
3424     }
3425 
3426     // DO NOT DELETE THIS FUNCTION! It may appear as dead code, but we use this to generate code
3427     // for MeasureFormat during the release process.
generateConstants(String thisVersion)3428     static void generateConstants(String thisVersion) {
3429         System.out.println("    // Start generated MeasureUnit constants");
3430         System.out.println();
3431         Map<String, MeasureUnit> seen = new HashMap<>();
3432         TreeMap<String, List<MeasureUnit>> allUnits = getAllUnits();
3433         for (Map.Entry<String, List<MeasureUnit>> entry : allUnits.entrySet()) {
3434             String type = entry.getKey();
3435             if (isTypeHidden(type)) {
3436                 continue;
3437             }
3438             for (MeasureUnit unit : entry.getValue()) {
3439                 String name = toJAVAName(unit);
3440                 String code = unit.getSubtype();
3441                 checkForDup(seen, name, unit);
3442                 System.out.println("    /**");
3443                 System.out.println("     * Constant for unit of " + type +
3444                         ": " +
3445                         code);
3446                 // Special case JAVA had old constants for time from before.
3447                 if ("duration".equals(type) && TIME_CODES.contains(code)) {
3448                     System.out.println("     * @stable ICU 4.0");
3449                 }
3450                 else if (isDraft(name)) {
3451                     System.out.println("     * @draft ICU " + getVersion(name, thisVersion));
3452                 } else {
3453                     System.out.println("     * @stable ICU " + getVersion(name, thisVersion));
3454                 }
3455                 System.out.println("     */");
3456                 if ("duration".equals(type) && TIME_CODES.contains(code)) {
3457                     System.out.println("    public static final TimeUnit " + name + " = (TimeUnit) MeasureUnit.internalGetInstance(\"" +
3458                             type +
3459                             "\", \"" +
3460                             code +
3461                             "\");");
3462                 } else {
3463                     System.out.println("    public static final MeasureUnit " + name + " = MeasureUnit.internalGetInstance(\"" +
3464                             type +
3465                             "\", \"" +
3466                             code +
3467                             "\");");
3468                 }
3469                 System.out.println();
3470             }
3471         }
3472         System.out.println("    // End generated MeasureUnit constants");
3473     }
3474 
getVersion(String javaName, String thisVersion)3475     private static String getVersion(String javaName, String thisVersion) {
3476         String version = JAVA_VERSION_MAP.get(javaName);
3477         if (version == null) {
3478             return thisVersion;
3479         }
3480         return version;
3481     }
3482 
isDraft(String javaName)3483     private static boolean isDraft(String javaName) {
3484         String version = JAVA_VERSION_MAP.get(javaName);
3485         if (version == null) {
3486             return true;
3487         }
3488         return DRAFT_VERSION_SET.contains(version);
3489     }
3490 
checkStreamingEquality(T item)3491     public <T extends Serializable> void checkStreamingEquality(T item) {
3492         try {
3493           ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
3494           ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteOut);
3495           objectOutputStream.writeObject(item);
3496           objectOutputStream.close();
3497           byte[] contents = byteOut.toByteArray();
3498           logln("bytes: " + contents.length + "; " + item.getClass() + ": " + showBytes(contents));
3499           ByteArrayInputStream byteIn = new ByteArrayInputStream(contents);
3500           ObjectInputStream objectInputStream = new ObjectInputStream(byteIn);
3501           Object obj = objectInputStream.readObject();
3502           assertEquals("Streamed Object equals ", item, obj);
3503         } catch (IOException e) {
3504           e.printStackTrace();
3505           assertNull("Test Serialization " + item.getClass(), e);
3506         } catch (ClassNotFoundException e) {
3507           assertNull("Test Serialization " + item.getClass(), e);
3508         }
3509       }
3510 
3511     /**
3512      * @param contents
3513      * @return
3514      */
showBytes(byte[] contents)3515     private String showBytes(byte[] contents) {
3516       StringBuilder b = new StringBuilder("[");
3517       for (int i = 0; i < contents.length; ++i) {
3518         int item = contents[i] & 0xFF;
3519         if (item >= 0x20 && item <= 0x7F) {
3520           b.append((char) item);
3521         } else {
3522           b.append('(').append(Utility.hex(item, 2)).append(')');
3523         }
3524       }
3525       return b.append(']').toString();
3526     }
3527 
verifyEqualsHashCode(Object o, Object eq, Object ne)3528     private void verifyEqualsHashCode(Object o, Object eq, Object ne) {
3529         assertEquals("verifyEqualsHashCodeSame", o, o);
3530         assertEquals("verifyEqualsHashCodeEq", o, eq);
3531         assertNotEquals("verifyEqualsHashCodeNe", o, ne);
3532         assertNotEquals("verifyEqualsHashCodeEqTrans", eq, ne);
3533         assertEquals("verifyEqualsHashCodeHashEq", o.hashCode(), eq.hashCode());
3534 
3535         // May be a flaky test, but generally should be true.
3536         // May need to comment this out later.
3537         assertNotEquals("verifyEqualsHashCodeHashNe", o.hashCode(), ne.hashCode());
3538     }
3539 
3540     public static class MeasureUnitHandler implements SerializableTestUtility.Handler
3541     {
3542         @Override
getTestObjects()3543         public Object[] getTestObjects()
3544         {
3545             MeasureUnit items[] = {
3546                     MeasureUnit.CELSIUS,
3547                     Currency.getInstance("EUR")
3548             };
3549             return items;
3550         }
3551         @Override
hasSameBehavior(Object a, Object b)3552         public boolean hasSameBehavior(Object a, Object b)
3553         {
3554             MeasureUnit a1 = (MeasureUnit) a;
3555             MeasureUnit b1 = (MeasureUnit) b;
3556             return a1.getType().equals(b1.getType())
3557                     && a1.getSubtype().equals(b1.getSubtype());
3558         }
3559     }
3560 
3561     public static class MeasureFormatHandler  implements SerializableTestUtility.Handler
3562     {
3563         FormatHandler.NumberFormatHandler nfh = new FormatHandler.NumberFormatHandler();
3564 
3565         @Override
getTestObjects()3566         public Object[] getTestObjects()
3567         {
3568             MeasureFormat items[] = {
3569                     MeasureFormat.getInstance(ULocale.FRANCE, FormatWidth.SHORT),
3570                     MeasureFormat.getInstance(
3571                             ULocale.FRANCE,
3572                             FormatWidth.WIDE,
3573                             NumberFormat.getIntegerInstance(ULocale.CANADA_FRENCH)),
3574             };
3575             return items;
3576         }
3577         @Override
hasSameBehavior(Object a, Object b)3578         public boolean hasSameBehavior(Object a, Object b)
3579         {
3580             MeasureFormat a1 = (MeasureFormat) a;
3581             MeasureFormat b1 = (MeasureFormat) b;
3582             boolean getLocaleEqual = a1.getLocale().equals(b1.getLocale());
3583             boolean getWidthEqual = a1.getWidth().equals(b1.getWidth());
3584             boolean numFmtHasSameBehavior = nfh.hasSameBehavior(a1.getNumberFormat(), b1.getNumberFormat());
3585             if (getLocaleEqual && getWidthEqual && numFmtHasSameBehavior) {
3586                 return true;
3587             }
3588             System.out.println("MeasureFormatHandler.hasSameBehavior fails:");
3589             if (!getLocaleEqual) {
3590                 System.out.println("- getLocale equality fails: old a1: " + a1.getLocale().getName() + "; test b1: " + b1.getLocale().getName());
3591             }
3592             if (!getWidthEqual) {
3593                 System.out.println("- getWidth equality fails: old a1: " + a1.getWidth().name() + "; test b1: " + b1.getWidth().name());
3594             }
3595             if (!numFmtHasSameBehavior) {
3596                 System.out.println("- getNumberFormat hasSameBehavior fails");
3597             }
3598             return false;
3599         }
3600     }
3601 
3602     @Test
TestNumericTimeNonLatin()3603     public void TestNumericTimeNonLatin() {
3604         ULocale ulocale = ULocale.forLanguageTag("bn");
3605         MeasureFormat fmt = MeasureFormat.getInstance(ulocale, FormatWidth.NUMERIC);
3606         String actual = fmt.formatMeasures(new Measure(12, MeasureUnit.MINUTE), new Measure(39.12345, MeasureUnit.SECOND));
3607         assertEquals("Incorect digits", "১২:৩৯.১২৩", actual);
3608     }
3609 
3610     @Test
TestNumericTime()3611     public void TestNumericTime() {
3612         MeasureFormat fmt = MeasureFormat.getInstance(ULocale.forLanguageTag("en"), FormatWidth.NUMERIC);
3613 
3614         Measure hours = new Measure(112, MeasureUnit.HOUR);
3615         Measure minutes = new Measure(113, MeasureUnit.MINUTE);
3616         Measure seconds = new Measure(114, MeasureUnit.SECOND);
3617         Measure fhours = new Measure(112.8765, MeasureUnit.HOUR);
3618         Measure fminutes = new Measure(113.8765, MeasureUnit.MINUTE);
3619         Measure fseconds = new Measure(114.8765, MeasureUnit.SECOND);
3620 
3621         Assert.assertEquals("112h", fmt.formatMeasures(hours));
3622         Assert.assertEquals("113m", fmt.formatMeasures(minutes));
3623         Assert.assertEquals("114s", fmt.formatMeasures(seconds));
3624 
3625         Assert.assertEquals("112.876h", fmt.formatMeasures(fhours));
3626         Assert.assertEquals("113.876m", fmt.formatMeasures(fminutes));
3627         Assert.assertEquals("114.876s", fmt.formatMeasures(fseconds));
3628 
3629         Assert.assertEquals("112:113", fmt.formatMeasures(hours, minutes));
3630         Assert.assertEquals("112:00:114", fmt.formatMeasures(hours, seconds));
3631         Assert.assertEquals("113:114", fmt.formatMeasures(minutes, seconds));
3632 
3633         Assert.assertEquals("112:113.876", fmt.formatMeasures(hours, fminutes));
3634         Assert.assertEquals("112:00:114.876", fmt.formatMeasures(hours, fseconds));
3635         Assert.assertEquals("113:114.876", fmt.formatMeasures(minutes, fseconds));
3636 
3637         Assert.assertEquals("112:113", fmt.formatMeasures(fhours, minutes));
3638         Assert.assertEquals("112:00:114", fmt.formatMeasures(fhours, seconds));
3639         Assert.assertEquals("113:114", fmt.formatMeasures(fminutes, seconds));
3640 
3641         Assert.assertEquals("112:113.876", fmt.formatMeasures(fhours, fminutes));
3642         Assert.assertEquals("112:00:114.876", fmt.formatMeasures(fhours, fseconds));
3643         Assert.assertEquals("113:114.876", fmt.formatMeasures(fminutes, fseconds));
3644 
3645         Assert.assertEquals("112:113:114", fmt.formatMeasures(hours, minutes, seconds));
3646         Assert.assertEquals("112:113:114.876", fmt.formatMeasures(fhours, fminutes, fseconds));
3647     }
3648 
3649     @Test
TestNumericTimeSomeSpecialFormats()3650     public void TestNumericTimeSomeSpecialFormats() {
3651         Measure fhours = new Measure(2.8765432, MeasureUnit.HOUR);
3652         Measure fminutes = new Measure(3.8765432, MeasureUnit.MINUTE);
3653 
3654         // Latvian is one of the very few locales 0-padding the hour
3655         MeasureFormat fmt = MeasureFormat.getInstance(ULocale.forLanguageTag("lt"), FormatWidth.NUMERIC);
3656         Assert.assertEquals("02:03,877", fmt.formatMeasures(fhours, fminutes));
3657 
3658         // Danish is one of the very few locales using '.' as separator
3659         fmt = MeasureFormat.getInstance(ULocale.forLanguageTag("da"), FormatWidth.NUMERIC);
3660         Assert.assertEquals("2.03,877", fmt.formatMeasures(fhours, fminutes));
3661     }
3662 
3663     @Test
TestIdentifiers()3664     public void TestIdentifiers() {
3665         class TestCase {
3666             final String id;
3667             final String normalized;
3668 
3669             TestCase(String id, String normalized) {
3670                 this.id = id;
3671                 this.normalized = normalized;
3672             }
3673         }
3674 
3675         TestCase cases[] = {
3676             // Correctly normalized identifiers should not change
3677             new TestCase("square-meter-per-square-meter", "square-meter-per-square-meter"),
3678             new TestCase("kilogram-meter-per-square-meter-square-second",
3679                          "kilogram-meter-per-square-meter-square-second"),
3680             new TestCase("square-mile-and-square-foot", "square-mile-and-square-foot"),
3681             new TestCase("square-foot-and-square-mile", "square-foot-and-square-mile"),
3682             new TestCase("per-cubic-centimeter", "per-cubic-centimeter"),
3683             new TestCase("per-kilometer", "per-kilometer"),
3684 
3685             // Normalization of power and per
3686             new TestCase("pow2-foot-and-pow2-mile", "square-foot-and-square-mile"),
3687             new TestCase("gram-square-gram-per-dekagram", "cubic-gram-per-dekagram"),
3688             new TestCase("kilogram-per-meter-per-second", "kilogram-per-meter-second"),
3689             new TestCase("kilometer-per-second-per-megaparsec", "kilometer-per-megaparsec-second"),
3690 
3691             // Correct order of units, as per unitQuantities in CLDR's units.xml
3692             new TestCase("newton-meter", "newton-meter"),
3693             new TestCase("meter-newton", "newton-meter"),
3694             new TestCase("pound-force-foot", "pound-force-foot"),
3695             new TestCase("foot-pound-force", "pound-force-foot"),
3696             new TestCase("kilowatt-hour", "kilowatt-hour"),
3697             new TestCase("hour-kilowatt", "kilowatt-hour"),
3698 
3699             // Testing prefixes are parsed and produced correctly (ensures no
3700             // collisions in the enum values)
3701             new TestCase("yoctofoot", "yoctofoot"),
3702             new TestCase("zeptofoot", "zeptofoot"),
3703             new TestCase("attofoot", "attofoot"),
3704             new TestCase("femtofoot", "femtofoot"),
3705             new TestCase("picofoot", "picofoot"),
3706             new TestCase("nanofoot", "nanofoot"),
3707             new TestCase("microfoot", "microfoot"),
3708             new TestCase("millifoot", "millifoot"),
3709             new TestCase("centifoot", "centifoot"),
3710             new TestCase("decifoot", "decifoot"),
3711             new TestCase("foot", "foot"),
3712             new TestCase("dekafoot", "dekafoot"),
3713             new TestCase("hectofoot", "hectofoot"),
3714             new TestCase("kilofoot", "kilofoot"),
3715             new TestCase("megafoot", "megafoot"),
3716             new TestCase("gigafoot", "gigafoot"),
3717             new TestCase("terafoot", "terafoot"),
3718             new TestCase("petafoot", "petafoot"),
3719             new TestCase("exafoot", "exafoot"),
3720             new TestCase("zettafoot", "zettafoot"),
3721             new TestCase("yottafoot", "yottafoot"),
3722             new TestCase("kibibyte", "kibibyte"),
3723             new TestCase("mebibyte", "mebibyte"),
3724             new TestCase("gibibyte", "gibibyte"),
3725             new TestCase("tebibyte", "tebibyte"),
3726             new TestCase("pebibyte", "pebibyte"),
3727             new TestCase("exbibyte", "exbibyte"),
3728             new TestCase("zebibyte", "zebibyte"),
3729             new TestCase("yobibyte", "yobibyte"),
3730 
3731             // Testing sort order of prefixes.
3732             //
3733             // TODO(icu-units#70): revisit when fixing normalization. For now we're
3734             // just checking some consistency between C&J.
3735             new TestCase("megafoot-mebifoot-kibifoot-kilofoot", "kibifoot-mebifoot-kilofoot-megafoot"),
3736         };
3737 
3738         for (TestCase testCase : cases) {
3739             MeasureUnit unit = MeasureUnit.forIdentifier(testCase.id);
3740 
3741             final String actual = unit.getIdentifier();
3742             assertEquals(testCase.id, testCase.normalized, actual);
3743         }
3744 
3745         assertEquals("for empty identifiers, the MeasureUnit will be null",
3746                 null, MeasureUnit.forIdentifier(""));
3747     }
3748 
3749     @Test
TestInvalidIdentifiers()3750     public void TestInvalidIdentifiers() {
3751         final String inputs[] = {
3752                 "kilo",
3753                 "kilokilo",
3754                 "onekilo",
3755                 "meterkilo",
3756                 "meter-kilo",
3757                 "k",
3758                 "meter-",
3759                 "meter+",
3760                 "-meter",
3761                 "+meter",
3762                 "-kilometer",
3763                 "+kilometer",
3764                 "-pow2-meter",
3765                 "+pow2-meter",
3766                 "p2-meter",
3767                 "p4-meter",
3768                 "+",
3769                 "-",
3770                 "-mile",
3771                 "-and-mile",
3772                 "-per-mile",
3773                 "one",
3774                 "one-one",
3775                 "one-per-mile",
3776                 "one-per-cubic-centimeter",
3777                 "square--per-meter",
3778                 "metersecond", // Must have compound part in between single units
3779 
3780                 // Negative powers not supported in mixed units yet. TODO(CLDR-13701).
3781                 "per-hour-and-hertz",
3782                 "hertz-and-per-hour",
3783 
3784                 // Compound units not supported in mixed units yet. TODO(CLDR-13700).
3785                 "kilonewton-meter-and-newton-meter",
3786         };
3787 
3788         for (String input : inputs) {
3789             try {
3790                 MeasureUnit.forIdentifier(input);
3791                 Assert.fail("An IllegalArgumentException must be thrown");
3792             } catch (IllegalArgumentException e) {
3793                 continue;
3794             }
3795         }
3796     }
3797 
3798     @Test
TestIdentifierDetails()3799     public void TestIdentifierDetails() {
3800         MeasureUnit joule = MeasureUnit.forIdentifier("joule");
3801         assertEquals("Initial joule", "joule", joule.getIdentifier());
3802 
3803         // "Invalid prefix" test not needed: in Java we cannot pass a
3804         // non-existant enum instance. (In C++ an int can be typecast.)
3805 
3806         MeasureUnit unit = joule.withPrefix(MeasureUnit.MeasurePrefix.HECTO);
3807         assertEquals("Joule with hecto prefix", "hectojoule", unit.getIdentifier());
3808 
3809         unit = unit.withPrefix(MeasureUnit.MeasurePrefix.EXBI);
3810         assertEquals("Joule with exbi prefix", "exbijoule", unit.getIdentifier());
3811     }
3812 
3813     @Test
TestPrefixes()3814     public void TestPrefixes() {
3815         class TestCase {
3816             final MeasureUnit.MeasurePrefix prefix;
3817             final int expectedBase;
3818             final int expectedPower;
3819 
3820             TestCase(MeasureUnit.MeasurePrefix prefix, int expectedBase, int expectedPower) {
3821                 this.prefix = prefix;
3822                 this.expectedBase = expectedBase;
3823                 this.expectedPower = expectedPower;
3824             }
3825         }
3826 
3827         TestCase cases[] = {
3828             new TestCase(MeasureUnit.MeasurePrefix.YOCTO, 10, -24),
3829             new TestCase(MeasureUnit.MeasurePrefix.ZEPTO, 10, -21),
3830             new TestCase(MeasureUnit.MeasurePrefix.ATTO, 10, -18),
3831             new TestCase(MeasureUnit.MeasurePrefix.FEMTO, 10, -15),
3832             new TestCase(MeasureUnit.MeasurePrefix.PICO, 10, -12),
3833             new TestCase(MeasureUnit.MeasurePrefix.NANO, 10, -9),
3834             new TestCase(MeasureUnit.MeasurePrefix.MICRO, 10, -6),
3835             new TestCase(MeasureUnit.MeasurePrefix.MILLI, 10, -3),
3836             new TestCase(MeasureUnit.MeasurePrefix.CENTI, 10, -2),
3837             new TestCase(MeasureUnit.MeasurePrefix.DECI, 10, -1),
3838             new TestCase(MeasureUnit.MeasurePrefix.ONE, 10, 0),
3839             new TestCase(MeasureUnit.MeasurePrefix.DEKA, 10, 1),
3840             new TestCase(MeasureUnit.MeasurePrefix.HECTO, 10, 2),
3841             new TestCase(MeasureUnit.MeasurePrefix.KILO, 10, 3),
3842             new TestCase(MeasureUnit.MeasurePrefix.MEGA, 10, 6),
3843             new TestCase(MeasureUnit.MeasurePrefix.GIGA, 10, 9),
3844             new TestCase(MeasureUnit.MeasurePrefix.TERA, 10, 12),
3845             new TestCase(MeasureUnit.MeasurePrefix.PETA, 10, 15),
3846             new TestCase(MeasureUnit.MeasurePrefix.EXA, 10, 18),
3847             new TestCase(MeasureUnit.MeasurePrefix.ZETTA, 10, 21),
3848             new TestCase(MeasureUnit.MeasurePrefix.YOTTA, 10, 24),
3849             new TestCase(MeasureUnit.MeasurePrefix.KIBI, 1024, 1),
3850             new TestCase(MeasureUnit.MeasurePrefix.MEBI, 1024, 2),
3851             new TestCase(MeasureUnit.MeasurePrefix.GIBI, 1024, 3),
3852             new TestCase(MeasureUnit.MeasurePrefix.TEBI, 1024, 4),
3853             new TestCase(MeasureUnit.MeasurePrefix.PEBI, 1024, 5),
3854             new TestCase(MeasureUnit.MeasurePrefix.EXBI, 1024, 6),
3855             new TestCase(MeasureUnit.MeasurePrefix.ZEBI, 1024, 7),
3856             new TestCase(MeasureUnit.MeasurePrefix.YOBI, 1024, 8),
3857         };
3858 
3859         for (TestCase testCase : cases) {
3860             MeasureUnit m = MeasureUnit.AMPERE.withPrefix(testCase.prefix);
3861             assertEquals("getPrefixPower()", testCase.expectedPower, m.getPrefix().getPower());
3862             assertEquals("getPrefixBase()", testCase.expectedBase, m.getPrefix().getBase());
3863         }
3864     }
3865 
3866     @Test
TestParseBuiltIns()3867     public void TestParseBuiltIns() {
3868         for (MeasureUnit unit : MeasureUnit.getAvailable()) {
3869             System.out.println("unit ident: " + unit.getIdentifier() + ", type: " + unit.getType());
3870             if (unit.getType() == "currency") {
3871                 continue;
3872             }
3873 
3874             // Prove that all built-in units are parseable, except "generic" temperature:
3875             if (unit == MeasureUnit.GENERIC_TEMPERATURE) {
3876                 try {
3877                     MeasureUnit.forIdentifier(unit.getIdentifier());
3878                     Assert.fail("GENERIC_TEMPERATURE should not be parseable");
3879                 } catch (IllegalArgumentException e) {
3880                     continue;
3881                 }
3882             } else {
3883                 MeasureUnit parsed = MeasureUnit.forIdentifier(unit.getIdentifier());
3884                 assertTrue("parsed MeasureUnit '" + parsed + "'' should equal built-in '" + unit + "'",
3885                            unit.equals(parsed));
3886             }
3887         }
3888     }
3889 
3890     @Test
TestParseToBuiltIn()3891     public void TestParseToBuiltIn() {
3892         class TestCase {
3893             final String identifier;
3894             MeasureUnit expectedBuiltin;
3895 
3896             TestCase(String identifier, MeasureUnit expectedBuiltin) {
3897                 this.identifier = identifier;
3898                 this.expectedBuiltin = expectedBuiltin;
3899             }
3900         }
3901 
3902         TestCase cases[] = {
3903             new TestCase("meter-per-second-per-second", MeasureUnit.METER_PER_SECOND_SQUARED),
3904             new TestCase("meter-per-second-second", MeasureUnit.METER_PER_SECOND_SQUARED),
3905             new TestCase("centimeter-centimeter", MeasureUnit.SQUARE_CENTIMETER),
3906             new TestCase("square-foot", MeasureUnit.SQUARE_FOOT),
3907             new TestCase("pow2-inch", MeasureUnit.SQUARE_INCH),
3908             new TestCase("milligram-per-deciliter", MeasureUnit.MILLIGRAM_PER_DECILITER),
3909             new TestCase("pound-force-per-pow2-inch", MeasureUnit.POUND_PER_SQUARE_INCH),
3910             new TestCase("yard-pow2-yard", MeasureUnit.CUBIC_YARD),
3911             new TestCase("square-yard-yard", MeasureUnit.CUBIC_YARD),
3912         };
3913 
3914         for (TestCase testCase : cases) {
3915             MeasureUnit m = MeasureUnit.forIdentifier(testCase.identifier);
3916             assertTrue(testCase.identifier + " parsed to builtin", m.equals(testCase.expectedBuiltin));
3917         }
3918     }
3919 
3920     @Test
TestCompoundUnitOperations()3921     public void TestCompoundUnitOperations() {
3922         MeasureUnit.forIdentifier("kilometer-per-second-joule");
3923 
3924         MeasureUnit kilometer = MeasureUnit.KILOMETER;
3925         MeasureUnit cubicMeter = MeasureUnit.CUBIC_METER;
3926         MeasureUnit meter = kilometer.withPrefix(MeasureUnit.MeasurePrefix.ONE);
3927         MeasureUnit centimeter1 = kilometer.withPrefix(MeasureUnit.MeasurePrefix.CENTI);
3928         MeasureUnit centimeter2 = meter.withPrefix(MeasureUnit.MeasurePrefix.CENTI);
3929         MeasureUnit cubicDecimeter = cubicMeter.withPrefix(MeasureUnit.MeasurePrefix.DECI);
3930 
3931         verifySingleUnit(kilometer, MeasureUnit.MeasurePrefix.KILO, 1, "kilometer");
3932         verifySingleUnit(meter, MeasureUnit.MeasurePrefix.ONE, 1, "meter");
3933         verifySingleUnit(centimeter1, MeasureUnit.MeasurePrefix.CENTI, 1, "centimeter");
3934         verifySingleUnit(centimeter2, MeasureUnit.MeasurePrefix.CENTI, 1, "centimeter");
3935         verifySingleUnit(cubicDecimeter, MeasureUnit.MeasurePrefix.DECI, 3, "cubic-decimeter");
3936 
3937         assertTrue("centimeter equality", centimeter1.equals( centimeter2));
3938         assertTrue("kilometer inequality", !centimeter1.equals( kilometer));
3939 
3940         MeasureUnit squareMeter = meter.withDimensionality(2);
3941         MeasureUnit overCubicCentimeter = centimeter1.withDimensionality(-3);
3942         MeasureUnit quarticKilometer = kilometer.withDimensionality(4);
3943         MeasureUnit overQuarticKilometer1 = kilometer.withDimensionality(-4);
3944 
3945         verifySingleUnit(squareMeter, MeasureUnit.MeasurePrefix.ONE, 2, "square-meter");
3946         verifySingleUnit(overCubicCentimeter, MeasureUnit.MeasurePrefix.CENTI, -3, "per-cubic-centimeter");
3947         verifySingleUnit(quarticKilometer, MeasureUnit.MeasurePrefix.KILO, 4, "pow4-kilometer");
3948         verifySingleUnit(overQuarticKilometer1, MeasureUnit.MeasurePrefix.KILO, -4, "per-pow4-kilometer");
3949 
3950         assertTrue("power inequality", quarticKilometer != overQuarticKilometer1);
3951 
3952         MeasureUnit overQuarticKilometer2 = quarticKilometer.reciprocal();
3953         MeasureUnit overQuarticKilometer3 = kilometer.product(kilometer)
3954                 .product(kilometer)
3955                 .product(kilometer)
3956                 .reciprocal();
3957         MeasureUnit overQuarticKilometer4 = meter.withDimensionality(4)
3958                 .reciprocal()
3959                 .withPrefix(MeasureUnit.MeasurePrefix.KILO);
3960 
3961         verifySingleUnit(overQuarticKilometer2, MeasureUnit.MeasurePrefix.KILO, -4, "per-pow4-kilometer");
3962         verifySingleUnit(overQuarticKilometer3, MeasureUnit.MeasurePrefix.KILO, -4, "per-pow4-kilometer");
3963         verifySingleUnit(overQuarticKilometer4, MeasureUnit.MeasurePrefix.KILO, -4, "per-pow4-kilometer");
3964 
3965         assertTrue("reciprocal equality", overQuarticKilometer1.equals(overQuarticKilometer2));
3966         assertTrue("reciprocal equality", overQuarticKilometer1.equals(overQuarticKilometer3));
3967         assertTrue("reciprocal equality", overQuarticKilometer1.equals(overQuarticKilometer4));
3968 
3969         MeasureUnit kiloSquareSecond = MeasureUnit.SECOND
3970                 .withDimensionality(2).withPrefix(MeasureUnit.MeasurePrefix.KILO);
3971         MeasureUnit meterSecond = meter.product(kiloSquareSecond);
3972         MeasureUnit cubicMeterSecond1 = meter.withDimensionality(3).product(kiloSquareSecond);
3973         MeasureUnit centimeterSecond1 = meter.withPrefix(MeasureUnit.MeasurePrefix.CENTI).product(kiloSquareSecond);
3974         MeasureUnit secondCubicMeter = kiloSquareSecond.product(meter.withDimensionality(3));
3975         MeasureUnit secondCentimeter = kiloSquareSecond.product(meter.withPrefix(MeasureUnit.MeasurePrefix.CENTI));
3976         MeasureUnit secondCentimeterPerKilometer = secondCentimeter.product(kilometer.reciprocal());
3977 
3978         verifySingleUnit(kiloSquareSecond, MeasureUnit.MeasurePrefix.KILO, 2, "square-kilosecond");
3979         String meterSecondSub[] = {
3980                 "meter", "square-kilosecond"
3981         };
3982         verifyCompoundUnit(meterSecond, "meter-square-kilosecond",
3983                 meterSecondSub, meterSecondSub.length);
3984         String cubicMeterSecond1Sub[] = {
3985                 "cubic-meter", "square-kilosecond"
3986         };
3987         verifyCompoundUnit(cubicMeterSecond1, "cubic-meter-square-kilosecond",
3988                 cubicMeterSecond1Sub, cubicMeterSecond1Sub.length);
3989         String centimeterSecond1Sub[] = {
3990                 "centimeter", "square-kilosecond"
3991         };
3992         verifyCompoundUnit(centimeterSecond1, "centimeter-square-kilosecond",
3993                 centimeterSecond1Sub, centimeterSecond1Sub.length);
3994         String secondCubicMeterSub[] = {
3995                 "cubic-meter", "square-kilosecond"
3996         };
3997         verifyCompoundUnit(secondCubicMeter, "cubic-meter-square-kilosecond",
3998                 secondCubicMeterSub, secondCubicMeterSub.length);
3999         String secondCentimeterSub[] = {
4000                 "centimeter", "square-kilosecond"
4001         };
4002         verifyCompoundUnit(secondCentimeter, "centimeter-square-kilosecond",
4003                 secondCentimeterSub, secondCentimeterSub.length);
4004         String secondCentimeterPerKilometerSub[] = {
4005                 "centimeter", "square-kilosecond", "per-kilometer"
4006         };
4007         verifyCompoundUnit(secondCentimeterPerKilometer, "centimeter-square-kilosecond-per-kilometer",
4008                 secondCentimeterPerKilometerSub, secondCentimeterPerKilometerSub.length);
4009 
4010         assertTrue("reordering equality", cubicMeterSecond1.equals(secondCubicMeter));
4011         assertTrue("additional simple units inequality", !secondCubicMeter.equals(secondCentimeter));
4012 
4013         // Don't allow get/set power or SI or binary prefix on compound units
4014         try {
4015             meterSecond.getDimensionality();
4016             fail("UnsupportedOperationException must be thrown");
4017         } catch (UnsupportedOperationException e) {
4018             // Expecting an exception to be thrown
4019         }
4020 
4021         try {
4022             meterSecond.withDimensionality(3);
4023             fail("UnsupportedOperationException must be thrown");
4024         } catch (UnsupportedOperationException e) {
4025             // Expecting an exception to be thrown
4026         }
4027 
4028         try {
4029             meterSecond.getPrefix();
4030             fail("UnsupportedOperationException must be thrown");
4031         } catch (UnsupportedOperationException e) {
4032             // Expecting an exception to be thrown
4033         }
4034 
4035         try {
4036             meterSecond.withPrefix(MeasureUnit.MeasurePrefix.CENTI);
4037             fail("UnsupportedOperationException must be thrown");
4038         } catch (UnsupportedOperationException e) {
4039             // Expecting an exception to be thrown
4040         }
4041 
4042         MeasureUnit footInch = MeasureUnit.forIdentifier("foot-and-inch");
4043         MeasureUnit inchFoot = MeasureUnit.forIdentifier("inch-and-foot");
4044 
4045         String footInchSub[] = {
4046                 "foot", "inch"
4047         };
4048         verifyMixedUnit(footInch, "foot-and-inch",
4049                 footInchSub, footInchSub.length);
4050         String inchFootSub[] = {
4051                 "inch", "foot"
4052         };
4053         verifyMixedUnit(inchFoot, "inch-and-foot",
4054                 inchFootSub, inchFootSub.length);
4055 
4056         assertTrue("order matters inequality", !footInch.equals(inchFoot));
4057 
4058 
4059         MeasureUnit dimensionless  = NoUnit.BASE;
4060         MeasureUnit dimensionless2 = MeasureUnit.forIdentifier("");
4061         assertEquals("dimensionless equality", dimensionless, dimensionless2);
4062 
4063         // We support starting from an "identity" MeasureUnit and then combining it
4064         // with others via product:
4065         MeasureUnit kilometer2 = kilometer.product(dimensionless);
4066 
4067         verifySingleUnit(kilometer2, MeasureUnit.MeasurePrefix.KILO, 1, "kilometer");
4068         assertTrue("kilometer equality", kilometer.equals(kilometer2));
4069 
4070         // Test out-of-range powers
4071         MeasureUnit power15 = MeasureUnit.forIdentifier("pow15-kilometer");
4072         verifySingleUnit(power15, MeasureUnit.MeasurePrefix.KILO, 15, "pow15-kilometer");
4073 
4074         try {
4075             MeasureUnit.forIdentifier("pow16-kilometer");
4076             fail("An IllegalArgumentException must be thrown");
4077         } catch (IllegalArgumentException e) {
4078             // Expecting an exception to be thrown
4079         }
4080 
4081         try {
4082             power15.product(kilometer);
4083             fail("An IllegalArgumentException must be thrown");
4084         } catch (IllegalArgumentException e) {
4085             // Expecting an exception to be thrown
4086         }
4087 
4088         MeasureUnit powerN15 = MeasureUnit.forIdentifier("per-pow15-kilometer");
4089         verifySingleUnit(powerN15, MeasureUnit.MeasurePrefix.KILO, -15, "per-pow15-kilometer");
4090 
4091         try {
4092             MeasureUnit.forIdentifier("per-pow16-kilometer");
4093             fail("An IllegalArgumentException must be thrown");
4094         } catch (IllegalArgumentException e) {
4095             // Expecting an exception to be thrown
4096         }
4097 
4098         try {
4099             powerN15.product(overQuarticKilometer1);
4100             fail("An IllegalArgumentException must be thrown");
4101         } catch (IllegalArgumentException e) {
4102             // Expecting an exception to be thrown
4103         }
4104     }
4105 
4106     @Test
TestDimensionlessBehaviour()4107     public void TestDimensionlessBehaviour() {
4108         MeasureUnit dimensionless = MeasureUnit.forIdentifier("");
4109         MeasureUnit dimensionless2 = NoUnit.BASE;
4110         MeasureUnit dimensionless3 = null;
4111         MeasureUnit dimensionless4 = MeasureUnit.forIdentifier(null);
4112 
4113         assertEquals("dimensionless must be equals", dimensionless, dimensionless2);
4114         assertEquals("dimensionless must be equals", dimensionless2, dimensionless3);
4115         assertEquals("dimensionless must be equals", dimensionless3, dimensionless4);
4116 
4117         // product(dimensionless)
4118         MeasureUnit mile = MeasureUnit.MILE;
4119         mile = mile.product(dimensionless);
4120         verifySingleUnit(mile, MeasureUnit.MeasurePrefix.ONE, 1, "mile");
4121     }
4122 
verifySingleUnit(MeasureUnit singleMeasureUnit, MeasureUnit.MeasurePrefix prefix, int power, String identifier)4123     private void verifySingleUnit(MeasureUnit singleMeasureUnit, MeasureUnit.MeasurePrefix prefix, int power, String identifier) {
4124         assertEquals(identifier + ": SI or binary prefix", prefix, singleMeasureUnit.getPrefix());
4125 
4126         assertEquals(identifier + ": Power", power, singleMeasureUnit.getDimensionality());
4127 
4128         assertEquals(identifier + ": Identifier", identifier, singleMeasureUnit.getIdentifier());
4129 
4130         assertTrue(identifier + ": Constructor", singleMeasureUnit.equals(MeasureUnit.forIdentifier(identifier)));
4131 
4132         assertEquals(identifier + ": Complexity", MeasureUnit.Complexity.SINGLE, singleMeasureUnit.getComplexity());
4133     }
4134 
4135 
4136     // Kilogram is a "base unit", although it's also "gram" with a kilo- prefix.
4137     // This tests that it is handled in the preferred manner.
4138     @Test
TestKilogramIdentifier()4139     public void TestKilogramIdentifier() {
4140         // SI unit of mass
4141         MeasureUnit kilogram = MeasureUnit.forIdentifier("kilogram");
4142         // Metric mass unit
4143         MeasureUnit gram = MeasureUnit.forIdentifier("gram");
4144         // Microgram: still a built-in type
4145         MeasureUnit microgram = MeasureUnit.forIdentifier("microgram");
4146         // Nanogram: not a built-in type at this time
4147         MeasureUnit nanogram = MeasureUnit.forIdentifier("nanogram");
4148 
4149         assertEquals("parsed kilogram equals built-in kilogram", MeasureUnit.KILOGRAM.getType(),
4150                 kilogram.getType());
4151         assertEquals("parsed kilogram equals built-in kilogram", MeasureUnit.KILOGRAM.getSubtype(),
4152                 kilogram.getSubtype());
4153         assertEquals("parsed gram equals built-in gram", MeasureUnit.GRAM.getType(), gram.getType());
4154         assertEquals("parsed gram equals built-in gram", MeasureUnit.GRAM.getSubtype(),
4155                 gram.getSubtype());
4156         assertEquals("parsed microgram equals built-in microgram", MeasureUnit.MICROGRAM.getType(),
4157                 microgram.getType());
4158         assertEquals("parsed microgram equals built-in microgram", MeasureUnit.MICROGRAM.getSubtype(),
4159                 microgram.getSubtype());
4160         assertEquals("nanogram", null, nanogram.getType());
4161         assertEquals("nanogram", "nanogram", nanogram.getIdentifier());
4162 
4163         assertEquals("prefix of kilogram", MeasureUnit.MeasurePrefix.KILO, kilogram.getPrefix());
4164         assertEquals("prefix of gram", MeasureUnit.MeasurePrefix.ONE, gram.getPrefix());
4165         assertEquals("prefix of microgram", MeasureUnit.MeasurePrefix.MICRO, microgram.getPrefix());
4166         assertEquals("prefix of nanogram", MeasureUnit.MeasurePrefix.NANO, nanogram.getPrefix());
4167 
4168         MeasureUnit tmp = kilogram.withPrefix(MeasureUnit.MeasurePrefix.MILLI);
4169         assertEquals("Kilogram + milli should be milligram, got: " + tmp.getIdentifier(),
4170                 MeasureUnit.MILLIGRAM.getIdentifier(), tmp.getIdentifier());
4171     }
4172 
4173     @Test
TestInternalMeasureUnitImpl()4174     public void TestInternalMeasureUnitImpl() {
4175         MeasureUnitImpl mu1 = MeasureUnitImpl.forIdentifier("meter");
4176         assertEquals("mu1 initial identifier", null, mu1.getIdentifier());
4177         assertEquals("mu1 initial complexity", MeasureUnit.Complexity.SINGLE, mu1.getComplexity());
4178         assertEquals("mu1 initial units length", 1, mu1.getSingleUnits().size());
4179         assertEquals("mu1 initial units[0]", "meter", mu1.getSingleUnits().get(0).getSimpleUnitID());
4180 
4181         // Producing identifier via build(): the MeasureUnitImpl instance gets modified
4182         // while it also gets assigned to tmp's internal measureUnitImpl.
4183         MeasureUnit tmp = mu1.build();
4184         assertEquals("mu1 post-build identifier", "meter", mu1.getIdentifier());
4185         assertEquals("mu1 post-build complexity", MeasureUnit.Complexity.SINGLE, mu1.getComplexity());
4186         assertEquals("mu1 post-build units length", 1, mu1.getSingleUnits().size());
4187         assertEquals("mu1 post-build units[0]", "meter", mu1.getSingleUnits().get(0).getSimpleUnitID());
4188         assertEquals("MeasureUnit tmp identifier", "meter", tmp.getIdentifier());
4189 
4190         mu1 = MeasureUnitImpl.forIdentifier("hour-and-minute-and-second");
4191         assertEquals("mu1 = HMS: identifier", null, mu1.getIdentifier());
4192         assertEquals("mu1 = HMS: complexity", MeasureUnit.Complexity.MIXED, mu1.getComplexity());
4193         assertEquals("mu1 = HMS: units length", 3, mu1.getSingleUnits().size());
4194         assertEquals("mu1 = HMS: units[0]", "hour", mu1.getSingleUnits().get(0).getSimpleUnitID());
4195         assertEquals("mu1 = HMS: units[1]", "minute", mu1.getSingleUnits().get(1).getSimpleUnitID());
4196         assertEquals("mu1 = HMS: units[2]", "second", mu1.getSingleUnits().get(2).getSimpleUnitID());
4197 
4198         MeasureUnitImpl m2 = MeasureUnitImpl.forIdentifier("meter");
4199         m2.appendSingleUnit(MeasureUnit.METER.getCopyOfMeasureUnitImpl().getSingleUnitImpl());
4200         assertEquals("append meter twice: complexity", MeasureUnit.Complexity.SINGLE, m2.getComplexity());
4201         assertEquals("append meter twice: units length", 1, m2.getSingleUnits().size());
4202         assertEquals("append meter twice: units[0]", "meter", m2.getSingleUnits().get(0).getSimpleUnitID());
4203         assertEquals("append meter twice: identifier", "square-meter", m2.build().getIdentifier());
4204 
4205         MeasureUnitImpl mcm = MeasureUnitImpl.forIdentifier("meter");
4206         mcm.appendSingleUnit(MeasureUnit.CENTIMETER.getCopyOfMeasureUnitImpl().getSingleUnitImpl());
4207         assertEquals("append meter & centimeter: complexity", MeasureUnit.Complexity.COMPOUND, mcm.getComplexity());
4208         assertEquals("append meter & centimeter: units length", 2, mcm.getSingleUnits().size());
4209         assertEquals("append meter & centimeter: units[0]", "meter", mcm.getSingleUnits().get(0).getSimpleUnitID());
4210         assertEquals("append meter & centimeter: units[1]", "meter", mcm.getSingleUnits().get(1).getSimpleUnitID());
4211         assertEquals("append meter & centimeter: identifier", "centimeter-meter", mcm.build().getIdentifier());
4212 
4213         MeasureUnitImpl m2m = MeasureUnitImpl.forIdentifier("meter-square-meter");
4214         assertEquals("meter-square-meter: complexity", MeasureUnit.Complexity.SINGLE, m2m.getComplexity());
4215         assertEquals("meter-square-meter: units length", 1, m2m.getSingleUnits().size());
4216         assertEquals("meter-square-meter: units[0]", "meter", m2m.getSingleUnits().get(0).getSimpleUnitID());
4217         assertEquals("meter-square-meter: identifier", "cubic-meter", m2m.build().getIdentifier());
4218 
4219     }
4220 
verifyCompoundUnit( MeasureUnit unit, String identifier, String subIdentifiers[], int subIdentifierCount)4221     private void verifyCompoundUnit(
4222             MeasureUnit unit,
4223             String identifier,
4224             String subIdentifiers[],
4225             int subIdentifierCount) {
4226         assertEquals(identifier + ": Identifier",
4227                 identifier,
4228                 unit.getIdentifier());
4229 
4230         assertTrue(identifier + ": Constructor",
4231                 unit.equals(MeasureUnit.forIdentifier(identifier)));
4232 
4233         assertEquals(identifier + ": Complexity",
4234                 MeasureUnit.Complexity.COMPOUND,
4235                 unit.getComplexity());
4236 
4237         List<MeasureUnit> subUnits = unit.splitToSingleUnits();
4238         assertEquals(identifier + ": Length", subIdentifierCount, subUnits.size());
4239         for (int i = 0; ; i++) {
4240             if (i >= subIdentifierCount || i >= subUnits.size()) break;
4241             assertEquals(identifier + ": Sub-unit #" + i,
4242                     subIdentifiers[i],
4243                     subUnits.get(i).getIdentifier());
4244             assertEquals(identifier + ": Sub-unit Complexity",
4245                     MeasureUnit.Complexity.SINGLE,
4246                     subUnits.get(i).getComplexity());
4247         }
4248     }
4249 
verifyMixedUnit( MeasureUnit unit, String identifier, String subIdentifiers[], int subIdentifierCount)4250     private void verifyMixedUnit(
4251             MeasureUnit unit,
4252             String identifier,
4253             String subIdentifiers[],
4254             int subIdentifierCount) {
4255         assertEquals(identifier + ": Identifier",
4256                 identifier,
4257                 unit.getIdentifier());
4258         assertTrue(identifier + ": Constructor",
4259                 unit.equals(MeasureUnit.forIdentifier(identifier)));
4260 
4261         assertEquals(identifier + ": Complexity",
4262                 MeasureUnit.Complexity.MIXED,
4263                 unit.getComplexity());
4264 
4265         List<MeasureUnit> subUnits = unit.splitToSingleUnits();
4266         assertEquals(identifier + ": Length", subIdentifierCount, subUnits.size());
4267         for (int i = 0; ; i++) {
4268             if (i >= subIdentifierCount || i >= subUnits.size()) break;
4269             assertEquals(identifier + ": Sub-unit #" + i,
4270                     subIdentifiers[i],
4271                     subUnits.get(i).getIdentifier());
4272         }
4273     }
4274 }
4275