blob: e5802b1076a7ae7831a1fb65f979520d25147afc [file] [log] [blame]
/*
*******************************************************************************
* Copyright (C) 2013-2014, International Business Machines Corporation and *
* others. All Rights Reserved. *
*******************************************************************************
*/
package com.ibm.icu.dev.test.format;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.text.FieldPosition;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.TreeMap;
import com.ibm.icu.dev.test.TestFmwk;
import com.ibm.icu.dev.test.serializable.SerializableTest;
import com.ibm.icu.impl.Utility;
import com.ibm.icu.math.BigDecimal;
import com.ibm.icu.text.MeasureFormat;
import com.ibm.icu.text.MeasureFormat.FormatWidth;
import com.ibm.icu.text.NumberFormat;
import com.ibm.icu.util.Currency;
import com.ibm.icu.util.Measure;
import com.ibm.icu.util.MeasureUnit;
import com.ibm.icu.util.TimeUnit;
import com.ibm.icu.util.TimeUnitAmount;
import com.ibm.icu.util.ULocale;
/**
* See https://sites.google.com/site/icusite/processes/release/tasks/standards?pli=1
* for information on how to update with each new release.
* @author markdavis
*/
public class MeasureUnitTest extends TestFmwk {
private static final String[] DRAFT_VERSIONS = {"53", "54"};
private static final HashSet<String> DRAFT_VERSION_SET = new HashSet<String>();
private static final HashSet<String> TIME_CODES = new HashSet<String>();
private static final String[][] JAVA_VERSIONS = {
{"G_FORCE", "53"},
{"DEGREE", "53"},
{"ARC_MINUTE", "53"},
{"ARC_SECOND", "53"},
{"ACRE", "53"},
{"HECTARE", "53"},
{"SQUARE_FOOT", "53"},
{"SQUARE_KILOMETER", "53"},
{"SQUARE_METER", "53"},
{"SQUARE_MILE", "53"},
{"MILLISECOND", "53"},
{"CENTIMETER", "53"},
{"FOOT", "53"},
{"INCH", "53"},
{"KILOMETER", "53"},
{"LIGHT_YEAR", "53"},
{"METER", "53"},
{"MILE", "53"},
{"MILLIMETER", "53"},
{"PICOMETER", "53"},
{"YARD", "53"},
{"GRAM", "53"},
{"KILOGRAM", "53"},
{"OUNCE", "53"},
{"POUND", "53"},
{"HORSEPOWER", "53"},
{"KILOWATT", "53"},
{"WATT", "53"},
{"HECTOPASCAL", "53"},
{"INCH_HG", "53"},
{"MILLIBAR", "53"},
{"KILOMETER_PER_HOUR", "53"},
{"METER_PER_SECOND", "53"},
{"MILE_PER_HOUR", "53"},
{"CELSIUS", "53"},
{"FAHRENHEIT", "53"},
{"CUBIC_KILOMETER", "53"},
{"CUBIC_MILE", "53"},
{"LITER", "53"},
{"YEAR", "53"},
{"MONTH", "53"},
{"WEEK", "53"},
{"DAY", "53"},
{"HOUR", "53"},
{"MINUTE", "53"},
{"SECOND", "53"},
{"METER_PER_SECOND_SQUARED", "54"},
{"RADIAN", "54"},
{"SQUARE_CENTIMETER", "54"},
{"SQUARE_INCH", "54"},
{"SQUARE_YARD", "54"},
{"LITER_PER_KILOMETER", "54"},
{"MILE_PER_GALLON", "54"},
{"BIT", "54"},
{"BYTE", "54"},
{"GIGABIT", "54"},
{"GIGABYTE", "54"},
{"KILOBIT", "54"},
{"KILOBYTE", "54"},
{"MEGABIT", "54"},
{"MEGABYTE", "54"},
{"TERABIT", "54"},
{"TERABYTE", "54"},
{"MICROSECOND", "54"},
{"NANOSECOND", "54"},
{"AMPERE", "54"},
{"MILLIAMPERE", "54"},
{"OHM", "54"},
{"VOLT", "54"},
{"CALORIE", "54"},
{"FOODCALORIE", "54"},
{"JOULE", "54"},
{"KILOCALORIE", "54"},
{"KILOJOULE", "54"},
{"KILOWATT_HOUR", "54"},
{"GIGAHERTZ", "54"},
{"HERTZ", "54"},
{"KILOHERTZ", "54"},
{"MEGAHERTZ", "54"},
{"ASTRONOMICAL_UNIT", "54"},
{"DECIMETER", "54"},
{"FATHOM", "54"},
{"FURLONG", "54"},
{"MICROMETER", "54"},
{"NANOMETER", "54"},
{"NAUTICAL_MILE", "54"},
{"PARSEC", "54"},
{"LUX", "54"},
{"CARAT", "54"},
{"METRIC_TON", "54"},
{"MICROGRAM", "54"},
{"MILLIGRAM", "54"},
{"OUNCE_TROY", "54"},
{"STONE", "54"},
{"TON", "54"},
{"GIGAWATT", "54"},
{"MEGAWATT", "54"},
{"MILLIWATT", "54"},
{"MILLIMETER_OF_MERCURY", "54"},
{"POUND_PER_SQUARE_INCH", "54"},
{"KARAT", "54"},
{"KELVIN", "54"},
{"ACRE_FOOT", "54"},
{"BUSHEL", "54"},
{"CENTILITER", "54"},
{"CUBIC_CENTIMETER", "54"},
{"CUBIC_FOOT", "54"},
{"CUBIC_INCH", "54"},
{"CUBIC_METER", "54"},
{"CUBIC_YARD", "54"},
{"CUP", "54"},
{"DECILITER", "54"},
{"FLUID_OUNCE", "54"},
{"GALLON", "54"},
{"HECTOLITER", "54"},
{"MEGALITER", "54"},
{"MILLILITER", "54"},
{"PINT", "54"},
{"QUART", "54"},
{"TABLESPOON", "54"},
{"TEASPOON", "54"},
};
private static final HashMap<String, String> JAVA_VERSION_MAP = new HashMap<String, String>();
static {
TIME_CODES.add("year");
TIME_CODES.add("month");
TIME_CODES.add("week");
TIME_CODES.add("day");
TIME_CODES.add("hour");
TIME_CODES.add("minute");
TIME_CODES.add("second");
for (String verNum : DRAFT_VERSIONS) {
DRAFT_VERSION_SET.add(verNum);
}
for (String[] funcNameAndVersion : JAVA_VERSIONS) {
JAVA_VERSION_MAP.put(funcNameAndVersion[0], funcNameAndVersion[1]);
}
}
/**
* @author markdavis
*
*/
public static void main(String[] args) {
//generateConstants(); if (true) return;
new MeasureUnitTest().run(args);
}
public void TestCompatible53_1() {
MeasureUnit[] units = {
MeasureUnit.G_FORCE,
MeasureUnit.DEGREE,
MeasureUnit.ARC_MINUTE,
MeasureUnit.ARC_SECOND,
MeasureUnit.ACRE,
MeasureUnit.HECTARE,
MeasureUnit.SQUARE_FOOT,
MeasureUnit.SQUARE_KILOMETER,
MeasureUnit.SQUARE_METER,
MeasureUnit.SQUARE_MILE,
MeasureUnit.MILLISECOND,
MeasureUnit.CENTIMETER,
MeasureUnit.FOOT,
MeasureUnit.INCH,
MeasureUnit.KILOMETER,
MeasureUnit.LIGHT_YEAR,
MeasureUnit.METER,
MeasureUnit.MILE,
MeasureUnit.MILLIMETER,
MeasureUnit.PICOMETER,
MeasureUnit.YARD,
MeasureUnit.GRAM,
MeasureUnit.KILOGRAM,
MeasureUnit.OUNCE,
MeasureUnit.POUND,
MeasureUnit.HORSEPOWER,
MeasureUnit.KILOWATT,
MeasureUnit.WATT,
MeasureUnit.HECTOPASCAL,
MeasureUnit.INCH_HG,
MeasureUnit.MILLIBAR,
MeasureUnit.KILOMETER_PER_HOUR,
MeasureUnit.METER_PER_SECOND,
MeasureUnit.MILE_PER_HOUR,
MeasureUnit.CELSIUS,
MeasureUnit.FAHRENHEIT,
MeasureUnit.CUBIC_KILOMETER,
MeasureUnit.CUBIC_MILE,
MeasureUnit.LITER,
MeasureUnit.YEAR,
MeasureUnit.MONTH,
MeasureUnit.WEEK,
MeasureUnit.DAY,
MeasureUnit.HOUR,
MeasureUnit.MINUTE,
MeasureUnit.SECOND,
};
assertEquals("", 46, units.length);
}
public void TestCompatible54_1() {
MeasureUnit[] units = {
MeasureUnit.G_FORCE,
MeasureUnit.METER_PER_SECOND_SQUARED,
MeasureUnit.ARC_MINUTE,
MeasureUnit.ARC_SECOND,
MeasureUnit.DEGREE,
MeasureUnit.RADIAN,
MeasureUnit.ACRE,
MeasureUnit.HECTARE,
MeasureUnit.SQUARE_CENTIMETER,
MeasureUnit.SQUARE_FOOT,
MeasureUnit.SQUARE_INCH,
MeasureUnit.SQUARE_KILOMETER,
MeasureUnit.SQUARE_METER,
MeasureUnit.SQUARE_MILE,
MeasureUnit.SQUARE_YARD,
MeasureUnit.LITER_PER_KILOMETER,
MeasureUnit.MILE_PER_GALLON,
MeasureUnit.BIT,
MeasureUnit.BYTE,
MeasureUnit.GIGABIT,
MeasureUnit.GIGABYTE,
MeasureUnit.KILOBIT,
MeasureUnit.KILOBYTE,
MeasureUnit.MEGABIT,
MeasureUnit.MEGABYTE,
MeasureUnit.TERABIT,
MeasureUnit.TERABYTE,
MeasureUnit.DAY,
MeasureUnit.HOUR,
MeasureUnit.MICROSECOND,
MeasureUnit.MILLISECOND,
MeasureUnit.MINUTE,
MeasureUnit.MONTH,
MeasureUnit.NANOSECOND,
MeasureUnit.SECOND,
MeasureUnit.WEEK,
MeasureUnit.YEAR,
MeasureUnit.AMPERE,
MeasureUnit.MILLIAMPERE,
MeasureUnit.OHM,
MeasureUnit.VOLT,
MeasureUnit.CALORIE,
MeasureUnit.FOODCALORIE,
MeasureUnit.JOULE,
MeasureUnit.KILOCALORIE,
MeasureUnit.KILOJOULE,
MeasureUnit.KILOWATT_HOUR,
MeasureUnit.GIGAHERTZ,
MeasureUnit.HERTZ,
MeasureUnit.KILOHERTZ,
MeasureUnit.MEGAHERTZ,
MeasureUnit.ASTRONOMICAL_UNIT,
MeasureUnit.CENTIMETER,
MeasureUnit.DECIMETER,
MeasureUnit.FATHOM,
MeasureUnit.FOOT,
MeasureUnit.FURLONG,
MeasureUnit.INCH,
MeasureUnit.KILOMETER,
MeasureUnit.LIGHT_YEAR,
MeasureUnit.METER,
MeasureUnit.MICROMETER,
MeasureUnit.MILE,
MeasureUnit.MILLIMETER,
MeasureUnit.NANOMETER,
MeasureUnit.NAUTICAL_MILE,
MeasureUnit.PARSEC,
MeasureUnit.PICOMETER,
MeasureUnit.YARD,
MeasureUnit.LUX,
MeasureUnit.CARAT,
MeasureUnit.GRAM,
MeasureUnit.KILOGRAM,
MeasureUnit.METRIC_TON,
MeasureUnit.MICROGRAM,
MeasureUnit.MILLIGRAM,
MeasureUnit.OUNCE,
MeasureUnit.OUNCE_TROY,
MeasureUnit.POUND,
MeasureUnit.STONE,
MeasureUnit.TON,
MeasureUnit.GIGAWATT,
MeasureUnit.HORSEPOWER,
MeasureUnit.KILOWATT,
MeasureUnit.MEGAWATT,
MeasureUnit.MILLIWATT,
MeasureUnit.WATT,
MeasureUnit.HECTOPASCAL,
MeasureUnit.INCH_HG,
MeasureUnit.MILLIBAR,
MeasureUnit.MILLIMETER_OF_MERCURY,
MeasureUnit.POUND_PER_SQUARE_INCH,
MeasureUnit.KARAT,
MeasureUnit.KILOMETER_PER_HOUR,
MeasureUnit.METER_PER_SECOND,
MeasureUnit.MILE_PER_HOUR,
MeasureUnit.CELSIUS,
MeasureUnit.FAHRENHEIT,
MeasureUnit.KELVIN,
MeasureUnit.ACRE_FOOT,
MeasureUnit.BUSHEL,
MeasureUnit.CENTILITER,
MeasureUnit.CUBIC_CENTIMETER,
MeasureUnit.CUBIC_FOOT,
MeasureUnit.CUBIC_INCH,
MeasureUnit.CUBIC_KILOMETER,
MeasureUnit.CUBIC_METER,
MeasureUnit.CUBIC_MILE,
MeasureUnit.CUBIC_YARD,
MeasureUnit.CUP,
MeasureUnit.DECILITER,
MeasureUnit.FLUID_OUNCE,
MeasureUnit.GALLON,
MeasureUnit.HECTOLITER,
MeasureUnit.LITER,
MeasureUnit.MEGALITER,
MeasureUnit.MILLILITER,
MeasureUnit.PINT,
MeasureUnit.QUART,
MeasureUnit.TABLESPOON,
MeasureUnit.TEASPOON,
};
assertEquals("", 121, units.length);
}
public void TestExamplesInDocs() {
MeasureFormat fmtFr = MeasureFormat.getInstance(
ULocale.FRENCH, FormatWidth.SHORT);
Measure measure = new Measure(23, MeasureUnit.CELSIUS);
assertEquals("23 °C", "23 °C", fmtFr.format(measure));
Measure measureF = new Measure(70, MeasureUnit.FAHRENHEIT);
assertEquals("70 °F", "70 °F", fmtFr.format(measureF));
MeasureFormat fmtFrFull = MeasureFormat.getInstance(
ULocale.FRENCH, FormatWidth.WIDE);
assertEquals(
"70 pied et 5,3 pouces",
"70 pieds et 5,3 pouces",
fmtFrFull.formatMeasures(
new Measure(70, MeasureUnit.FOOT),
new Measure(5.3, MeasureUnit.INCH)));
assertEquals(
"1 pied et 1 pouce",
"1 pied et 1 pouce",
fmtFrFull.formatMeasures(
new Measure(1, MeasureUnit.FOOT),
new Measure(1, MeasureUnit.INCH)));
MeasureFormat fmtFrNarrow = MeasureFormat.getInstance(
ULocale.FRENCH, FormatWidth.NARROW);
assertEquals(
"1′ 1″",
"1′ 1″",
fmtFrNarrow.formatMeasures(
new Measure(1, MeasureUnit.FOOT),
new Measure(1, MeasureUnit.INCH)));
MeasureFormat fmtEn = MeasureFormat.getInstance(ULocale.ENGLISH, FormatWidth.WIDE);
assertEquals(
"1 inch, 2 feet",
"1 inch, 2 feet",
fmtEn.formatMeasures(
new Measure(1, MeasureUnit.INCH),
new Measure(2, MeasureUnit.FOOT)));
}
public void TestFormatPeriodEn() {
TimeUnitAmount[] _19m = {new TimeUnitAmount(19.0, TimeUnit.MINUTE)};
TimeUnitAmount[] _1h_23_5s = {
new TimeUnitAmount(1.0, TimeUnit.HOUR),
new TimeUnitAmount(23.5, TimeUnit.SECOND)};
TimeUnitAmount[] _1h_23_5m = {
new TimeUnitAmount(1.0, TimeUnit.HOUR),
new TimeUnitAmount(23.5, TimeUnit.MINUTE)};
TimeUnitAmount[] _1h_0m_23s = {
new TimeUnitAmount(1.0, TimeUnit.HOUR),
new TimeUnitAmount(0.0, TimeUnit.MINUTE),
new TimeUnitAmount(23.0, TimeUnit.SECOND)};
TimeUnitAmount[] _2y_5M_3w_4d = {
new TimeUnitAmount(2.0, TimeUnit.YEAR),
new TimeUnitAmount(5.0, TimeUnit.MONTH),
new TimeUnitAmount(3.0, TimeUnit.WEEK),
new TimeUnitAmount(4.0, TimeUnit.DAY)};
TimeUnitAmount[] _1m_59_9996s = {
new TimeUnitAmount(1.0, TimeUnit.MINUTE),
new TimeUnitAmount(59.9996, TimeUnit.SECOND)};
TimeUnitAmount[] _5h_17m = {
new TimeUnitAmount(5.0, TimeUnit.HOUR),
new TimeUnitAmount(17.0, TimeUnit.MINUTE)};
TimeUnitAmount[] _neg5h_17m = {
new TimeUnitAmount(-5.0, TimeUnit.HOUR),
new TimeUnitAmount(17.0, TimeUnit.MINUTE)};
TimeUnitAmount[] _19m_28s = {
new TimeUnitAmount(19.0, TimeUnit.MINUTE),
new TimeUnitAmount(28.0, TimeUnit.SECOND)};
TimeUnitAmount[] _0h_0m_9s = {
new TimeUnitAmount(0.0, TimeUnit.HOUR),
new TimeUnitAmount(0.0, TimeUnit.MINUTE),
new TimeUnitAmount(9.0, TimeUnit.SECOND)};
TimeUnitAmount[] _0h_0m_17s = {
new TimeUnitAmount(0.0, TimeUnit.HOUR),
new TimeUnitAmount(0.0, TimeUnit.MINUTE),
new TimeUnitAmount(17.0, TimeUnit.SECOND)};
TimeUnitAmount[] _6h_56_92m = {
new TimeUnitAmount(6.0, TimeUnit.HOUR),
new TimeUnitAmount(56.92, TimeUnit.MINUTE)};
TimeUnitAmount[] _3h_4s_5m = {
new TimeUnitAmount(3.0, TimeUnit.HOUR),
new TimeUnitAmount(4.0, TimeUnit.SECOND),
new TimeUnitAmount(5.0, TimeUnit.MINUTE)};
TimeUnitAmount[] _6_7h_56_92m = {
new TimeUnitAmount(6.7, TimeUnit.HOUR),
new TimeUnitAmount(56.92, TimeUnit.MINUTE)};
TimeUnitAmount[] _3h_5h = {
new TimeUnitAmount(3.0, TimeUnit.HOUR),
new TimeUnitAmount(5.0, TimeUnit.HOUR)};
Object[][] fullData = {
{_1m_59_9996s, "1 minute, 59.9996 seconds"},
{_19m, "19 minutes"},
{_1h_23_5s, "1 hour, 23.5 seconds"},
{_1h_23_5m, "1 hour, 23.5 minutes"},
{_1h_0m_23s, "1 hour, 0 minutes, 23 seconds"},
{_2y_5M_3w_4d, "2 years, 5 months, 3 weeks, 4 days"}};
Object[][] abbrevData = {
{_1m_59_9996s, "1 min, 59.9996 secs"},
{_19m, "19 mins"},
{_1h_23_5s, "1 hr, 23.5 secs"},
{_1h_23_5m, "1 hr, 23.5 mins"},
{_1h_0m_23s, "1 hr, 0 mins, 23 secs"},
{_2y_5M_3w_4d, "2 yrs, 5 mths, 3 wks, 4 days"}};
Object[][] narrowData = {
{_1m_59_9996s, "1m 59.9996s"},
{_19m, "19m"},
{_1h_23_5s, "1h 23.5s"},
{_1h_23_5m, "1h 23.5m"},
{_1h_0m_23s, "1h 0m 23s"},
{_2y_5M_3w_4d, "2y 5m 3w 4d"}};
Object[][] numericData = {
{_1m_59_9996s, "1:59.9996"},
{_19m, "19m"},
{_1h_23_5s, "1:00:23.5"},
{_1h_0m_23s, "1:00:23"},
{_1h_23_5m, "1:23.5"},
{_5h_17m, "5:17"},
{_neg5h_17m, "-5h 17m"},
{_19m_28s, "19:28"},
{_2y_5M_3w_4d, "2y 5m 3w 4d"},
{_0h_0m_9s, "0:00:09"},
{_6h_56_92m, "6:56.92"},
{_6_7h_56_92m, "6:56.92"},
{_3h_4s_5m, "3h 4s 5m"},
{_3h_5h, "3h 5h"}};
Object[][] fullDataDe = {
{_1m_59_9996s, "1 Minute und 59,9996 Sekunden"},
{_19m, "19 Minuten"},
{_1h_23_5s, "1 Stunde und 23,5 Sekunden"},
{_1h_23_5m, "1 Stunde und 23,5 Minuten"},
{_1h_0m_23s, "1 Stunde, 0 Minuten und 23 Sekunden"},
{_2y_5M_3w_4d, "2 Jahre, 5 Monate, 3 Wochen und 4 Tage"}};
Object[][] numericDataDe = {
{_1m_59_9996s, "1:59,9996"},
{_19m, "19 Min."},
{_1h_23_5s, "1:00:23,5"},
{_1h_0m_23s, "1:00:23"},
{_1h_23_5m, "1:23,5"},
{_5h_17m, "5:17"},
{_19m_28s, "19:28"},
{_2y_5M_3w_4d, "2 J, 5 M, 3 W und 4 T"},
{_0h_0m_17s, "0:00:17"},
{_6h_56_92m, "6:56,92"},
{_3h_5h, "3 Std., 5 Std."}};
NumberFormat nf = NumberFormat.getNumberInstance(ULocale.ENGLISH);
nf.setMaximumFractionDigits(4);
MeasureFormat mf = MeasureFormat.getInstance(ULocale.ENGLISH, FormatWidth.WIDE, nf);
verifyFormatPeriod("en FULL", mf, fullData);
mf = MeasureFormat.getInstance(ULocale.ENGLISH, FormatWidth.SHORT, nf);
verifyFormatPeriod("en SHORT", mf, abbrevData);
mf = MeasureFormat.getInstance(ULocale.ENGLISH, FormatWidth.NARROW, nf);
verifyFormatPeriod("en NARROW", mf, narrowData);
mf = MeasureFormat.getInstance(ULocale.ENGLISH, FormatWidth.NUMERIC, nf);
verifyFormatPeriod("en NUMERIC", mf, numericData);
nf = NumberFormat.getNumberInstance(ULocale.GERMAN);
nf.setMaximumFractionDigits(4);
mf = MeasureFormat.getInstance(ULocale.GERMAN, FormatWidth.WIDE, nf);
verifyFormatPeriod("de FULL", mf, fullDataDe);
mf = MeasureFormat.getInstance(ULocale.GERMAN, FormatWidth.NUMERIC, nf);
verifyFormatPeriod("de NUMERIC", mf, numericDataDe);
// Same tests, with Java Locale
nf = NumberFormat.getNumberInstance(Locale.GERMAN);
nf.setMaximumFractionDigits(4);
mf = MeasureFormat.getInstance(Locale.GERMAN, FormatWidth.WIDE, nf);
verifyFormatPeriod("de FULL(Java Locale)", mf, fullDataDe);
mf = MeasureFormat.getInstance(Locale.GERMAN, FormatWidth.NUMERIC, nf);
verifyFormatPeriod("de NUMERIC(Java Locale)", mf, numericDataDe);
}
private void verifyFormatPeriod(String desc, MeasureFormat mf, Object[][] testData) {
StringBuilder builder = new StringBuilder();
boolean failure = false;
for (Object[] testCase : testData) {
String actual = mf.format((Measure[]) testCase[0]);
if (!testCase[1].equals(actual)) {
builder.append(String.format("%s: Expected: '%s', got: '%s'\n", desc, testCase[1], actual));
failure = true;
}
}
if (failure) {
errln(builder.toString());
}
}
public void Test10219FractionalPlurals() {
double[] values = {1.588, 1.011};
String[][] expected = {
{"1 minute", "1.5 minutes", "1.58 minutes"},
{"1 minute", "1.0 minutes", "1.01 minutes"}
};
for (int j = 0; j < values.length; j++) {
for (int i = 0; i < expected[j].length; i++) {
NumberFormat nf = NumberFormat.getNumberInstance(ULocale.ENGLISH);
nf.setRoundingMode(BigDecimal.ROUND_DOWN);
nf.setMinimumFractionDigits(i);
nf.setMaximumFractionDigits(i);
MeasureFormat mf = MeasureFormat.getInstance(
ULocale.ENGLISH, FormatWidth.WIDE, nf);
assertEquals("Test10219", expected[j][i], mf.format(new Measure(values[j], MeasureUnit.MINUTE)));
}
}
}
public void TestGreek() {
String[] locales = {"el_GR", "el"};
final MeasureUnit[] units = new MeasureUnit[]{
MeasureUnit.SECOND,
MeasureUnit.MINUTE,
MeasureUnit.HOUR,
MeasureUnit.DAY,
MeasureUnit.WEEK,
MeasureUnit.MONTH,
MeasureUnit.YEAR};
FormatWidth[] styles = new FormatWidth[] {FormatWidth.WIDE, FormatWidth.SHORT};
int[] numbers = new int[] {1, 7};
String[] expected = {
// "el_GR" 1 wide
"1 δευτερόλεπτο",
"1 λεπτό",
"1 ώρα",
"1 ημέρα",
"1 εβδομάδα",
"1 μήνας",
"1 έτος",
// "el_GR" 1 short
"1 δευτ.",
"1 λεπ.",
"1 ώρα",
"1 ημέρα",
"1 εβδ.",
"1 μήν.",
"1 έτ.", // year (one)
// "el_GR" 7 wide
"7 δευτερόλεπτα",
"7 λεπτά",
"7 ώρες",
"7 ημέρες",
"7 εβδομάδες",
"7 μήνες",
"7 έτη",
// "el_GR" 7 short
"7 δευτ.",
"7 λεπ.",
"7 ώρ.", // hour (other)
"7 ημέρες",
"7 εβδ.",
"7 μήν.",
"7 έτ.", // year (other)
// "el" 1 wide
"1 δευτερόλεπτο",
"1 λεπτό",
"1 ώρα",
"1 ημέρα",
"1 εβδομάδα",
"1 μήνας",
"1 έτος",
// "el" 1 short
"1 δευτ.",
"1 λεπ.",
"1 ώρα",
"1 ημέρα",
"1 εβδ.",
"1 μήν.",
"1 έτ.", // year (one)
// "el" 7 wide
"7 δευτερόλεπτα",
"7 λεπτά",
"7 ώρες",
"7 ημέρες",
"7 εβδομάδες",
"7 μήνες",
"7 έτη",
// "el" 7 short
"7 δευτ.",
"7 λεπ.",
"7 ώρ.", // hour (other)
"7 ημέρες",
"7 εβδ.",
"7 μήν.",
"7 έτ."}; // year (other
int counter = 0;
String formatted;
for ( int locIndex = 0; locIndex < locales.length; ++locIndex ) {
for( int numIndex = 0; numIndex < numbers.length; ++numIndex ) {
for ( int styleIndex = 0; styleIndex < styles.length; ++styleIndex ) {
for ( int unitIndex = 0; unitIndex < units.length; ++unitIndex ) {
Measure m = new Measure(numbers[numIndex], units[unitIndex]);
MeasureFormat fmt = MeasureFormat.getInstance(new ULocale(locales[locIndex]), styles[styleIndex]);
formatted = fmt.format(m);
assertEquals(
"locale: " + locales[locIndex]
+ ", style: " + styles[styleIndex]
+ ", units: " + units[unitIndex]
+ ", value: " + numbers[numIndex],
expected[counter], formatted);
++counter;
}
}
}
}
}
public void testAUnit() {
String lastType = null;
for (MeasureUnit expected : MeasureUnit.getAvailable()) {
String type = expected.getType();
String code = expected.getSubtype();
if (!type.equals(lastType)) {
logln(type);
lastType = type;
}
MeasureUnit actual = MeasureUnit.internalGetInstance(type, code);
assertSame("Identity check", expected, actual);
}
}
public void testFormatSingleArg() {
MeasureFormat mf = MeasureFormat.getInstance(ULocale.ENGLISH, FormatWidth.WIDE);
assertEquals("", "5 meters", mf.format(new Measure(5, MeasureUnit.METER)));
}
public void testFormatMeasuresZeroArg() {
MeasureFormat mf = MeasureFormat.getInstance(ULocale.ENGLISH, FormatWidth.WIDE);
assertEquals("", "", mf.formatMeasures());
}
public void testFormatMeasuresOneArg() {
MeasureFormat mf = MeasureFormat.getInstance(ULocale.ENGLISH, FormatWidth.WIDE);
assertEquals("", "5 meters", mf.formatMeasures(new Measure(5, MeasureUnit.METER)));
}
public void testMultiples() {
ULocale russia = new ULocale("ru");
Object[][] data = new Object[][] {
{ULocale.ENGLISH, FormatWidth.WIDE, "2 miles, 1 foot, 2.3 inches"},
{ULocale.ENGLISH, FormatWidth.SHORT, "2 mi, 1 ft, 2.3 in"},
{ULocale.ENGLISH, FormatWidth.NARROW, "2mi 1\u2032 2.3\u2033"},
{russia, FormatWidth.WIDE, "2 \u043C\u0438\u043B\u0438, 1 \u0444\u0443\u0442 \u0438 2,3 \u0434\u044E\u0439\u043C\u0430"},
{russia, FormatWidth.SHORT, "2 \u043C\u0438\u043B\u0438, 1 \u0444\u0443\u0442, 2,3 \u0434\u044E\u0439\u043C."},
{russia, FormatWidth.NARROW, "2 \u043C\u0438\u043B\u044C 1 \u0444\u0443\u0442 2,3 \u0434\u044E\u0439\u043C\u0430"},
};
for (Object[] row : data) {
MeasureFormat mf = MeasureFormat.getInstance(
(ULocale) row[0], (FormatWidth) row[1]);
assertEquals(
"testMultiples",
row[2],
mf.formatMeasures(
new Measure(2, MeasureUnit.MILE),
new Measure(1, MeasureUnit.FOOT),
new Measure(2.3, MeasureUnit.INCH)));
}
}
public void testMultiplesPer() {
Object[][] data = new Object[][] {
// perUnit pattern
{ULocale.ENGLISH, FormatWidth.WIDE, MeasureUnit.SECOND, "2 miles, 1 foot, 2.3 inches per second"},
{ULocale.ENGLISH, FormatWidth.SHORT, MeasureUnit.SECOND, "2 mi, 1 ft, 2.3 inps"},
{ULocale.ENGLISH, FormatWidth.NARROW, MeasureUnit.SECOND, "2mi 1\u2032 2.3\u2033/s"},
// global per pattern
{ULocale.ENGLISH, FormatWidth.WIDE, MeasureUnit.MINUTE, "2 miles, 1 foot, 2.3 inches per minute"},
{ULocale.ENGLISH, FormatWidth.SHORT, MeasureUnit.MINUTE, "2 mi, 1 ft, 2.3 in/min"},
{ULocale.ENGLISH, FormatWidth.NARROW, MeasureUnit.MINUTE, "2mi 1\u2032 2.3\u2033/m"}
};
for (Object[] row : data) {
MeasureFormat mf = MeasureFormat.getInstance(
(ULocale) row[0], (FormatWidth) row[1]);
assertEquals(
"testMultiples",
row[3],
mf.formatMeasuresPer(
new StringBuilder(),
new FieldPosition(0),
(MeasureUnit) row[2],
new Measure(2, MeasureUnit.MILE),
new Measure(1, MeasureUnit.FOOT),
new Measure(2.3, MeasureUnit.INCH)).toString());
}
}
public void testSimplePer() {
Object[][] data = new Object[][] {
// per unit singular
{1, MeasureUnit.SECOND, "1 lbps"},
// per unit plural
{2, MeasureUnit.SECOND, "2 lbps"},
// compound singular
{1, MeasureUnit.MINUTE, "1 lb/min"},
// compound plural
{2, MeasureUnit.MINUTE, "2 lb/min"},
};
for (Object[] row : data) {
MeasureFormat mf = MeasureFormat.getInstance(
ULocale.ENGLISH, FormatWidth.SHORT);
assertEquals(
"",
row[2],
mf.formatMeasuresPer(
new StringBuilder(),
new FieldPosition(0),
(MeasureUnit) row[1],
new Measure((Number) row[0], MeasureUnit.POUND)).toString());
}
}
public void testNumeratorPlurals() {
ULocale polish = new ULocale("pl");
Object[][] data = new Object[][] {
{1, "1 stopa na sekundę"},
{2, "2 stopy na sekundę"},
{5, "5 stóp na sekundę"},
{1.5, "1,5 stopy na sekundę"}};
for (Object[] row : data) {
MeasureFormat mf = MeasureFormat.getInstance(polish, FormatWidth.WIDE);
assertEquals(
"",
row[1],
mf.formatMeasuresPer(
new StringBuilder(),
new FieldPosition(0),
MeasureUnit.SECOND,
new Measure((Number) row[0], MeasureUnit.FOOT)).toString());
}
}
public void testGram() {
MeasureFormat mf = MeasureFormat.getInstance(ULocale.ENGLISH, FormatWidth.SHORT);
assertEquals(
"testGram",
"1 g",
mf.format(new Measure(1, MeasureUnit.GRAM)));
assertEquals(
"testGram",
"1 G",
mf.format(new Measure(1, MeasureUnit.G_FORCE)));
}
public void testCurrencies() {
Measure USD_1 = new Measure(1.0, Currency.getInstance("USD"));
Measure USD_2 = new Measure(2.0, Currency.getInstance("USD"));
Measure USD_NEG_1 = new Measure(-1.0, Currency.getInstance("USD"));
MeasureFormat mf = MeasureFormat.getInstance(ULocale.ENGLISH, FormatWidth.WIDE);
assertEquals("Wide currency", "-1.00 US dollars", mf.format(USD_NEG_1));
assertEquals("Wide currency", "1.00 US dollars", mf.format(USD_1));
assertEquals("Wide currency", "2.00 US dollars", mf.format(USD_2));
mf = MeasureFormat.getInstance(ULocale.ENGLISH, FormatWidth.SHORT);
assertEquals("short currency", "-USD1.00", mf.format(USD_NEG_1));
assertEquals("short currency", "USD1.00", mf.format(USD_1));
assertEquals("short currency", "USD2.00", mf.format(USD_2));
mf = MeasureFormat.getInstance(ULocale.ENGLISH, FormatWidth.NARROW);
assertEquals("narrow currency", "-$1.00", mf.format(USD_NEG_1));
assertEquals("narrow currency", "$1.00", mf.format(USD_1));
assertEquals("narrow currency", "$2.00", mf.format(USD_2));
mf = MeasureFormat.getInstance(ULocale.ENGLISH, FormatWidth.NUMERIC);
assertEquals("numeric currency", "-$1.00", mf.format(USD_NEG_1));
assertEquals("numeric currency", "$1.00", mf.format(USD_1));
assertEquals("numeric currency", "$2.00", mf.format(USD_2));
mf = MeasureFormat.getInstance(ULocale.JAPAN, FormatWidth.WIDE);
assertEquals("Wide currency", "-1.00 \u7C73\u30C9\u30EB", mf.format(USD_NEG_1));
assertEquals("Wide currency", "1.00 \u7C73\u30C9\u30EB", mf.format(USD_1));
assertEquals("Wide currency", "2.00 \u7C73\u30C9\u30EB", mf.format(USD_2));
}
public void testFieldPosition() {
MeasureFormat fmt = MeasureFormat.getInstance(
ULocale.ENGLISH, FormatWidth.SHORT);
FieldPosition pos = new FieldPosition(NumberFormat.Field.DECIMAL_SEPARATOR);
fmt.format(new Measure(43.5, MeasureUnit.FOOT), new StringBuffer("123456: "), pos);
assertEquals("beginIndex", 10, pos.getBeginIndex());
assertEquals("endIndex", 11, pos.getEndIndex());
pos = new FieldPosition(NumberFormat.Field.DECIMAL_SEPARATOR);
fmt.format(new Measure(43, MeasureUnit.FOOT), new StringBuffer(), pos);
assertEquals("beginIndex", 0, pos.getBeginIndex());
assertEquals("endIndex", 0, pos.getEndIndex());
}
public void testFieldPositionMultiple() {
MeasureFormat fmt = MeasureFormat.getInstance(
ULocale.ENGLISH, FormatWidth.SHORT);
FieldPosition pos = new FieldPosition(NumberFormat.Field.INTEGER);
String result = fmt.formatMeasures(
new StringBuilder(),
pos,
new Measure(354, MeasureUnit.METER),
new Measure(23, MeasureUnit.CENTIMETER)).toString();
assertEquals("result", "354 m, 23 cm", result);
// According to javadocs for {@link Format#format} FieldPosition is set to
// beginning and end of first such field encountered instead of the last
// such field encountered.
assertEquals("beginIndex", 0, pos.getBeginIndex());
assertEquals("endIndex", 3, pos.getEndIndex());
pos = new FieldPosition(NumberFormat.Field.DECIMAL_SEPARATOR);
result = fmt.formatMeasures(
new StringBuilder("123456: "),
pos,
new Measure(354, MeasureUnit.METER),
new Measure(23, MeasureUnit.CENTIMETER),
new Measure(5.4, MeasureUnit.MILLIMETER)).toString();
assertEquals("result", "123456: 354 m, 23 cm, 5.4 mm", result);
assertEquals("beginIndex", 23, pos.getBeginIndex());
assertEquals("endIndex", 24, pos.getEndIndex());
result = fmt.formatMeasures(
new StringBuilder(),
pos,
new Measure(3, MeasureUnit.METER),
new Measure(23, MeasureUnit.CENTIMETER),
new Measure(5.4, MeasureUnit.MILLIMETER)).toString();
assertEquals("result", "3 m, 23 cm, 5.4 mm", result);
assertEquals("beginIndex", 13, pos.getBeginIndex());
assertEquals("endIndex", 14, pos.getEndIndex());
pos = new FieldPosition(NumberFormat.Field.DECIMAL_SEPARATOR);
result = fmt.formatMeasures(
new StringBuilder("123456: "),
pos,
new Measure(3, MeasureUnit.METER),
new Measure(23, MeasureUnit.CENTIMETER),
new Measure(5, MeasureUnit.MILLIMETER)).toString();
assertEquals("result", "123456: 3 m, 23 cm, 5 mm", result);
assertEquals("beginIndex", 0, pos.getBeginIndex());
assertEquals("endIndex", 0, pos.getEndIndex());
pos = new FieldPosition(NumberFormat.Field.INTEGER);
result = fmt.formatMeasures(
new StringBuilder("123456: "),
pos,
new Measure(57, MeasureUnit.MILLIMETER)).toString();
assertEquals("result", "123456: 57 mm", result);
assertEquals("beginIndex", 8, pos.getBeginIndex());
assertEquals("endIndex", 10, pos.getEndIndex());
}
public void testFieldPositionMultipleWithPer() {
MeasureFormat fmt = MeasureFormat.getInstance(
ULocale.ENGLISH, FormatWidth.SHORT);
FieldPosition pos = new FieldPosition(NumberFormat.Field.INTEGER);
String result = fmt.formatMeasuresPer(
new StringBuilder(),
pos,
MeasureUnit.SECOND,
new Measure(354, MeasureUnit.METER),
new Measure(23, MeasureUnit.CENTIMETER)).toString();
assertEquals("result", "354 m, 23 cmps", result);
// According to javadocs for {@link Format#format} FieldPosition is set to
// beginning and end of first such field encountered instead of the last
// such field encountered.
assertEquals("beginIndex", 0, pos.getBeginIndex());
assertEquals("endIndex", 3, pos.getEndIndex());
pos = new FieldPosition(NumberFormat.Field.DECIMAL_SEPARATOR);
result = fmt.formatMeasuresPer(
new StringBuilder("123456: "),
pos,
MeasureUnit.SECOND,
new Measure(354, MeasureUnit.METER),
new Measure(23, MeasureUnit.CENTIMETER),
new Measure(5.4, MeasureUnit.MILLIMETER)).toString();
assertEquals("result", "123456: 354 m, 23 cm, 5.4 mmps", result);
assertEquals("beginIndex", 23, pos.getBeginIndex());
assertEquals("endIndex", 24, pos.getEndIndex());
pos = new FieldPosition(NumberFormat.Field.INTEGER);
result = fmt.formatMeasuresPer(
new StringBuilder(),
pos,
MeasureUnit.MINUTE,
new Measure(354, MeasureUnit.METER),
new Measure(23, MeasureUnit.CENTIMETER)).toString();
assertEquals("result", "354 m, 23 cm/min", result);
// According to javadocs for {@link Format#format} FieldPosition is set to
// beginning and end of first such field encountered instead of the last
// such field encountered.
assertEquals("beginIndex", 0, pos.getBeginIndex());
assertEquals("endIndex", 3, pos.getEndIndex());
pos = new FieldPosition(NumberFormat.Field.DECIMAL_SEPARATOR);
result = fmt.formatMeasuresPer(
new StringBuilder("123456: "),
pos,
MeasureUnit.MINUTE,
new Measure(354, MeasureUnit.METER),
new Measure(23, MeasureUnit.CENTIMETER),
new Measure(5.4, MeasureUnit.MILLIMETER)).toString();
assertEquals("result", "123456: 354 m, 23 cm, 5.4 mm/min", result);
assertEquals("beginIndex", 23, pos.getBeginIndex());
assertEquals("endIndex", 24, pos.getEndIndex());
}
public void testOldFormatWithList() {
List<Measure> measures = new ArrayList<Measure>(2);
measures.add(new Measure(5, MeasureUnit.ACRE));
measures.add(new Measure(3000, MeasureUnit.SQUARE_FOOT));
MeasureFormat fmt = MeasureFormat.getInstance(
ULocale.ENGLISH, FormatWidth.WIDE);
assertEquals("", "5 acres, 3,000 square feet", fmt.format(measures));
assertEquals("", "5 acres", fmt.format(measures.subList(0, 1)));
List<String> badList = new ArrayList<String>();
badList.add("be");
badList.add("you");
try {
fmt.format(badList);
fail("Expected IllegalArgumentException.");
} catch (IllegalArgumentException expected) {
// Expected
}
}
public void testOldFormatWithArray() {
Measure[] measures = new Measure[] {
new Measure(5, MeasureUnit.ACRE),
new Measure(3000, MeasureUnit.SQUARE_FOOT),
};
MeasureFormat fmt = MeasureFormat.getInstance(
ULocale.ENGLISH, FormatWidth.WIDE);
assertEquals("", "5 acres, 3,000 square feet", fmt.format(measures));
}
public void testOldFormatBadArg() {
MeasureFormat fmt = MeasureFormat.getInstance(
ULocale.ENGLISH, FormatWidth.WIDE);
try {
fmt.format("be");
fail("Expected IllegalArgumentExceptino.");
} catch (IllegalArgumentException e) {
// Expected
}
}
public void testEqHashCode() {
MeasureFormat mf = MeasureFormat.getInstance(ULocale.CANADA, FormatWidth.SHORT);
MeasureFormat mfeq = MeasureFormat.getInstance(ULocale.CANADA, FormatWidth.SHORT);
MeasureFormat mfne = MeasureFormat.getInstance(ULocale.CANADA, FormatWidth.WIDE);
MeasureFormat mfne2 = MeasureFormat.getInstance(ULocale.ENGLISH, FormatWidth.SHORT);
verifyEqualsHashCode(mf, mfeq, mfne);
verifyEqualsHashCode(mf, mfeq, mfne2);
}
public void testEqHashCodeOfMeasure() {
Measure _3feetDouble = new Measure(3.0, MeasureUnit.FOOT);
Measure _3feetInt = new Measure(3, MeasureUnit.FOOT);
Measure _4feetInt = new Measure(4, MeasureUnit.FOOT);
verifyEqualsHashCode(_3feetDouble, _3feetInt, _4feetInt);
}
public void testGetLocale() {
MeasureFormat mf = MeasureFormat.getInstance(ULocale.GERMAN, FormatWidth.SHORT);
assertEquals("", ULocale.GERMAN, mf.getLocale(ULocale.VALID_LOCALE));
}
public void TestSerial() {
checkStreamingEquality(MeasureUnit.CELSIUS);
checkStreamingEquality(MeasureFormat.getInstance(ULocale.FRANCE, FormatWidth.NARROW));
checkStreamingEquality(Currency.getInstance("EUR"));
checkStreamingEquality(MeasureFormat.getInstance(ULocale.GERMAN, FormatWidth.SHORT));
checkStreamingEquality(MeasureFormat.getCurrencyFormat(ULocale.ITALIAN));
}
public void TestSerialFormatWidthEnum() {
// FormatWidth enum values must map to the same ordinal values for all time in order for
// serialization to work.
assertEquals("FormatWidth.WIDE", 0, FormatWidth.WIDE.ordinal());
assertEquals("FormatWidth.SHORT", 1, FormatWidth.SHORT.ordinal());
assertEquals("FormatWidth.NARROW", 2, FormatWidth.NARROW.ordinal());
assertEquals("FormatWidth.NUMERIC", 3, FormatWidth.NUMERIC.ordinal());
}
public void testCurrencyFormatStandInForMeasureFormat() {
MeasureFormat mf = MeasureFormat.getCurrencyFormat(ULocale.ENGLISH);
assertEquals(
"70 feet, 5.3 inches",
"70 feet, 5.3 inches",
mf.formatMeasures(
new Measure(70, MeasureUnit.FOOT),
new Measure(5.3, MeasureUnit.INCH)));
assertEquals("getLocale", ULocale.ENGLISH, mf.getLocale());
assertEquals("getNumberFormat", ULocale.ENGLISH, mf.getNumberFormat().getLocale(ULocale.VALID_LOCALE));
assertEquals("getWidth", MeasureFormat.FormatWidth.WIDE, mf.getWidth());
}
public void testCurrencyFormatLocale() {
MeasureFormat mfu = MeasureFormat.getCurrencyFormat(ULocale.FRANCE);
MeasureFormat mfj = MeasureFormat.getCurrencyFormat(Locale.FRANCE);
assertEquals("getCurrencyFormat ULocale/Locale", mfu, mfj);
}
public void testDoubleZero() {
ULocale en = new ULocale("en");
NumberFormat nf = NumberFormat.getInstance(en);
nf.setMinimumFractionDigits(2);
nf.setMaximumFractionDigits(2);
MeasureFormat mf = MeasureFormat.getInstance(en, FormatWidth.WIDE, nf);
assertEquals(
"Positive Rounding",
"4 hours, 23 minutes, 16.00 seconds",
mf.formatMeasures(
new Measure(4.7, MeasureUnit.HOUR),
new Measure(23, MeasureUnit.MINUTE),
new Measure(16, MeasureUnit.SECOND)));
assertEquals(
"Negative Rounding",
"-4 hours, 23 minutes, 16.00 seconds",
mf.formatMeasures(
new Measure(-4.7, MeasureUnit.HOUR),
new Measure(23, MeasureUnit.MINUTE),
new Measure(16, MeasureUnit.SECOND)));
}
// DO NOT DELETE THIS FUNCTION! It may appear as dead code, but we use this to generate code
// for MeasureFormat during the release process.
static void generateCXXHConstants(String thisVersion) {
Map<String, MeasureUnit> seen = new HashMap<String, MeasureUnit>();
System.out.println();
TreeMap<String, List<MeasureUnit>> allUnits = getAllUnits();
for (Map.Entry<String, List<MeasureUnit>> entry : allUnits.entrySet()) {
String type = entry.getKey();
if (type.equals("currency")) {
continue;
}
for (MeasureUnit unit : entry.getValue()) {
String code = unit.getSubtype();
String name = toCamelCase(unit);
String javaName = toJAVAName(unit);
checkForDup(seen, name, unit);
if (isDraft(javaName)) {
System.out.println("#ifndef U_HIDE_DRAFT_API");
}
System.out.println(" /**");
System.out.println(" * Returns unit of " + type + ": " + code + ".");
System.out.println(" * Caller owns returned value and must free it.");
System.out.println(" * @param status ICU error code.");
if (isDraft(javaName)) {
System.out.println(" * @draft ICU " + getVersion(javaName, thisVersion));
} else {
System.out.println(" * @stable ICU " + getVersion(javaName, thisVersion));
}
System.out.println(" */");
System.out.printf(" static MeasureUnit *create%s(UErrorCode &status);\n\n", name);
if (isDraft(javaName)) {
System.out.println("#endif /* U_HIDE_DRAFT_API */");
}
}
}
}
private static void checkForDup(
Map<String, MeasureUnit> seen, String name, MeasureUnit unit) {
if (seen.containsKey(name)) {
throw new RuntimeException("\nCollision!!" + unit + ", " + seen.get(name));
} else {
seen.put(name, unit);
}
}
// DO NOT DELETE THIS FUNCTION! It may appear as dead code, but we use this to generate code
// for MeasureFormat during the release process.
static void updateJAVAVersions(String thisVersion) {
System.out.println();
Map<String, MeasureUnit> seen = new HashMap<String, MeasureUnit>();
TreeMap<String, List<MeasureUnit>> allUnits = getAllUnits();
for (Map.Entry<String, List<MeasureUnit>> entry : allUnits.entrySet()) {
String type = entry.getKey();
if (type.equals("currency")) {
continue;
}
for (MeasureUnit unit : entry.getValue()) {
String javaName = toJAVAName(unit);
checkForDup(seen, javaName, unit);
if (!JAVA_VERSION_MAP.containsKey(javaName)) {
System.out.printf(" {\"%s\", \"%s\"},\n", javaName, thisVersion);
}
}
}
}
static TreeMap<String, List<MeasureUnit>> getAllUnits() {
TreeMap<String, List<MeasureUnit>> allUnits = new TreeMap<String, List<MeasureUnit>>();
for (String type : MeasureUnit.getAvailableTypes()) {
ArrayList<MeasureUnit> units = new ArrayList<MeasureUnit>(MeasureUnit.getAvailable(type));
Collections.sort(
units,
new Comparator<MeasureUnit>() {
public int compare(MeasureUnit o1, MeasureUnit o2) {
return o1.getSubtype().compareTo(o2.getSubtype());
}
});
allUnits.put(type, units);
}
return allUnits;
}
// DO NOT DELETE THIS FUNCTION! It may appear as dead code, but we use this to generate code
// for MeasureFormat during the release process.
static void generateCXXConstants() {
System.out.println("static final MeasureUnit");
Map<String, MeasureUnit> seen = new HashMap<String, MeasureUnit>();
TreeMap<String, List<MeasureUnit>> allUnits = getAllUnits();
System.out.println("static const int32_t gOffsets[] = {");
int index = 0;
for (Map.Entry<String, List<MeasureUnit>> entry : allUnits.entrySet()) {
System.out.printf(" %d,\n", index);
index += entry.getValue().size();
}
System.out.printf(" %d\n", index);
System.out.println("};");
System.out.println();
System.out.println("static const int32_t gIndexes[] = {");
index = 0;
for (Map.Entry<String, List<MeasureUnit>> entry : allUnits.entrySet()) {
System.out.printf(" %d,\n", index);
if (!entry.getKey().equals("currency")) {
index += entry.getValue().size();
}
}
System.out.printf(" %d\n", index);
System.out.println("};");
System.out.println();
System.out.println("static const char * const gTypes[] = {");
boolean first = true;
for (Map.Entry<String, List<MeasureUnit>> entry : allUnits.entrySet()) {
if (!first) {
System.out.println(",");
}
System.out.print(" \"" + entry.getKey() + "\"");
first = false;
}
System.out.println();
System.out.println("};");
System.out.println();
System.out.println("static const char * const gSubTypes[] = {");
first = true;
for (Map.Entry<String, List<MeasureUnit>> entry : allUnits.entrySet()) {
for (MeasureUnit unit : entry.getValue()) {
if (!first) {
System.out.println(",");
}
System.out.print(" \"" + unit.getSubtype() + "\"");
first = false;
}
}
System.out.println();
System.out.println("};");
System.out.println();
int typeIdx = 0;
for (Map.Entry<String, List<MeasureUnit>> entry : allUnits.entrySet()) {
int subTypeIdx = 0;
String type = entry.getKey();
if (type.equals("currency")) {
typeIdx++;
continue;
}
for (MeasureUnit unit : entry.getValue()) {
String name = toCamelCase(unit);
String javaName = toJAVAName(unit);
checkForDup(seen, name, unit);
if (isDraft(javaName)) {
System.out.println("#ifndef U_HIDE_DRAFT_API");
}
System.out.printf("MeasureUnit *MeasureUnit::create%s(UErrorCode &status) {\n", name);
System.out.printf(" return MeasureUnit::create(%d, %d, status);\n", typeIdx, subTypeIdx);
System.out.println("}");
if (isDraft(javaName)) {
System.out.println("#endif /* U_HIDE_DRAFT_API */");
}
System.out.println();
subTypeIdx++;
}
typeIdx++;
}
}
private static String toCamelCase(MeasureUnit unit) {
StringBuilder result = new StringBuilder();
boolean caps = true;
String code = unit.getSubtype();
int len = code.length();
for (int i = 0; i < len; i++) {
char ch = code.charAt(i);
if (ch == '-') {
caps = true;
} else if (caps) {
result.append(Character.toUpperCase(ch));
caps = false;
} else {
result.append(ch);
}
}
return result.toString();
}
static boolean isTypeHidden(String type) {
return "currency".equals(type);
}
// DO NOT DELETE THIS FUNCTION! It may appear as dead code, but we use this to generate code
// for MeasureFormat during the release process.
static void generateBackwardCompatibilityTest(String version) {
Map<String, MeasureUnit> seen = new HashMap<String, MeasureUnit>();
System.out.println();
System.out.printf(" public void TestCompatible%s() {\n", version.replace(".", "_"));
System.out.println(" MeasureUnit[] units = {");
TreeMap<String, List<MeasureUnit>> allUnits = getAllUnits();
int count = 0;
for (Map.Entry<String, List<MeasureUnit>> entry : allUnits.entrySet()) {
if (isTypeHidden(entry.getKey())) {
continue;
}
for (MeasureUnit unit : entry.getValue()) {
String javaName = toJAVAName(unit);
checkForDup(seen, javaName, unit);
System.out.printf(" MeasureUnit.%s,\n", javaName);
count++;
}
}
System.out.println(" };");
System.out.printf(" assertEquals(\"\", %d, units.length);\n", count);
System.out.println(" }");
}
// DO NOT DELETE THIS FUNCTION! It may appear as dead code, but we use this to generate code
// for MeasureFormat during the release process.
static void generateCXXBackwardCompatibilityTest(String version) {
System.out.println();
Map<String, MeasureUnit> seen = new HashMap<String, MeasureUnit>();
System.out.printf("void MeasureFormatTest::TestCompatible%s() {\n", version.replace(".", "_"));
System.out.println(" UErrorCode status = U_ZERO_ERROR;");
System.out.println(" LocalPointer<MeasureUnit> measureUnit;");
TreeMap<String, List<MeasureUnit>> allUnits = getAllUnits();
for (Map.Entry<String, List<MeasureUnit>> entry : allUnits.entrySet()) {
if (isTypeHidden(entry.getKey())) {
continue;
}
for (MeasureUnit unit : entry.getValue()) {
String camelCase = toCamelCase(unit);
checkForDup(seen, camelCase, unit);
System.out.printf(" measureUnit.adoptInstead(MeasureUnit::create%s(status));\n", camelCase);
}
}
System.out.println(" assertSuccess(\"\", status);");
System.out.println("}");
}
static String toJAVAName(MeasureUnit unit) {
String code = unit.getSubtype();
String type = unit.getType();
String name = code.toUpperCase(Locale.ENGLISH).replace("-", "_");
if (type.equals("angle")) {
if (code.equals("minute") || code.equals("second")) {
name = "ARC_" + name;
}
}
return name;
}
// DO NOT DELETE THIS FUNCTION! It may appear as dead code, but we use this to generate code
// for MeasureFormat during the release process.
static void generateConstants(String thisVersion) {
System.out.println();
Map<String, MeasureUnit> seen = new HashMap<String, MeasureUnit>();
TreeMap<String, List<MeasureUnit>> allUnits = getAllUnits();
for (Map.Entry<String, List<MeasureUnit>> entry : allUnits.entrySet()) {
String type = entry.getKey();
if (isTypeHidden(type)) {
continue;
}
for (MeasureUnit unit : entry.getValue()) {
String name = toJAVAName(unit);
String code = unit.getSubtype();
checkForDup(seen, name, unit);
System.out.println(" /**");
System.out.println(" * Constant for unit of " + type +
": " +
code);
// Special case JAVA had old constants for time from before.
if ("duration".equals(type) && TIME_CODES.contains(code)) {
System.out.println(" * @stable ICU 4.0");
}
else if (isDraft(name)) {
System.out.println(" * @draft ICU " + getVersion(name, thisVersion));
System.out.println(" * @provisional This API might change or be removed in a future release.");
} else {
System.out.println(" * @stable ICU " + getVersion(name, thisVersion));
}
System.out.println(" */");
if ("duration".equals(type) && TIME_CODES.contains(code)) {
System.out.println(" public static final TimeUnit " + name + " = (TimeUnit) MeasureUnit.internalGetInstance(\"" +
type +
"\", \"" +
code +
"\");");
} else {
System.out.println(" public static final MeasureUnit " + name + " = MeasureUnit.internalGetInstance(\"" +
type +
"\", \"" +
code +
"\");");
}
System.out.println();
}
}
}
private static String getVersion(String javaName, String thisVersion) {
String version = JAVA_VERSION_MAP.get(javaName);
if (version == null) {
return thisVersion;
}
return version;
}
private static boolean isDraft(String javaName) {
String version = JAVA_VERSION_MAP.get(javaName);
if (version == null) {
return true;
}
return DRAFT_VERSION_SET.contains(version);
}
public <T extends Serializable> void checkStreamingEquality(T item) {
try {
ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteOut);
objectOutputStream.writeObject(item);
objectOutputStream.close();
byte[] contents = byteOut.toByteArray();
logln("bytes: " + contents.length + "; " + item.getClass() + ": " + showBytes(contents));
ByteArrayInputStream byteIn = new ByteArrayInputStream(contents);
ObjectInputStream objectInputStream = new ObjectInputStream(byteIn);
Object obj = objectInputStream.readObject();
assertEquals("Streamed Object equals ", item, obj);
} catch (IOException e) {
e.printStackTrace();
assertNull("Test Serialization " + item.getClass(), e);
} catch (ClassNotFoundException e) {
assertNull("Test Serialization " + item.getClass(), e);
}
}
/**
* @param contents
* @return
*/
private String showBytes(byte[] contents) {
StringBuilder b = new StringBuilder('[');
for (int i = 0; i < contents.length; ++i) {
int item = contents[i] & 0xFF;
if (item >= 0x20 && item <= 0x7F) {
b.append((char) item);
} else {
b.append('(').append(Utility.hex(item, 2)).append(')');
}
}
return b.append(']').toString();
}
private void verifyEqualsHashCode(Object o, Object eq, Object ne) {
assertEquals("verifyEqualsHashCodeSame", o, o);
assertEquals("verifyEqualsHashCodeEq", o, eq);
assertNotEquals("verifyEqualsHashCodeNe", o, ne);
assertNotEquals("verifyEqualsHashCodeEqTrans", eq, ne);
assertEquals("verifyEqualsHashCodeHashEq", o.hashCode(), eq.hashCode());
// May be a flaky test, but generally should be true.
// May need to comment this out later.
assertNotEquals("verifyEqualsHashCodeHashNe", o.hashCode(), ne.hashCode());
}
public static class MeasureUnitHandler implements SerializableTest.Handler
{
public Object[] getTestObjects()
{
MeasureUnit items[] = {
MeasureUnit.CELSIUS,
Currency.getInstance("EUR")
};
return items;
}
public boolean hasSameBehavior(Object a, Object b)
{
MeasureUnit a1 = (MeasureUnit) a;
MeasureUnit b1 = (MeasureUnit) b;
return a1.getType().equals(b1.getType())
&& a1.getSubtype().equals(b1.getSubtype());
}
}
public static class MeasureFormatHandler implements SerializableTest.Handler
{
public Object[] getTestObjects()
{
MeasureFormat items[] = {
MeasureFormat.getInstance(ULocale.FRANCE, FormatWidth.SHORT),
MeasureFormat.getInstance(
ULocale.FRANCE,
FormatWidth.WIDE,
NumberFormat.getIntegerInstance(ULocale.CANADA_FRENCH)),
};
return items;
}
public boolean hasSameBehavior(Object a, Object b)
{
MeasureFormat a1 = (MeasureFormat) a;
MeasureFormat b1 = (MeasureFormat) b;
return a1.getLocale().equals(b1.getLocale())
&& a1.getWidth().equals(b1.getWidth())
&& a1.getNumberFormat().equals(b1.getNumberFormat())
;
}
}
}