]> gitweb.fperrin.net Git - Dictionary.git/blob - jars/icu4j-4_2_1-src/src/com/ibm/icu/dev/eclipse/plugins/com.ibm.icu.base.tests/src/com/ibm/icu/tests/ICUTestCase.java
icu4jsrc
[Dictionary.git] / jars / icu4j-4_2_1-src / src / com / ibm / icu / dev / eclipse / plugins / com.ibm.icu.base.tests / src / com / ibm / icu / tests / ICUTestCase.java
1 /*\r
2  *******************************************************************************\r
3  * Copyright (C) 2006, International Business Machines Corporation and         *\r
4  * others. All Rights Reserved.                                                *\r
5  *******************************************************************************\r
6  */\r
7 \r
8 package com.ibm.icu.tests;\r
9 \r
10 import java.io.ByteArrayInputStream;\r
11 import java.io.ByteArrayOutputStream;\r
12 import java.io.Externalizable;\r
13 import java.io.IOException;\r
14 import java.io.ObjectInputStream;\r
15 import java.io.ObjectOutputStream;\r
16 import java.io.Serializable;\r
17 import java.lang.reflect.Array;\r
18 import java.lang.reflect.InvocationTargetException;\r
19 import java.lang.reflect.Method;\r
20 import java.util.Locale;\r
21 \r
22 import com.ibm.icu.util.TimeZone;\r
23 import com.ibm.icu.util.ULocale;\r
24 \r
25 import junit.framework.TestCase;\r
26 \r
27 /**\r
28  * Implement boilerplate tests.\r
29  * Currently there is only one method, testEHCS, which tests equals, hashCode, \r
30  * clone, and serialization.\r
31  */\r
32 public abstract class ICUTestCase extends TestCase {\r
33     private static final Object[] EMPTY_ARGS = {};\r
34     private static final Class[] EMPTY_CLASSES = {};\r
35         \r
36     private static final Locale oldLocale = Locale.getDefault();\r
37     private static final ULocale oldULocale = ULocale.getDefault();\r
38     private static final java.util.TimeZone oldJTimeZone = java.util.TimeZone.getDefault();\r
39     private static final TimeZone oldITimeZone = TimeZone.getDefault();\r
40                 \r
41     // TODO: what's the best way to check this?\r
42     public static final boolean testingWrapper = true;\r
43 \r
44     protected void setUp() throws Exception {\r
45         super.setUp();\r
46         Locale.setDefault(Locale.US);\r
47         ULocale.setDefault(ULocale.US);\r
48         java.util.TimeZone.setDefault(java.util.TimeZone.getTimeZone("PST"));\r
49         TimeZone.setDefault(TimeZone.getTimeZone("PST"));\r
50     }\r
51         \r
52     protected void tearDown() throws Exception {\r
53         ULocale.setDefault(oldULocale);\r
54         Locale.setDefault(oldLocale);\r
55         TimeZone.setDefault(oldITimeZone);\r
56         java.util.TimeZone.setDefault(oldJTimeZone);\r
57         super.tearDown();\r
58     }\r
59 \r
60     private static final Object test = new Object();\r
61         \r
62     /**\r
63      * Assert that two objects are _not_ equal.  Curiously missing from Assert.\r
64      * @param lhs an object to test, may be null\r
65      * @param rhs an object to test, may be null\r
66      */\r
67     public static void assertNotEqual(Object lhs, Object rhs) {\r
68         if (lhs == null) {\r
69             if (rhs == null) fail("null equals null");\r
70         } else {\r
71             if (lhs.equals(rhs)) {\r
72                 fail(lhs.toString() + " equals " + rhs);\r
73             }\r
74         }\r
75     }\r
76         \r
77     public static void assertNotEqual(long lhs, long rhs) {\r
78         if (lhs == rhs) {\r
79             fail("values are equal: " + lhs);\r
80         }\r
81     }\r
82         \r
83     /**\r
84      * Test whether equality, hashCode, clone, and serialization work as expected.  \r
85      * Equals(Object) is assumed to return false (not throw an exception) if passed \r
86      * null or an object of an incompatible class.\r
87      * Hashcodes must be equal iff the two objects compare equal.  No attempt is made to\r
88      * evaluate the quality of the hashcode distribution, so (in particular) degenerate \r
89      * hashcode implementations will pass this test.\r
90      * Clone will be tested if the method "clone" is public on the class of obj.  \r
91      * It is assumed to return an object that compares equal to obj.\r
92      * Serialization will be tested if object implements Serializable or Externalizable.\r
93      * It is assumed the serialized/deserialized object compares equal to obj.\r
94      * @param obj the object to test\r
95      * @param eq an object that should compare equal to, but is not the same as, obj.  \r
96      *     it should be assignable to the class of obj.\r
97      * @param neq a non-null object that should not compare equal to obj.  \r
98      *     it should be assignable to the class of obj.\r
99      */\r
100     public static void testEHCS(Object obj, Object eq, Object neq) {\r
101         if (obj == null || eq == null || neq == null) {\r
102             throw new NullPointerException();\r
103         }\r
104         Class cls = obj.getClass();\r
105         if (!(cls.isAssignableFrom(eq.getClass()) && cls.isAssignableFrom(neq.getClass()))) {\r
106             throw new IllegalArgumentException("unassignable classes");\r
107         }\r
108                 \r
109         // reflexive\r
110         assertEquals(obj, obj);\r
111                 \r
112         // should return false, not throw exception\r
113         assertNotEqual(obj, test);\r
114         assertNotEqual(obj, null);\r
115                 \r
116         // commutative\r
117         assertEquals(obj, eq);\r
118         assertEquals(eq, obj);\r
119                 \r
120         assertNotEqual(obj, neq);\r
121         assertNotEqual(neq, obj);\r
122                 \r
123         // equal objects MUST have equal hashes, unequal objects MAY have equal hashes\r
124         assertEquals(obj.hashCode(), eq.hashCode());\r
125                 \r
126         Object clone = null;\r
127         try {\r
128             // look for public clone method and call it if available\r
129             Method method_clone = cls.getMethod("clone", EMPTY_CLASSES);\r
130             clone = method_clone.invoke(obj, EMPTY_ARGS);\r
131             assertNotNull(clone);\r
132         }\r
133         catch(NoSuchMethodException e) {\r
134             // ok\r
135         }\r
136         catch(InvocationTargetException e) {\r
137             // ok\r
138         }\r
139         catch(IllegalAccessException e) {\r
140             // ok\r
141         }\r
142                 \r
143         if (clone != null) {\r
144             assertEquals(obj, clone);\r
145             assertEquals(clone, obj);\r
146         }\r
147                 \r
148         if (obj instanceof Serializable || obj instanceof Externalizable) {\r
149             Object ser = null;\r
150             try {\r
151                 ByteArrayOutputStream bos = new ByteArrayOutputStream();\r
152                 ObjectOutputStream oos = new ObjectOutputStream(bos);\r
153                 oos.writeObject(clone);\r
154                 oos.close();\r
155                                 \r
156                 ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());\r
157                 ObjectInputStream ois = new ObjectInputStream(bis);\r
158                 ser = ois.readObject();\r
159                 ois.close();\r
160             }\r
161             catch(IOException e) {\r
162                 System.err.println(e.getMessage());\r
163                 throw new RuntimeException(e);\r
164             }\r
165             catch(ClassNotFoundException e) {\r
166                 System.err.println(e.getMessage());\r
167                 throw new RuntimeException(e);\r
168             }\r
169                         \r
170             if (ser != null) {\r
171                 assertEquals(obj, ser);\r
172                 assertEquals(ser, obj);\r
173                 assertEquals(obj.hashCode(), ser.hashCode());\r
174             }\r
175         }\r
176     }\r
177 \r
178     /**\r
179      * Fail if the arrays are not equal.  To be equal, the arrays must\r
180      * be the same length, and each element in the left array must compare\r
181      * equal to the corresponding element of the right array.\r
182      * Also fails if one of the objects is not an array.\r
183      * @param lhs the left array\r
184      * @param rhs the right array\r
185      */\r
186     public static void assertArraysEqual(Object lhs, Object rhs) {\r
187         Class lcls = lhs.getClass();\r
188         Class rcls = rhs.getClass();\r
189         if (!(lcls.isArray() && rcls.isArray())) {\r
190             fail("objects are not arrays");\r
191         }\r
192         String result = arraysAreEqual(lhs, rhs);\r
193         if (result != null) {\r
194             fail(result);\r
195         }\r
196     }\r
197 \r
198     /**\r
199      * Fail if the arrays are equal.  Also fails if one or the other \r
200      * argument is not an array.\r
201      * @param lhs the left array\r
202      * @param rhs the right array\r
203      */\r
204     public static void assertArraysNotEqual(Object lhs, Object rhs) {\r
205         Class lcls = lhs.getClass();\r
206         Class rcls = rhs.getClass();\r
207         if (!(lcls.isArray() && rcls.isArray())) {\r
208             fail("objects are not arrays");\r
209         }\r
210         String result = arraysAreEqual(lhs, rhs);\r
211         if (result == null) {\r
212             fail("arrays are equal");\r
213         }\r
214     }\r
215         \r
216     // slow but general\r
217     private static String arraysAreEqual(Object lhsa, Object rhsa) {\r
218         int lhsl = Array.getLength(lhsa);\r
219         int rhsl = Array.getLength(rhsa);\r
220         if (lhsl != rhsl) {\r
221             return "length " + lhsl + " != " + rhsl;\r
222         }\r
223         boolean lhsaA = lhsa.getClass().getComponentType().isArray();\r
224         boolean rhsaA = rhsa.getClass().getComponentType().isArray();\r
225         if (lhsaA != rhsaA) {\r
226             return (lhsaA ? "" : "non-") + "array != " + (rhsaA ? "" : "non-") + "array";\r
227         }\r
228         for (int i = 0; i < lhsl; ++i) {\r
229             Object lhse = Array.get(lhsa, i);\r
230             Object rhse = Array.get(rhsa, i);\r
231             if (lhse == null) {\r
232                 if (rhse != null) {\r
233                     return "null != " + rhse;\r
234                 }\r
235             } else {\r
236                 if (lhsaA) {\r
237                     String result = arraysAreEqual(lhse, rhse);\r
238                     if (result != null) {\r
239                         if (result.charAt(0) != '[') {\r
240                             result = " " + result;\r
241                         }\r
242                         return "[" + i + "]" + result;\r
243                     }\r
244                 } else {\r
245                     if (!lhse.equals(rhse)) {\r
246                         return lhse.toString() + " != " + rhse;\r
247                     }\r
248                 }\r
249             }\r
250         }\r
251         return null;\r
252     }\r
253         \r
254     // much more painful and slow than it should be... partly because of the\r
255     // oddness of clone, partly because arrays don't provide a Method for \r
256     // 'clone' despite the fact that they implement it and make it public.\r
257     public static Object cloneComplex(Object obj) {\r
258         Object result = null;\r
259         if (obj != null) {\r
260             Class cls = obj.getClass();\r
261             if (cls.isArray()) {\r
262                 int len = Array.getLength(obj);\r
263                 Class typ = cls.getComponentType();\r
264                 result = Array.newInstance(typ, len);\r
265                 boolean prim = typ.isPrimitive();\r
266                 for (int i = 0; i < len; ++i) {\r
267                     Object elem = Array.get(obj, i);\r
268                     Array.set(result, i, prim ? elem : cloneComplex(elem));\r
269                 }\r
270             } else {\r
271                 result = obj; // default\r
272                 try {\r
273                     Method cloneM = cls.getMethod("clone", null);\r
274                     result = cloneM.invoke(obj, null);\r
275                 }\r
276                 catch (NoSuchMethodException e) {\r
277                 }\r
278                 catch (IllegalAccessException e) {\r
279                 }\r
280                 catch (InvocationTargetException e) {\r
281                 }\r
282             }\r
283         }\r
284         return result;\r
285     }\r
286 }\r