2 *******************************************************************************
3 * Copyright (C) 2013, International Business Machines Corporation and *
4 * others. All Rights Reserved. *
5 *******************************************************************************
7 package com.ibm.icu.dev.test.format;
9 import java.io.ByteArrayInputStream;
10 import java.io.ByteArrayOutputStream;
11 import java.io.IOException;
12 import java.io.ObjectInputStream;
13 import java.io.ObjectOutputStream;
14 import java.io.Serializable;
15 import java.text.FieldPosition;
16 import java.text.ParsePosition;
17 import java.util.HashMap;
18 import java.util.Locale;
20 import java.util.TreeSet;
22 import com.ibm.icu.dev.test.TestFmwk;
23 import com.ibm.icu.dev.test.serializable.SerializableTest;
24 import com.ibm.icu.impl.Utility;
25 import com.ibm.icu.text.DecimalFormat;
26 import com.ibm.icu.text.GeneralMeasureFormat;
27 import com.ibm.icu.text.NumberFormat;
28 import com.ibm.icu.util.Currency;
29 import com.ibm.icu.util.FormatWidth;
30 import com.ibm.icu.util.Measure;
31 import com.ibm.icu.util.MeasureUnit;
32 import com.ibm.icu.util.ULocale;
37 public class MeasureUnitTest extends TestFmwk {
42 public static void main(String[] args) {
43 //generateConstants(); if (true) return;
44 new MeasureUnitTest().run(args);
47 public void testAUnit() {
48 String lastType = null;
49 for (MeasureUnit expected : MeasureUnit.getAvailable()) {
50 String type = expected.getType();
51 String code = expected.getCode();
52 if (!type.equals(lastType)) {
56 MeasureUnit actual = MeasureUnit.getInstance(type, code);
57 assertSame("Identity check", expected, actual);
61 public void testMultiples() {
62 for (ULocale locale : new ULocale[]{
68 for (FormatWidth style : FormatWidth.values()) {
69 GeneralMeasureFormat gmlf = GeneralMeasureFormat.getInstance(locale, style);
70 String formatted = gmlf.format(
71 new Measure(2, MeasureUnit.MILE),
72 new Measure(1, MeasureUnit.FOOT),
73 new Measure(2.3, MeasureUnit.INCH));
74 logln(locale + ",\t" + style + ": " + formatted);
80 public void testGram() {
81 checkRoundtrip(ULocale.ENGLISH, MeasureUnit.GRAM, 1, 0, FormatWidth.SHORT);
82 checkRoundtrip(ULocale.ENGLISH, MeasureUnit.G_FORCE, 1, 0, FormatWidth.SHORT);
85 public void testRoundtripFormat() {
86 for (ULocale locale : new ULocale[]{
91 for (MeasureUnit unit : MeasureUnit.getAvailable()) {
92 for (double d : new double[]{2.1, 1}) {
93 for (int fractionalDigits : new int[]{0, 1}) {
94 for (FormatWidth style : FormatWidth.values()) {
95 checkRoundtrip(locale, unit, d, fractionalDigits, style);
103 private void checkRoundtrip(ULocale locale, MeasureUnit unit, double d, int fractionalDigits, FormatWidth style) {
104 if (unit instanceof Currency) {
105 return; // known limitation
107 Measure amount = new Measure(d, unit);
108 String header = locale
111 + "\t" + fractionalDigits;
112 ParsePosition pex = new ParsePosition(0);
113 NumberFormat nformat = NumberFormat.getInstance(locale);
114 nformat.setMinimumFractionDigits(fractionalDigits);
116 GeneralMeasureFormat format = GeneralMeasureFormat.getInstance(locale, style, nformat);
118 FieldPosition pos = new FieldPosition(DecimalFormat.FRACTION_FIELD);
119 StringBuffer b = format.format(amount, new StringBuffer(), pos);
120 String message = header + "\t" + style
121 + "\t«" + b.substring(0, pos.getBeginIndex())
122 + "⟪" + b.substring(pos.getBeginIndex(), pos.getEndIndex())
123 + "⟫" + b.substring(pos.getEndIndex()) + "»";
125 Measure unitAmount = format.parseObject(b.toString(), pex);
126 if (!assertNotNull(message, unitAmount)) {
128 + b.substring(0,pex.getErrorIndex())
129 + "||" + b.substring(pex.getErrorIndex()) + "»");
130 } else if (style != FormatWidth.NARROW) { // narrow items may collide
131 if (unit.equals(MeasureUnit.GRAM)) {
132 logKnownIssue("cldrupdate", "waiting on collision fix for gram");
135 if (unit.equals(MeasureUnit.ARC_MINUTE) || unit.equals(MeasureUnit.ARC_SECOND) || unit.equals(MeasureUnit.METER)) {
136 logKnownIssue("8474", "Waiting for CLDR data");
138 assertEquals(message + "\tParse Roundtrip of unit", unit, unitAmount.getUnit());
140 double actualNumber = unitAmount.getNumber().doubleValue();
141 assertEquals(message + "\tParse Roundtrip of number", d, actualNumber);
145 public void testExamples() {
146 GeneralMeasureFormat fmtFr = GeneralMeasureFormat.getInstance(ULocale.FRENCH, FormatWidth.SHORT);
147 Measure measure = new Measure(23, MeasureUnit.CELSIUS);
148 assertEquals("", "23°C", fmtFr.format(measure));
150 Measure measureF = new Measure(70, MeasureUnit.FAHRENHEIT);
151 assertEquals("", "70°F", fmtFr.format(measureF));
153 GeneralMeasureFormat fmtFrFull = GeneralMeasureFormat.getInstance(ULocale.FRENCH, FormatWidth.WIDE);
154 if (!logKnownIssue("8474", "needs latest CLDR data")) {
155 assertEquals("", "70 pieds, 5,3 pouces", fmtFrFull.format(new Measure(70, MeasureUnit.FOOT),
156 new Measure(5.3, MeasureUnit.INCH)));
157 assertEquals("", "1 pied, 1 pouce", fmtFrFull.format(new Measure(1, MeasureUnit.FOOT),
158 new Measure(1, MeasureUnit.INCH)));
161 GeneralMeasureFormat fmtEn = GeneralMeasureFormat.getInstance(ULocale.ENGLISH, FormatWidth.WIDE);
162 assertEquals("", "1 inch, 2 feet", fmtEn.format(new Measure(1, MeasureUnit.INCH),
163 new Measure(2, MeasureUnit.FOOT)));
165 logln("Show all currently available units");
166 String lastType = null;
167 for (MeasureUnit unit : MeasureUnit.getAvailable()) {
168 String type = unit.getType();
169 if (!type.equals(lastType)) {
176 // Add these examples (and others) to the class definition.
177 // Clarify that these classes *do not* do conversion; they simply do the formatting of whatever units they
181 static void generateConstants() {
182 System.out.println("static final MeasureUnit");
183 Map<String, MeasureUnit> seen = new HashMap<String, MeasureUnit>();
184 boolean first = true;
185 for (String type : new TreeSet<String>(MeasureUnit.getAvailableTypes())) {
186 for (MeasureUnit unit : MeasureUnit.getAvailable(type)) {
187 String code = unit.getCode();
188 String name = code.toUpperCase(Locale.ENGLISH).replace("-", "_");
190 if (type.equals("angle")) {
191 if (code.equals("minute") || code.equals("second")) {
192 name = "ARC_" + name;
198 System.out.print(",");
200 if (seen.containsKey(name)) {
201 System.out.println("\nCollision!!" + unit + ", " + seen.get(name));
203 seen.put(name, unit);
205 System.out.println("\n\t/** Constant for unit of " + type +
210 System.out.print("\t" + name + " = MeasureUnit.getInstance(\"" +
216 System.out.println(";");
220 public void TestSerial() {
221 checkStreamingEquality(MeasureUnit.CELSIUS);
222 checkStreamingEquality(GeneralMeasureFormat.getInstance(ULocale.FRANCE, FormatWidth.NARROW));
223 checkStreamingEquality(Currency.getInstance("EUR"));
226 public <T extends Serializable> void checkStreamingEquality(T item) {
228 ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
229 ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteOut);
230 objectOutputStream.writeObject(item);
231 objectOutputStream.close();
232 byte[] contents = byteOut.toByteArray();
233 logln("bytes: " + contents.length + "; " + item.getClass() + ": " + showBytes(contents));
234 ByteArrayInputStream byteIn = new ByteArrayInputStream(contents);
235 ObjectInputStream objectInputStream = new ObjectInputStream(byteIn);
236 Object obj = objectInputStream.readObject();
237 assertEquals("Streamed Object equals ", item, obj);
238 } catch (IOException e) {
239 assertNull("Test Serialization " + item.getClass(), e);
240 } catch (ClassNotFoundException e) {
241 assertNull("Test Serialization " + item.getClass(), e);
249 private String showBytes(byte[] contents) {
250 StringBuilder b = new StringBuilder('[');
251 for (int i = 0; i < contents.length; ++i) {
252 int item = contents[i] & 0xFF;
253 if (item >= 0x20 && item <= 0x7F) {
254 b.append((char) item);
256 b.append('(').append(Utility.hex(item, 2)).append(')');
259 return b.append(']').toString();
262 public static class MeasureUnitHandler implements SerializableTest.Handler
264 public Object[] getTestObjects()
266 MeasureUnit items[] = {
268 Currency.getInstance("EUR")
273 public boolean hasSameBehavior(Object a, Object b)
275 MeasureUnit a1 = (MeasureUnit) a;
276 MeasureUnit b1 = (MeasureUnit) b;
277 return a1.getType().equals(b1.getType())
278 && a1.getCode().equals(b1.getCode());
282 public static class GeneralMeasureFormatHandler implements SerializableTest.Handler
284 public Object[] getTestObjects()
286 GeneralMeasureFormat items[] = {
287 GeneralMeasureFormat.getInstance(ULocale.FRANCE, FormatWidth.SHORT),
288 GeneralMeasureFormat.getInstance(ULocale.FRANCE, FormatWidth.WIDE, NumberFormat.getIntegerInstance(ULocale.CANADA_FRENCH
294 public boolean hasSameBehavior(Object a, Object b)
296 GeneralMeasureFormat a1 = (GeneralMeasureFormat) a;
297 GeneralMeasureFormat b1 = (GeneralMeasureFormat) b;
298 return a1.getLocale().equals(b1.getLocale())
299 && a1.getLength().equals(b1.getLength())
300 // && a1.getNumberFormat().equals(b1.getNumberFormat())