]> gitweb.fperrin.net Git - Dictionary.git/blob - jars/icu4j-52_1/main/tests/core/src/com/ibm/icu/dev/test/format/MeasureUnitTest.java
Upgrade ICU4J.
[Dictionary.git] / jars / icu4j-52_1 / main / tests / core / src / com / ibm / icu / dev / test / format / MeasureUnitTest.java
1 /*
2  *******************************************************************************
3  * Copyright (C) 2013, International Business Machines Corporation and         *
4  * others. All Rights Reserved.                                                *
5  *******************************************************************************
6  */
7 package com.ibm.icu.dev.test.format;
8
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;
19 import java.util.Map;
20 import java.util.TreeSet;
21
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;
33
34 /**
35  * @author markdavis
36  */
37 public class MeasureUnitTest extends TestFmwk {
38     /**
39      * @author markdavis
40      *
41      */
42     public static void main(String[] args) {
43         //generateConstants(); if (true) return;
44         new MeasureUnitTest().run(args);
45     }
46
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)) {
53                 logln(type);
54                 lastType = type;
55             }
56             MeasureUnit actual = MeasureUnit.getInstance(type, code);
57             assertSame("Identity check", expected, actual);
58         }
59     }
60
61     public void testMultiples() {
62         for (ULocale locale : new ULocale[]{
63                 ULocale.ENGLISH, 
64                 new ULocale("ru"), 
65                 //ULocale.JAPANESE
66         }) {
67
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);
75             }
76
77         }
78     }
79
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);
83     }
84
85     public void testRoundtripFormat() {        
86         for (ULocale locale : new ULocale[]{
87                 ULocale.ENGLISH, 
88                 new ULocale("ru"), 
89                 //ULocale.JAPANESE
90         }) {
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);
96                         }
97                     }
98                 }
99             }
100         }
101     }
102
103     private void checkRoundtrip(ULocale locale, MeasureUnit unit, double d, int fractionalDigits, FormatWidth style) {
104         if (unit instanceof Currency) {
105             return; // known limitation
106         }
107         Measure amount = new Measure(d, unit);
108         String header = locale
109                 + "\t" + unit
110                 + "\t" + d
111                 + "\t" + fractionalDigits;
112         ParsePosition pex = new ParsePosition(0);
113         NumberFormat nformat = NumberFormat.getInstance(locale);
114         nformat.setMinimumFractionDigits(fractionalDigits);
115
116         GeneralMeasureFormat format = GeneralMeasureFormat.getInstance(locale, style, nformat);
117         
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()) + "»";
124         pex.setIndex(0);
125         Measure unitAmount = format.parseObject(b.toString(), pex);
126         if (!assertNotNull(message, unitAmount)) {
127             logln("Parse: «" 
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");
133                 return;
134             }
135             if (unit.equals(MeasureUnit.ARC_MINUTE) || unit.equals(MeasureUnit.ARC_SECOND) || unit.equals(MeasureUnit.METER)) {
136                 logKnownIssue("8474", "Waiting for CLDR data");
137             } else {
138                 assertEquals(message + "\tParse Roundtrip of unit", unit, unitAmount.getUnit());
139             }
140             double actualNumber = unitAmount.getNumber().doubleValue();
141             assertEquals(message + "\tParse Roundtrip of number", d, actualNumber);
142         }
143     }
144
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));
149
150         Measure measureF = new Measure(70, MeasureUnit.FAHRENHEIT);
151         assertEquals("", "70°F", fmtFr.format(measureF));
152
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)));
159         }
160         // Degenerate case
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)));
164
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)) {
170                 logln(type);
171                 lastType = type;
172             }
173             logln("\t" + unit);
174         }
175         // TODO 
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
178         // are provided.
179     }
180
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("-", "_");
189
190                 if (type.equals("angle")) {
191                     if (code.equals("minute") || code.equals("second")) {
192                         name = "ARC_" + name;
193                     }
194                 }
195                 if (first) {
196                     first = false;
197                 } else {
198                     System.out.print(",");
199                 }
200                 if (seen.containsKey(name)) {
201                     System.out.println("\nCollision!!" + unit + ", " + seen.get(name));
202                 } else {
203                     seen.put(name, unit);
204                 }
205                 System.out.println("\n\t/** Constant for unit of " + type +
206                         ": " +
207                         code +
208                         " */");
209
210                 System.out.print("\t" + name + " = MeasureUnit.getInstance(\"" +
211                         type +
212                         "\", \"" +
213                         code +
214                         "\")");
215             }
216             System.out.println(";");
217         }
218     }
219     
220     public void TestSerial() {
221         checkStreamingEquality(MeasureUnit.CELSIUS);
222         checkStreamingEquality(GeneralMeasureFormat.getInstance(ULocale.FRANCE, FormatWidth.NARROW));
223         checkStreamingEquality(Currency.getInstance("EUR"));
224     }
225     
226     public <T extends Serializable> void checkStreamingEquality(T item) {
227         try {
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);
242         }
243       }
244
245     /**
246      * @param contents
247      * @return
248      */
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);
255         } else {
256           b.append('(').append(Utility.hex(item, 2)).append(')');
257         }
258       }
259       return b.append(']').toString();
260     }
261     
262     public static class MeasureUnitHandler implements SerializableTest.Handler
263     {
264         public Object[] getTestObjects()
265         {
266             MeasureUnit items[] = {
267                     MeasureUnit.CELSIUS,
268                     Currency.getInstance("EUR")               
269             };
270             return items;
271         }
272
273         public boolean hasSameBehavior(Object a, Object b)
274         {
275             MeasureUnit a1 = (MeasureUnit) a;
276             MeasureUnit b1 = (MeasureUnit) b;
277             return a1.getType().equals(b1.getType()) 
278                     && a1.getCode().equals(b1.getCode());
279         }
280     }
281     
282     public static class GeneralMeasureFormatHandler  implements SerializableTest.Handler
283     {
284         public Object[] getTestObjects()
285         {
286             GeneralMeasureFormat items[] = {
287                     GeneralMeasureFormat.getInstance(ULocale.FRANCE, FormatWidth.SHORT),
288                     GeneralMeasureFormat.getInstance(ULocale.FRANCE, FormatWidth.WIDE, NumberFormat.getIntegerInstance(ULocale.CANADA_FRENCH
289                             )),
290             };
291             return items;
292         }
293
294         public boolean hasSameBehavior(Object a, Object b)
295         {
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())
301                     ;
302         }
303     }
304 }