LEFT | RIGHT |
(no file at all) | |
1 // © 2017 and later: Unicode, Inc. and others. | 1 // © 2017 and later: Unicode, Inc. and others. |
2 // License & terms of use: http://www.unicode.org/copyright.html#License | 2 // License & terms of use: http://www.unicode.org/copyright.html#License |
3 package com.ibm.icu.dev.test.number; | 3 package com.ibm.icu.dev.test.number; |
4 | 4 |
5 import static org.junit.Assert.assertEquals; | 5 import static org.junit.Assert.assertEquals; |
6 import static org.junit.Assert.assertNotEquals; | 6 import static org.junit.Assert.assertNotEquals; |
7 import static org.junit.Assert.assertTrue; | 7 import static org.junit.Assert.assertTrue; |
8 import static org.junit.Assert.fail; | 8 import static org.junit.Assert.fail; |
9 | 9 |
10 import java.io.ByteArrayInputStream; | 10 import java.io.ByteArrayInputStream; |
(...skipping 27 matching lines...) Expand all Loading... |
38 import com.ibm.icu.text.CurrencyPluralInfo; | 38 import com.ibm.icu.text.CurrencyPluralInfo; |
39 import com.ibm.icu.text.MeasureFormat.FormatWidth; | 39 import com.ibm.icu.text.MeasureFormat.FormatWidth; |
40 import com.ibm.icu.text.PluralRules; | 40 import com.ibm.icu.text.PluralRules; |
41 import com.ibm.icu.util.Currency; | 41 import com.ibm.icu.util.Currency; |
42 import com.ibm.icu.util.Currency.CurrencyUsage; | 42 import com.ibm.icu.util.Currency.CurrencyUsage; |
43 import com.ibm.icu.util.MeasureUnit; | 43 import com.ibm.icu.util.MeasureUnit; |
44 import com.ibm.icu.util.ULocale; | 44 import com.ibm.icu.util.ULocale; |
45 | 45 |
46 public class PropertiesTest { | 46 public class PropertiesTest { |
47 | 47 |
48 @Test | 48 @Test |
49 public void testBasicEquals() { | 49 public void testBasicEquals() { |
50 DecimalFormatProperties p1 = new DecimalFormatProperties(); | 50 DecimalFormatProperties p1 = new DecimalFormatProperties(); |
51 DecimalFormatProperties p2 = new DecimalFormatProperties(); | 51 DecimalFormatProperties p2 = new DecimalFormatProperties(); |
52 assertEquals(p1, p2); | |
53 | |
54 p1.setPositivePrefix("abc"); | |
55 assertNotEquals(p1, p2); | |
56 p2.setPositivePrefix("xyz"); | |
57 assertNotEquals(p1, p2); | |
58 p1.setPositivePrefix("xyz"); | |
59 assertEquals(p1, p2); | |
60 } | |
61 | |
62 @Test | |
63 public void testFieldCoverage() { | |
64 DecimalFormatProperties p0 = new DecimalFormatProperties(); | |
65 DecimalFormatProperties p1 = new DecimalFormatProperties(); | |
66 DecimalFormatProperties p2 = new DecimalFormatProperties(); | |
67 DecimalFormatProperties p3 = new DecimalFormatProperties(); | |
68 DecimalFormatProperties p4 = new DecimalFormatProperties(); | |
69 | |
70 Set<Integer> hashCodes = new HashSet<Integer>(); | |
71 Field[] fields = DecimalFormatProperties.class.getDeclaredFields(); | |
72 for (Field field : fields) { | |
73 if (Modifier.isStatic(field.getModifiers())) { | |
74 continue; | |
75 } | |
76 | |
77 // Check for getters and setters | |
78 String fieldNamePascalCase = | |
79 Character.toUpperCase(field.getName().charAt(0)) + field.getName().sub
string(1); | |
80 String getterName = "get" + fieldNamePascalCase; | |
81 String setterName = "set" + fieldNamePascalCase; | |
82 Method getter, setter; | |
83 try { | |
84 getter = DecimalFormatProperties.class.getMethod(getterName); | |
85 assertEquals( | |
86 "Getter does not return correct type", field.getType(), getter.getRe
turnType()); | |
87 } catch (NoSuchMethodException e) { | |
88 fail("Could not find method " + getterName + " for field " + field); | |
89 continue; | |
90 } catch (SecurityException e) { | |
91 fail("Could not access method " + getterName + " for field " + field); | |
92 continue; | |
93 } | |
94 try { | |
95 setter = DecimalFormatProperties.class.getMethod(setterName, field.getTy
pe()); | |
96 assertEquals( | |
97 "Method " + setterName + " does not return correct type", | |
98 DecimalFormatProperties.class, | |
99 setter.getReturnType()); | |
100 } catch (NoSuchMethodException e) { | |
101 fail("Could not find method " + setterName + " for field " + field); | |
102 continue; | |
103 } catch (SecurityException e) { | |
104 fail("Could not access method " + setterName + " for field " + field); | |
105 continue; | |
106 } | |
107 | |
108 // Check for parameter name equality. | |
109 // The parameter name is not always available, depending on compiler setti
ngs. | |
110 // TODO: Enable in Java 8 | |
111 /* | |
112 Parameter param = setter.getParameters()[0]; | |
113 if (!param.getName().subSequence(0, 3).equals("arg")) { | |
114 assertEquals("Parameter name should equal field name", field.getName(),
param.getName()); | |
115 } | |
116 */ | |
117 | |
118 try { | |
119 // Check for default value (should be null for objects) | |
120 if (field.getType() != Integer.TYPE && field.getType() != Boolean.TYPE)
{ | |
121 Object default0 = getter.invoke(p0); | |
122 assertEquals("Field " + field + " has non-null default value:", null,
default0); | |
123 } | |
124 | |
125 // Check for getter, equals, and hash code behavior | |
126 Object val0 = getSampleValueForType(field.getType(), 0); | |
127 Object val1 = getSampleValueForType(field.getType(), 1); | |
128 Object val2 = getSampleValueForType(field.getType(), 2); | |
129 assertNotEquals(val0, val1); | |
130 setter.invoke(p1, val0); | |
131 setter.invoke(p2, val0); | |
132 assertEquals(p1, p2); | 52 assertEquals(p1, p2); |
133 assertEquals(p1.hashCode(), p2.hashCode()); | 53 |
134 assertEquals(getter.invoke(p1), getter.invoke(p2)); | 54 p1.setPositivePrefix("abc"); |
135 assertEquals(getter.invoke(p1), val0); | 55 assertNotEquals(p1, p2); |
136 assertNotEquals(getter.invoke(p1), val1); | 56 p2.setPositivePrefix("xyz"); |
137 hashCodes.add(p1.hashCode()); | 57 assertNotEquals(p1, p2); |
138 setter.invoke(p1, val1); | 58 p1.setPositivePrefix("xyz"); |
139 assertNotEquals("Field " + field + " is missing from equals()", p1, p2); | |
140 assertNotEquals(getter.invoke(p1), getter.invoke(p2)); | |
141 assertNotEquals(getter.invoke(p1), val0); | |
142 assertEquals(getter.invoke(p1), val1); | |
143 setter.invoke(p1, val0); | |
144 assertEquals("Field " + field + " setter might have side effects", p1, p
2); | |
145 assertEquals(p1.hashCode(), p2.hashCode()); | |
146 assertEquals(getter.invoke(p1), getter.invoke(p2)); | |
147 setter.invoke(p1, val1); | |
148 setter.invoke(p2, val1); | |
149 assertEquals(p1, p2); | 59 assertEquals(p1, p2); |
150 assertEquals(p1.hashCode(), p2.hashCode()); | 60 } |
151 assertEquals(getter.invoke(p1), getter.invoke(p2)); | 61 |
152 setter.invoke(p1, val2); | 62 @Test |
153 setter.invoke(p1, val1); | 63 public void testFieldCoverage() { |
154 assertEquals("Field " + field + " setter might have side effects", p1, p
2); | 64 DecimalFormatProperties p0 = new DecimalFormatProperties(); |
155 assertEquals(p1.hashCode(), p2.hashCode()); | 65 DecimalFormatProperties p1 = new DecimalFormatProperties(); |
156 assertEquals(getter.invoke(p1), getter.invoke(p2)); | 66 DecimalFormatProperties p2 = new DecimalFormatProperties(); |
157 hashCodes.add(p1.hashCode()); | 67 DecimalFormatProperties p3 = new DecimalFormatProperties(); |
158 | 68 DecimalFormatProperties p4 = new DecimalFormatProperties(); |
159 // Check for clone behavior | 69 |
160 DecimalFormatProperties copy = p1.clone(); | 70 Set<Integer> hashCodes = new HashSet<Integer>(); |
161 assertEquals("Field " + field + " did not get copied in clone", p1, copy
); | 71 Field[] fields = DecimalFormatProperties.class.getDeclaredFields(); |
162 assertEquals(p1.hashCode(), copy.hashCode()); | 72 for (Field field : fields) { |
163 assertEquals(getter.invoke(p1), getter.invoke(copy)); | 73 if (Modifier.isStatic(field.getModifiers())) { |
164 | 74 continue; |
165 // Check for copyFrom behavior | 75 } |
166 setter.invoke(p1, val0); | 76 |
167 assertNotEquals(p1, p2); | 77 // Check for getters and setters |
168 assertNotEquals(getter.invoke(p1), getter.invoke(p2)); | 78 String fieldNamePascalCase = Character.toUpperCase(field.getName().c
harAt(0)) |
169 p2.copyFrom(p1); | 79 + field.getName().substring(1); |
170 assertEquals("Field " + field + " is missing from copyFrom()", p1, p2); | 80 String getterName = "get" + fieldNamePascalCase; |
171 assertEquals(p1.hashCode(), p2.hashCode()); | 81 String setterName = "set" + fieldNamePascalCase; |
172 assertEquals(getter.invoke(p1), getter.invoke(p2)); | 82 Method getter, setter; |
173 | 83 try { |
174 // Load values into p3 and p4 for clear() behavior test | 84 getter = DecimalFormatProperties.class.getMethod(getterName); |
175 setter.invoke(p3, getSampleValueForType(field.getType(), 3)); | 85 assertEquals("Getter does not return correct type", |
176 hashCodes.add(p3.hashCode()); | 86 field.getType(), |
177 setter.invoke(p4, getSampleValueForType(field.getType(), 4)); | 87 getter.getReturnType()); |
178 hashCodes.add(p4.hashCode()); | 88 } catch (NoSuchMethodException e) { |
179 } catch (IllegalAccessException e) { | 89 fail("Could not find method " + getterName + " for field " + fie
ld); |
180 fail("Could not access method for field " + field); | 90 continue; |
181 } catch (IllegalArgumentException e) { | 91 } catch (SecurityException e) { |
182 fail("Could call method for field " + field); | 92 fail("Could not access method " + getterName + " for field " + f
ield); |
183 } catch (InvocationTargetException e) { | 93 continue; |
184 fail("Could invoke method on target for field " + field); | 94 } |
185 } | 95 try { |
186 } | 96 setter = DecimalFormatProperties.class.getMethod(setterName, fie
ld.getType()); |
187 | 97 assertEquals("Method " + setterName + " does not return correct
type", |
188 // Check for clear() behavior | 98 DecimalFormatProperties.class, |
189 assertNotEquals(p3, p4); | 99 setter.getReturnType()); |
190 p3.clear(); | 100 } catch (NoSuchMethodException e) { |
191 p4.clear(); | 101 fail("Could not find method " + setterName + " for field " + fie
ld); |
192 assertEquals("A field is missing from the clear() function", p3, p4); | 102 continue; |
193 | 103 } catch (SecurityException e) { |
194 // A good hashCode() implementation should produce very few collisions. We
added at most | 104 fail("Could not access method " + setterName + " for field " + f
ield); |
195 // 4*fields.length codes to the set. We'll say the implementation is good i
f we had at least | 105 continue; |
196 // fields.length unique values. | 106 } |
197 // TODO: Should the requirement be stronger than this? | 107 |
198 assertTrue( | 108 // Check for parameter name equality. |
199 "Too many hash code collisions: " + hashCodes.size() + " out of " + (fie
lds.length * 4), | 109 // The parameter name is not always available, depending on compiler
settings. |
200 hashCodes.size() >= fields.length); | 110 // TODO: Enable in Java 8 |
201 } | 111 /* |
202 | 112 * Parameter param = setter.getParameters()[0]; if (!param.getName()
.subSequence(0, |
203 /** | 113 * 3).equals("arg")) { assertEquals("Parameter name should equal fie
ld name", |
204 * Creates a valid sample instance of the given type. Used to simulate getters
and setters. | 114 * field.getName(), param.getName()); } |
205 * | 115 */ |
206 * @param type The type to generate. | 116 |
207 * @param seed An integer seed, guaranteed to be positive. The same seed shoul
d generate two | 117 try { |
208 * instances that are equal. A different seed should in general generate t
wo instances that | 118 // Check for default value (should be null for objects) |
209 * are not equal; this might not always be possible, such as with booleans
or enums where | 119 if (field.getType() != Integer.TYPE && field.getType() != Boolea
n.TYPE) { |
210 * there are limited possible values. | 120 Object default0 = getter.invoke(p0); |
211 * @return An instance of the specified type. | 121 assertEquals("Field " + field + " has non-null default value
:", null, default0); |
212 */ | 122 } |
213 Object getSampleValueForType(Class<?> type, int seed) { | 123 |
214 if (type == Integer.TYPE) { | 124 // Check for getter, equals, and hash code behavior |
215 return seed * 1000001; | 125 Object val0 = getSampleValueForType(field.getType(), 0); |
216 | 126 Object val1 = getSampleValueForType(field.getType(), 1); |
217 } else if (type == Boolean.TYPE) { | 127 Object val2 = getSampleValueForType(field.getType(), 2); |
218 return (seed % 2) == 0; | 128 assertNotEquals(val0, val1); |
219 | 129 setter.invoke(p1, val0); |
220 } else if (type == BigDecimal.class) { | 130 setter.invoke(p2, val0); |
221 if (seed == 0) return null; | 131 assertEquals(p1, p2); |
222 return new BigDecimal(seed * 1000002); | 132 assertEquals(p1.hashCode(), p2.hashCode()); |
223 | 133 assertEquals(getter.invoke(p1), getter.invoke(p2)); |
224 } else if (type == String.class) { | 134 assertEquals(getter.invoke(p1), val0); |
225 if (seed == 0) return null; | 135 assertNotEquals(getter.invoke(p1), val1); |
226 return BigInteger.valueOf(seed * 1000003).toString(32); | 136 hashCodes.add(p1.hashCode()); |
227 | 137 setter.invoke(p1, val1); |
228 } else if (type == CompactStyle.class) { | 138 assertNotEquals("Field " + field + " is missing from equals()",
p1, p2); |
229 if (seed == 0) return null; | 139 assertNotEquals(getter.invoke(p1), getter.invoke(p2)); |
230 CompactStyle[] values = CompactStyle.values(); | 140 assertNotEquals(getter.invoke(p1), val0); |
231 return values[seed % values.length]; | 141 assertEquals(getter.invoke(p1), val1); |
232 | 142 setter.invoke(p1, val0); |
233 } else if (type == Currency.class) { | 143 assertEquals("Field " + field + " setter might have side effects
", p1, p2); |
234 if (seed == 0) return null; | 144 assertEquals(p1.hashCode(), p2.hashCode()); |
235 Object[] currencies = Currency.getAvailableCurrencies().toArray(); | 145 assertEquals(getter.invoke(p1), getter.invoke(p2)); |
236 return currencies[seed % currencies.length]; | 146 setter.invoke(p1, val1); |
237 | 147 setter.invoke(p2, val1); |
238 } else if (type == CurrencyPluralInfo.class) { | 148 assertEquals(p1, p2); |
239 if (seed == 0) return null; | 149 assertEquals(p1.hashCode(), p2.hashCode()); |
240 ULocale[] locales = ULocale.getAvailableLocales(); | 150 assertEquals(getter.invoke(p1), getter.invoke(p2)); |
241 return CurrencyPluralInfo.getInstance(locales[seed % locales.length]); | 151 setter.invoke(p1, val2); |
242 | 152 setter.invoke(p1, val1); |
243 } else if (type == CurrencyUsage.class) { | 153 assertEquals("Field " + field + " setter might have side effects
", p1, p2); |
244 if (seed == 0) return null; | 154 assertEquals(p1.hashCode(), p2.hashCode()); |
245 CurrencyUsage[] values = CurrencyUsage.values(); | 155 assertEquals(getter.invoke(p1), getter.invoke(p2)); |
246 return values[seed % values.length]; | 156 hashCodes.add(p1.hashCode()); |
247 | 157 |
248 } else if (type == GroupingMode.class) { | 158 // Check for clone behavior |
249 if (seed == 0) return null; | 159 DecimalFormatProperties copy = p1.clone(); |
250 GroupingMode[] values = GroupingMode.values(); | 160 assertEquals("Field " + field + " did not get copied in clone",
p1, copy); |
251 return values[seed % values.length]; | 161 assertEquals(p1.hashCode(), copy.hashCode()); |
252 | 162 assertEquals(getter.invoke(p1), getter.invoke(copy)); |
253 } else if (type == FormatWidth.class) { | 163 |
254 if (seed == 0) return null; | 164 // Check for copyFrom behavior |
255 FormatWidth[] values = FormatWidth.values(); | 165 setter.invoke(p1, val0); |
256 return values[seed % values.length]; | 166 assertNotEquals(p1, p2); |
257 | 167 assertNotEquals(getter.invoke(p1), getter.invoke(p2)); |
258 } else if (type == Map.class) { | 168 p2.copyFrom(p1); |
259 // Map<String,Map<String,String>> for compactCustomData property | 169 assertEquals("Field " + field + " is missing from copyFrom()", p
1, p2); |
260 if (seed == 0) return null; | 170 assertEquals(p1.hashCode(), p2.hashCode()); |
261 Map<String, Map<String, String>> outer = new HashMap<String, Map<String, S
tring>>(); | 171 assertEquals(getter.invoke(p1), getter.invoke(p2)); |
262 Map<String, String> inner = new HashMap<String, String>(); | 172 |
263 inner.put("one", "0 thousand"); | 173 // Load values into p3 and p4 for clear() behavior test |
264 StringBuilder magnitudeKey = new StringBuilder(); | 174 setter.invoke(p3, getSampleValueForType(field.getType(), 3)); |
265 magnitudeKey.append("1000"); | 175 hashCodes.add(p3.hashCode()); |
266 for (int i = 0; i < seed % 9; i++) { | 176 setter.invoke(p4, getSampleValueForType(field.getType(), 4)); |
267 magnitudeKey.append("0"); | 177 hashCodes.add(p4.hashCode()); |
268 } | 178 } catch (IllegalAccessException e) { |
269 outer.put(magnitudeKey.toString(), inner); | 179 fail("Could not access method for field " + field); |
270 return outer; | 180 } catch (IllegalArgumentException e) { |
271 | 181 fail("Could call method for field " + field); |
272 } else if (type == MathContext.class) { | 182 } catch (InvocationTargetException e) { |
273 if (seed == 0) return null; | 183 fail("Could invoke method on target for field " + field); |
274 RoundingMode[] modes = RoundingMode.values(); | 184 } |
275 return new MathContext(seed, modes[seed % modes.length]); | 185 } |
276 | 186 |
277 } else if (type == MeasureUnit.class) { | 187 // Check for clear() behavior |
278 if (seed == 0) return null; | 188 assertNotEquals(p3, p4); |
279 Object[] units = MeasureUnit.getAvailable().toArray(); | 189 p3.clear(); |
280 return units[seed % units.length]; | 190 p4.clear(); |
281 | 191 assertEquals("A field is missing from the clear() function", p3, p4); |
282 } else if (type == PadPosition.class) { | 192 |
283 if (seed == 0) return null; | 193 // A good hashCode() implementation should produce very few collisions.
We added at most |
284 PadPosition[] values = PadPosition.values(); | 194 // 4*fields.length codes to the set. We'll say the implementation is goo
d if we had at least |
285 return values[seed % values.length]; | 195 // fields.length unique values. |
286 | 196 // TODO: Should the requirement be stronger than this? |
287 } else if (type == ParseMode.class) { | 197 assertTrue( |
288 if (seed == 0) return null; | 198 "Too many hash code collisions: " + hashCodes.size() + " out of
" + (fields.length * 4), |
289 ParseMode[] values = ParseMode.values(); | 199 hashCodes.size() >= fields.length); |
290 return values[seed % values.length]; | 200 } |
291 | 201 |
292 } else if (type == PluralRules.class) { | 202 /** |
293 if (seed == 0) return null; | 203 * Creates a valid sample instance of the given type. Used to simulate gette
rs and setters. |
294 ULocale[] locales = PluralRules.getAvailableULocales(); | 204 * |
295 return PluralRules.forLocale(locales[seed % locales.length]); | 205 * @param type |
296 | 206 * The type to generate. |
297 } else if (type == RoundingMode.class) { | 207 * @param seed |
298 if (seed == 0) return null; | 208 * An integer seed, guaranteed to be positive. The same seed shou
ld generate two instances |
299 RoundingMode[] values = RoundingMode.values(); | 209 * that are equal. A different seed should in general generate tw
o instances that are not |
300 return values[seed % values.length]; | 210 * equal; this might not always be possible, such as with boolean
s or enums where there |
301 | 211 * are limited possible values. |
302 } else { | 212 * @return An instance of the specified type. |
303 fail("Don't know how to handle type " + type + ". Please add it to getSamp
leValueForType()."); | 213 */ |
304 return null; | 214 Object getSampleValueForType(Class<?> type, int seed) { |
305 } | 215 if (type == Integer.TYPE) { |
306 } | 216 return seed * 1000001; |
307 | 217 |
308 @Test | 218 } else if (type == Boolean.TYPE) { |
309 public void TestBasicSerializationRoundTrip() throws IOException, ClassNotFoun
dException { | 219 return (seed % 2) == 0; |
310 DecimalFormatProperties props0 = new DecimalFormatProperties(); | 220 |
311 | 221 } else if (type == BigDecimal.class) { |
312 // Write values to some of the fields | 222 if (seed == 0) |
313 PatternStringParser.parseToExistingProperties("A-**####,#00.00#b¤", props0); | 223 return null; |
314 | 224 return new BigDecimal(seed * 1000002); |
315 // Write to byte stream | 225 |
316 ByteArrayOutputStream baos = new ByteArrayOutputStream(); | 226 } else if (type == String.class) { |
317 ObjectOutputStream oos = new ObjectOutputStream(baos); | 227 if (seed == 0) |
318 oos.writeObject(props0); | 228 return null; |
319 oos.flush(); | 229 return BigInteger.valueOf(seed * 1000003).toString(32); |
320 baos.close(); | 230 |
321 byte[] bytes = baos.toByteArray(); | 231 } else if (type == CompactStyle.class) { |
322 | 232 if (seed == 0) |
323 // Read from byte stream | 233 return null; |
324 ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(bytes
)); | 234 CompactStyle[] values = CompactStyle.values(); |
325 Object obj = ois.readObject(); | 235 return values[seed % values.length]; |
326 ois.close(); | 236 |
327 DecimalFormatProperties props1 = (DecimalFormatProperties) obj; | 237 } else if (type == Currency.class) { |
328 | 238 if (seed == 0) |
329 // Test equality | 239 return null; |
330 assertEquals("Did not round-trip through serialization", props0, props1); | 240 Object[] currencies = Currency.getAvailableCurrencies().toArray(); |
331 } | 241 return currencies[seed % currencies.length]; |
332 | 242 |
333 /** Handler for serialization compatibility test suite. */ | 243 } else if (type == CurrencyPluralInfo.class) { |
334 public static class PropertiesHandler implements SerializableTestUtility.Handl
er { | 244 if (seed == 0) |
335 | 245 return null; |
336 @Override | 246 ULocale[] locales = ULocale.getAvailableLocales(); |
337 public Object[] getTestObjects() { | 247 return CurrencyPluralInfo.getInstance(locales[seed % locales.length]
); |
338 return new Object[] { | 248 |
339 new DecimalFormatProperties(), | 249 } else if (type == CurrencyUsage.class) { |
340 PatternStringParser.parseToProperties("x#,##0.00%"), | 250 if (seed == 0) |
341 new DecimalFormatProperties().setCompactStyle(CompactStyle.LONG).setMini
mumExponentDigits(2) | 251 return null; |
342 }; | 252 CurrencyUsage[] values = CurrencyUsage.values(); |
343 } | 253 return values[seed % values.length]; |
344 | 254 |
345 @Override | 255 } else if (type == GroupingMode.class) { |
346 public boolean hasSameBehavior(Object a, Object b) { | 256 if (seed == 0) |
347 return a.equals(b); | 257 return null; |
348 } | 258 GroupingMode[] values = GroupingMode.values(); |
349 } | 259 return values[seed % values.length]; |
350 | 260 |
351 /** Handler for the ICU 59 class named "Properties" before it was renamed to "
DecimalFormatProperties". */ | 261 } else if (type == FormatWidth.class) { |
352 public static class ICU59PropertiesHandler implements SerializableTestUtility.
Handler { | 262 if (seed == 0) |
353 | 263 return null; |
354 @Override | 264 FormatWidth[] values = FormatWidth.values(); |
355 public Object[] getTestObjects() { | 265 return values[seed % values.length]; |
356 return new Object[] { | 266 |
357 new com.ibm.icu.impl.number.Properties() | 267 } else if (type == Map.class) { |
358 }; | 268 // Map<String,Map<String,String>> for compactCustomData property |
359 } | 269 if (seed == 0) |
360 | 270 return null; |
361 @Override | 271 Map<String, Map<String, String>> outer = new HashMap<String, Map<Str
ing, String>>(); |
362 public boolean hasSameBehavior(Object a, Object b) { | 272 Map<String, String> inner = new HashMap<String, String>(); |
363 return true; | 273 inner.put("one", "0 thousand"); |
364 } | 274 StringBuilder magnitudeKey = new StringBuilder(); |
365 } | 275 magnitudeKey.append("1000"); |
| 276 for (int i = 0; i < seed % 9; i++) { |
| 277 magnitudeKey.append("0"); |
| 278 } |
| 279 outer.put(magnitudeKey.toString(), inner); |
| 280 return outer; |
| 281 |
| 282 } else if (type == MathContext.class) { |
| 283 if (seed == 0) |
| 284 return null; |
| 285 RoundingMode[] modes = RoundingMode.values(); |
| 286 return new MathContext(seed, modes[seed % modes.length]); |
| 287 |
| 288 } else if (type == MeasureUnit.class) { |
| 289 if (seed == 0) |
| 290 return null; |
| 291 Object[] units = MeasureUnit.getAvailable().toArray(); |
| 292 return units[seed % units.length]; |
| 293 |
| 294 } else if (type == PadPosition.class) { |
| 295 if (seed == 0) |
| 296 return null; |
| 297 PadPosition[] values = PadPosition.values(); |
| 298 return values[seed % values.length]; |
| 299 |
| 300 } else if (type == ParseMode.class) { |
| 301 if (seed == 0) |
| 302 return null; |
| 303 ParseMode[] values = ParseMode.values(); |
| 304 return values[seed % values.length]; |
| 305 |
| 306 } else if (type == PluralRules.class) { |
| 307 if (seed == 0) |
| 308 return null; |
| 309 ULocale[] locales = PluralRules.getAvailableULocales(); |
| 310 return PluralRules.forLocale(locales[seed % locales.length]); |
| 311 |
| 312 } else if (type == RoundingMode.class) { |
| 313 if (seed == 0) |
| 314 return null; |
| 315 RoundingMode[] values = RoundingMode.values(); |
| 316 return values[seed % values.length]; |
| 317 |
| 318 } else { |
| 319 fail("Don't know how to handle type " |
| 320 + type |
| 321 + ". Please add it to getSampleValueForType()."); |
| 322 return null; |
| 323 } |
| 324 } |
| 325 |
| 326 @Test |
| 327 public void TestBasicSerializationRoundTrip() throws IOException, ClassNotFo
undException { |
| 328 DecimalFormatProperties props0 = new DecimalFormatProperties(); |
| 329 |
| 330 // Write values to some of the fields |
| 331 PatternStringParser.parseToExistingProperties("A-**####,#00.00#b¤", prop
s0); |
| 332 |
| 333 // Write to byte stream |
| 334 ByteArrayOutputStream baos = new ByteArrayOutputStream(); |
| 335 ObjectOutputStream oos = new ObjectOutputStream(baos); |
| 336 oos.writeObject(props0); |
| 337 oos.flush(); |
| 338 baos.close(); |
| 339 byte[] bytes = baos.toByteArray(); |
| 340 |
| 341 // Read from byte stream |
| 342 ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(b
ytes)); |
| 343 Object obj = ois.readObject(); |
| 344 ois.close(); |
| 345 DecimalFormatProperties props1 = (DecimalFormatProperties) obj; |
| 346 |
| 347 // Test equality |
| 348 assertEquals("Did not round-trip through serialization", props0, props1)
; |
| 349 } |
| 350 |
| 351 /** Handler for serialization compatibility test suite. */ |
| 352 public static class PropertiesHandler implements SerializableTestUtility.Han
dler { |
| 353 |
| 354 @Override |
| 355 public Object[] getTestObjects() { |
| 356 return new Object[] { |
| 357 new DecimalFormatProperties(), |
| 358 PatternStringParser.parseToProperties("x#,##0.00%"), |
| 359 new DecimalFormatProperties().setCompactStyle(CompactStyle.L
ONG) |
| 360 .setMinimumExponentDigits(2) }; |
| 361 } |
| 362 |
| 363 @Override |
| 364 public boolean hasSameBehavior(Object a, Object b) { |
| 365 return a.equals(b); |
| 366 } |
| 367 } |
| 368 |
| 369 /** |
| 370 * Handler for the ICU 59 class named "Properties" before it was renamed to |
| 371 * "DecimalFormatProperties". |
| 372 */ |
| 373 public static class ICU59PropertiesHandler implements SerializableTestUtilit
y.Handler { |
| 374 |
| 375 @Override |
| 376 public Object[] getTestObjects() { |
| 377 return new Object[] { new com.ibm.icu.impl.number.Properties() }; |
| 378 } |
| 379 |
| 380 @Override |
| 381 public boolean hasSameBehavior(Object a, Object b) { |
| 382 return true; |
| 383 } |
| 384 } |
366 } | 385 } |
LEFT | RIGHT |