001:/*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018:package org.apache.commons.lang.enum;
019:
020:import java.lang.reflect.InvocationTargetException;
021:import java.lang.reflect.Method;
022:import java.net.URL;
023:import java.net.URLClassLoader;
024:import java.util.ArrayList;
025:import java.util.HashMap;
026:import java.util.Iterator;
027:import java.util.List;
028:import java.util.Map;
029:
030:import junit.framework.AssertionFailedError;
031:import junit.framework.Test;
032:import junit.framework.TestCase;
033:import junit.framework.TestSuite;
034:
035:import org.apache.commons.lang.SerializationUtils;
036:
037:/**
038: * Test cases for the {@link Enum} class.
039: *
040: * @author Stephen Colebourne
041: * @author Gary D. Gregory
042: * @version $Id: EnumTest.java 501606 2007-01-30 22:26:38Z bayard $
043: */
044:
045:public final class EnumTest extends TestCase {
046:
047: private static final String ENUM_CLASS_NAME = "org.apache.commons.lang.enum.ColorEnum";
048:
049: public EnumTest(String name) {
050: super (name);
051: }
052:
053: public void setUp() {
054: }
055:
056: public static Test suite() {
057: TestSuite suite = new TestSuite(EnumTest.class);
058: suite.setName("Enum Tests");
059: return suite;
060: }
061:
062: public void testName() {
063: assertEquals("Red", ColorEnum.RED.getName());
064: assertEquals("Green", ColorEnum.GREEN.getName());
065: assertEquals("Blue", ColorEnum.BLUE.getName());
066: }
067:
068: public void testCompareTo() {
069: assertTrue(ColorEnum.BLUE.compareTo(ColorEnum.BLUE) == 0);
070: assertTrue(ColorEnum.RED.compareTo(ColorEnum.BLUE) > 0);
071: assertTrue(ColorEnum.BLUE.compareTo(ColorEnum.RED) < 0);
072: try {
073: ColorEnum.RED.compareTo(null);
074: fail();
075: } catch (NullPointerException ex) {
076: }
077: try {
078: ColorEnum.RED.compareTo(new Object());
079: fail();
080: } catch (ClassCastException ex) {
081: }
082: }
083:
084: public void testEquals() {
085: assertSame(ColorEnum.RED, ColorEnum.RED);
086: assertSame(ColorEnum.getEnum("Red"), ColorEnum.RED);
087: assertEquals(false, ColorEnum.RED.equals(null));
088: assertEquals(true, ColorEnum.RED.equals(ColorEnum.RED));
089: assertEquals(true, ColorEnum.RED.equals(ColorEnum.getEnum("Red")));
090: }
091:
092: public void testHashCode() {
093: assertEquals(ColorEnum.RED.hashCode(), ColorEnum.RED.hashCode());
094: assertEquals(7 + ColorEnum.class.hashCode() + 3 * "Red".hashCode(), ColorEnum.RED.hashCode());
095: }
096:
097: public void testToString() {
098: String toString = ColorEnum.RED.toString();
099: assertEquals("ColorEnum[Red]", toString);
100: assertSame(toString, ColorEnum.RED.toString());
101: }
102:
103: public void testIterator() {
104: Iterator it = ColorEnum.iterator();
105: assertSame(ColorEnum.RED, it.next());
106: assertSame(ColorEnum.GREEN, it.next());
107: assertSame(ColorEnum.BLUE, it.next());
108: }
109:
110: public void testList() {
111: List list = new ArrayList(ColorEnum.getEnumList());
112:
113: assertNotNull(list);
114:
115: assertEquals(list.size(), ColorEnum.getEnumMap().keySet().size());
116:
117: Iterator it = list.iterator();
118: assertSame(ColorEnum.RED, it.next());
119: assertSame(ColorEnum.GREEN, it.next());
120: assertSame(ColorEnum.BLUE, it.next());
121: }
122:
123: public void testMap() {
124: Map map = new HashMap(ColorEnum.getEnumMap());
125:
126: assertNotNull(map);
127: assertTrue(map.containsValue(ColorEnum.RED));
128: assertTrue(map.containsValue(ColorEnum.GREEN));
129: assertTrue(map.containsValue(ColorEnum.BLUE));
130: assertSame(ColorEnum.RED, map.get("Red"));
131: assertSame(ColorEnum.GREEN, map.get("Green"));
132: assertSame(ColorEnum.BLUE, map.get("Blue"));
133: assertEquals(map.keySet().size(), ColorEnum.getEnumList().size());
134: }
135:
136: public void testGet() {
137: assertSame(ColorEnum.RED, ColorEnum.getEnum("Red"));
138: assertSame(ColorEnum.GREEN, ColorEnum.getEnum("Green"));
139: assertSame(ColorEnum.BLUE, ColorEnum.getEnum("Blue"));
140: assertSame(null, ColorEnum.getEnum("Pink"));
141: }
142:
143: public void testSerialization() {
144: int hashCode = ColorEnum.RED.hashCode();
145: assertSame(ColorEnum.RED, SerializationUtils.clone(ColorEnum.RED));
146: assertEquals(hashCode, SerializationUtils.clone(ColorEnum.RED).hashCode());
147: assertSame(ColorEnum.GREEN, SerializationUtils.clone(ColorEnum.GREEN));
148: assertSame(ColorEnum.BLUE, SerializationUtils.clone(ColorEnum.BLUE));
149: }
150:
151: public void testBroken1() {
152: try {
153: Broken1Enum.RED.getName();
154: fail();
155: } catch (ExceptionInInitializerError ex) {
156: assertTrue(ex.getException() instanceof IllegalArgumentException);
157: }
158: }
159:
160: public void testBroken2() {
161: try {
162: Broken2Enum.RED.getName();
163: fail();
164: } catch (ExceptionInInitializerError ex) {
165: assertTrue(ex.getException() instanceof IllegalArgumentException);
166: }
167: }
168:
169: public void testBroken3() {
170: try {
171: Broken3Enum.RED.getName();
172: fail();
173: } catch (ExceptionInInitializerError ex) {
174: assertTrue(ex.getException() instanceof IllegalArgumentException);
175: }
176: }
177:
178: public void testBroken1Operation() {
179: try {
180: Broken1OperationEnum.PLUS.getName();
181: fail();
182: } catch (ExceptionInInitializerError ex) {
183: assertTrue(ex.getException() instanceof IllegalArgumentException);
184: }
185: }
186:
187: public void testBroken2Operation() {
188: try {
189: Broken2OperationEnum.PLUS.getName();
190: fail();
191: } catch (ExceptionInInitializerError ex) {
192: assertTrue(ex.getException() instanceof IllegalArgumentException);
193: }
194: }
195:
196: public void testBroken3Operation() {
197: try {
198: Broken3OperationEnum.PLUS.getName();
199: fail();
200: } catch (ExceptionInInitializerError ex) {
201: assertTrue(ex.getException() instanceof IllegalArgumentException);
202: }
203: }
204:
205: public void testBroken4Operation() {
206: try {
207: Broken4OperationEnum.PLUS.getName();
208: fail();
209: } catch (ExceptionInInitializerError ex) {
210: assertTrue(ex.getException() instanceof IllegalArgumentException);
211: }
212: }
213:
214: public void testBroken5Operation() {
215: try {
216: Broken5OperationEnum.PLUS.getName();
217: fail();
218: } catch (ExceptionInInitializerError ex) {
219: assertTrue(ex.getException() instanceof IllegalArgumentException);
220: }
221: }
222:
223: public void testOperationGet() {
224: assertSame(OperationEnum.PLUS, OperationEnum.getEnum("Plus"));
225: assertSame(OperationEnum.MINUS, OperationEnum.getEnum("Minus"));
226: assertSame(null, OperationEnum.getEnum("Pink"));
227: }
228:
229: public void testOperationSerialization() {
230: assertSame(OperationEnum.PLUS, SerializationUtils.clone(OperationEnum.PLUS));
231: assertSame(OperationEnum.MINUS, SerializationUtils.clone(OperationEnum.MINUS));
232: }
233:
234: public void testOperationToString() {
235: assertEquals("OperationEnum[Plus]", OperationEnum.PLUS.toString());
236: }
237:
238: public void testOperationList() {
239: List list = OperationEnum.getEnumList();
240: assertNotNull(list);
241: assertEquals(2, list.size());
242: assertEquals(list.size(), OperationEnum.getEnumMap().keySet().size());
243:
244: Iterator it = list.iterator();
245: assertSame(OperationEnum.PLUS, it.next());
246: assertSame(OperationEnum.MINUS, it.next());
247: }
248:
249: public void testOperationMap() {
250: Map map = OperationEnum.getEnumMap();
251: assertNotNull(map);
252: assertEquals(map.keySet().size(), OperationEnum.getEnumList().size());
253:
254: assertTrue(map.containsValue(OperationEnum.PLUS));
255: assertTrue(map.containsValue(OperationEnum.MINUS));
256: assertSame(OperationEnum.PLUS, map.get("Plus"));
257: assertSame(OperationEnum.MINUS, map.get("Minus"));
258: }
259:
260: public void testOperationCalculation() {
261: assertEquals(3, OperationEnum.PLUS.eval(1, 2));
262: assertEquals(-1, OperationEnum.MINUS.eval(1, 2));
263: }
264:
265: // -----------------------------------------------------------------------
266: public void testExtended1Get() {
267: assertSame(Extended1Enum.ALPHA, Extended1Enum.getEnum("Alpha"));
268: assertSame(Extended1Enum.BETA, Extended1Enum.getEnum("Beta"));
269: assertSame(null, Extended1Enum.getEnum("Gamma"));
270: assertSame(null, Extended1Enum.getEnum("Delta"));
271: }
272:
273: public void testExtended2Get() {
274: assertSame(Extended1Enum.ALPHA, Extended2Enum.ALPHA);
275: assertSame(Extended1Enum.BETA, Extended2Enum.BETA);
276:
277: assertSame(Extended2Enum.ALPHA, Extended2Enum.getEnum("Alpha"));
278: assertSame(Extended2Enum.BETA, Extended2Enum.getEnum("Beta"));
279: assertSame(Extended2Enum.GAMMA, Extended2Enum.getEnum("Gamma"));
280: assertSame(null, Extended2Enum.getEnum("Delta"));
281: }
282:
283: public void testExtended3Get() {
284: assertSame(Extended2Enum.ALPHA, Extended3Enum.ALPHA);
285: assertSame(Extended2Enum.BETA, Extended3Enum.BETA);
286: assertSame(Extended2Enum.GAMMA, Extended3Enum.GAMMA);
287:
288: assertSame(Extended3Enum.ALPHA, Extended3Enum.getEnum("Alpha"));
289: assertSame(Extended3Enum.BETA, Extended3Enum.getEnum("Beta"));
290: assertSame(Extended3Enum.GAMMA, Extended3Enum.getEnum("Gamma"));
291: assertSame(Extended3Enum.DELTA, Extended3Enum.getEnum("Delta"));
292: }
293:
294: public void testExtendedSerialization() {
295: assertSame(Extended1Enum.ALPHA, SerializationUtils.clone(Extended1Enum.ALPHA));
296: assertSame(Extended1Enum.BETA, SerializationUtils.clone(Extended1Enum.BETA));
297: assertSame(Extended2Enum.GAMMA, SerializationUtils.clone(Extended2Enum.GAMMA));
298: assertSame(Extended3Enum.DELTA, SerializationUtils.clone(Extended3Enum.DELTA));
299: }
300:
301: public void testExtendedToString() {
302: assertEquals("Extended1Enum[Alpha]", Extended1Enum.ALPHA.toString());
303: assertEquals("Extended1Enum[Beta]", Extended1Enum.BETA.toString());
304:
305: assertEquals("Extended1Enum[Alpha]", Extended2Enum.ALPHA.toString());
306: assertEquals("Extended1Enum[Beta]", Extended2Enum.BETA.toString());
307: assertEquals("Extended2Enum[Gamma]", Extended2Enum.GAMMA.toString());
308:
309: assertEquals("Extended1Enum[Alpha]", Extended3Enum.ALPHA.toString());
310: assertEquals("Extended1Enum[Beta]", Extended3Enum.BETA.toString());
311: assertEquals("Extended2Enum[Gamma]", Extended3Enum.GAMMA.toString());
312: assertEquals("Extended3Enum[Delta]", Extended3Enum.DELTA.toString());
313: }
314:
315: public void testExtended1List() {
316: List list = Extended1Enum.getEnumList();
317: assertNotNull(list);
318: assertEquals(2, list.size());
319: assertEquals(list.size(), Extended1Enum.getEnumMap().keySet().size());
320:
321: Iterator it = list.iterator();
322: assertSame(Extended1Enum.ALPHA, it.next());
323: assertSame(Extended1Enum.BETA, it.next());
324: }
325:
326: public void testExtended2List() {
327: List list = Extended2Enum.getEnumList();
328: assertNotNull(list);
329: assertEquals(3, list.size());
330: assertEquals(list.size(), Extended2Enum.getEnumMap().keySet().size());
331:
332: Iterator it = list.iterator();
333: assertSame(Extended2Enum.ALPHA, it.next());
334: assertSame(Extended2Enum.BETA, it.next());
335: assertSame(Extended2Enum.GAMMA, it.next());
336: }
337:
338: public void testExtended3List() {
339: List list = Extended3Enum.getEnumList();
340: assertNotNull(list);
341: assertEquals(4, list.size());
342: assertEquals(list.size(), Extended3Enum.getEnumMap().keySet().size());
343:
344: Iterator it = list.iterator();
345: assertSame(Extended3Enum.ALPHA, it.next());
346: assertSame(Extended3Enum.BETA, it.next());
347: assertSame(Extended3Enum.GAMMA, it.next());
348: assertSame(Extended3Enum.DELTA, it.next());
349: }
350:
351: public void testExtended1Map() {
352: Map map = Extended1Enum.getEnumMap();
353: assertNotNull(map);
354: assertEquals(map.keySet().size(), Extended1Enum.getEnumList().size());
355:
356: assertTrue(map.containsValue(Extended1Enum.ALPHA));
357: assertTrue(map.containsValue(Extended1Enum.BETA));
358: assertSame(Extended1Enum.ALPHA, map.get("Alpha"));
359: assertSame(Extended1Enum.BETA, map.get("Beta"));
360: }
361:
362: public void testExtended2Map() {
363: Map map = Extended2Enum.getEnumMap();
364: assertNotNull(map);
365: assertEquals(map.keySet().size(), Extended2Enum.getEnumList().size());
366:
367: assertTrue(map.containsValue(Extended2Enum.ALPHA));
368: assertTrue(map.containsValue(Extended2Enum.BETA));
369: assertTrue(map.containsValue(Extended2Enum.GAMMA));
370: assertSame(Extended2Enum.ALPHA, map.get("Alpha"));
371: assertSame(Extended2Enum.BETA, map.get("Beta"));
372: assertSame(Extended2Enum.GAMMA, map.get("Gamma"));
373: }
374:
375: public void testExtended3Map() {
376: Map map = Extended3Enum.getEnumMap();
377: assertNotNull(map);
378: assertEquals(map.keySet().size(), Extended3Enum.getEnumList().size());
379:
380: assertTrue(map.containsValue(Extended3Enum.ALPHA));
381: assertTrue(map.containsValue(Extended3Enum.BETA));
382: assertTrue(map.containsValue(Extended3Enum.GAMMA));
383: assertTrue(map.containsValue(Extended3Enum.DELTA));
384: assertSame(Extended3Enum.ALPHA, map.get("Alpha"));
385: assertSame(Extended3Enum.BETA, map.get("Beta"));
386: assertSame(Extended3Enum.GAMMA, map.get("Gamma"));
387: assertSame(Extended3Enum.DELTA, map.get("Delta"));
388: }
389:
390: // -----------------------------------------------------------------------
391: public void testNested() {
392: List list = new ArrayList(Nest.ColorEnum.getEnumList());
393: assertEquals(3, list.size()); // all is well
394: Iterator it = list.iterator();
395: assertSame(Nest.ColorEnum.RED, it.next());
396: assertSame(Nest.ColorEnum.GREEN, it.next());
397: assertSame(Nest.ColorEnum.BLUE, it.next());
398: // This nesting works because the enum constants are defined in the SAME
399: // class as the getEnumList(). It just acts as a normal enum.
400: }
401:
402: public void testNestedBroken() {
403: List list = new ArrayList(NestBroken.ColorEnum.getEnumList());
404: try {
405: assertEquals(0, list.size()); // no enums!!!
406: // this is BROKEN because the enum constants are defined in a DIFFERENT
407: // class from getEnumList(). Once NestBroken class is referenced,
408: // and thus class loaded with its enum constants, the getEnumList works:
409: } catch (AssertionFailedError ex) {
410: // this actually works and isn't broken on Linux SunJDK1.4.1, so...
411: assertEquals(3, list.size());
412: }
413: new NestBroken();
414: list = new ArrayList(NestBroken.ColorEnum.getEnumList());
415: assertEquals(3, list.size()); // all is well!!!
416: Iterator it = list.iterator();
417: assertSame(NestBroken.RED, it.next());
418: assertSame(NestBroken.GREEN, it.next());
419: assertSame(NestBroken.BLUE, it.next());
420: }
421:
422: public void testNestedLinked() {
423: List list = new ArrayList(NestLinked.ColorEnum.getEnumList());
424: assertEquals(3, list.size()); // all is well
425: Iterator it = list.iterator();
426: assertSame(NestLinked.RED, it.next());
427: assertSame(NestLinked.GREEN, it.next());
428: assertSame(NestLinked.BLUE, it.next());
429: // This nesting works because a static block in the enum class forces a
430: // class load of the outer class which defines the enum constants.
431: }
432:
433: public void testNestedReferenced() {
434: List list = new ArrayList(NestReferenced.ColorEnum.getEnumList());
435: assertEquals(3, list.size()); // all is well
436: Iterator it = list.iterator();
437: assertSame(NestReferenced.RED, it.next());
438: assertSame(NestReferenced.GREEN, it.next());
439: assertSame(NestReferenced.BLUE, it.next());
440: // This nesting works because the enum constants are actually defined in
441: // the SAME class as the getEnumList(). The references in the outer class
442: // are just extra references.
443: }
444:
445: public void testColorEnumEqualsWithDifferentClassLoaders() throws SecurityException, IllegalArgumentException,
446: ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException {
447: this .testWithDifferentClassLoaders(ColorEnum.BLUE);
448: this .testWithDifferentClassLoaders(ColorEnum.GREEN);
449: this .testWithDifferentClassLoaders(ColorEnum.RED);
450: }
451:
452: void testWithDifferentClassLoaders(ColorEnum colorEnum) throws ClassNotFoundException, SecurityException,
453: NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException {
454: // Sanity checks:
455: assertTrue(colorEnum.equals(colorEnum));
456: assertNotNull(ColorEnum.class.getClassLoader());
457: // set up:
458: ClassLoader myClassLoader = EnumTest.class.getClassLoader();
459: if (!(myClassLoader instanceof URLClassLoader)) {
460: fail("EnumTest ClassLoader = " + (myClassLoader == null ? null : myClassLoader.getClass().getName()));
461: }
462: ClassLoader classLoader = URLClassLoader.newInstance( ((URLClassLoader)myClassLoader).getURLs(), null);
463: Object enumObjectFromOtherClassLoader = this .getColorEnum(classLoader, colorEnum.getName());
464:
465: // the real test, part 1.
466: try {
467: ColorEnum testCase = (ColorEnum) enumObjectFromOtherClassLoader;
468: fail("Should have thrown a ClassCastException for " + testCase);
469: } catch (ClassCastException e) {
470: // normal.
471: }
472:
473: // the real test, part 2.
474: assertEquals("The two objects should match even though they are from different class loaders", colorEnum,
475: enumObjectFromOtherClassLoader);
476:
477: // the real test, part 3 - testing equals(Object)
478: int falseCount = 0;
479: for (Iterator iter = ColorEnum.iterator(); iter.hasNext();) {
480: ColorEnum element = (ColorEnum) iter.next();
481: if (!colorEnum.equals(element)) {
482: falseCount++;
483: assertFalse(enumObjectFromOtherClassLoader.equals(element));
484: }
485: }
486: assertEquals(ColorEnum.getEnumList().size() - 1, falseCount);
487:
488: // the real test, part 4 - testing compareTo(Object) == 0
489: falseCount = 0;
490: for (Iterator iter = ColorEnum.iterator(); iter.hasNext();) {
491: ColorEnum element = (ColorEnum) iter.next();
492: if (!colorEnum.equals(element)) {
493: falseCount++;
494: assertFalse( ((Comparable)enumObjectFromOtherClassLoader).compareTo(element) == 0);
495: }
496: }
497: assertEquals(ColorEnum.getEnumList().size() - 1, falseCount);
498: }
499:
500: Object getColorEnum(ClassLoader classLoader, String color) throws ClassNotFoundException, SecurityException,
501: NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException {
502: // Sanity check:
503: ColorEnum.RED.equals(ColorEnum.RED);
504: assertNotNull(ColorEnum.class.getClassLoader());
505: // set up:
506: assertNotNull(classLoader);
507: assertFalse(classLoader.equals(ColorEnum.class.getClassLoader()));
508: Class otherColorEnumClass = null;
509: try {
510: otherColorEnumClass = classLoader.loadClass(ENUM_CLASS_NAME);
511: } catch (ClassNotFoundException e) {
512: // Dump some information to help debug class loader issues under different JREs, Ant, Eclipse.
513: System.err.println("Could not load " + ENUM_CLASS_NAME + " from the class loader " + classLoader);
514: URLClassLoader urlCl = (URLClassLoader) classLoader;
515: URL[] urls = urlCl.getURLs();
516: System.err.println("Class loader has " + urls.length + " URLs:");
517: for (int i = 0; i < urls.length; i++) {
518: System.err.println("URL[" + i + "] = " + urls[i]);
519: }
520: e.printStackTrace();
521: throw e;
522: }
523: assertNotNull(otherColorEnumClass);
524: assertNotNull(otherColorEnumClass.getClassLoader());
525: assertTrue(classLoader.equals(otherColorEnumClass.getClassLoader()));
526: assertFalse(otherColorEnumClass.getClassLoader().equals(ColorEnum.class.getClassLoader()));
527: Method method = otherColorEnumClass.getMethod("getEnum", new Class[]{String.class});
528: Object enumObject = method.invoke(otherColorEnumClass, new Object[]{color});
529: assertNotNull(enumObject);
530: assertFalse(ColorEnum.class.equals(enumObject.getClass()));
531: assertFalse(ColorEnum.class == enumObject.getClass());
532: return enumObject;
533: }
534:
535: public void testEqualsToWrongInstance() {
536: for (Iterator iter = ColorEnum.iterator(); iter.hasNext();) {
537: ColorEnum element = (ColorEnum) iter.next();
538: this .testEqualsToWrongInstance(element);
539: }
540: }
541:
542: void testEqualsToWrongInstance(ColorEnum colorEnum) {
543: assertEquals(false, colorEnum.equals("test"));
544: assertEquals(false, colorEnum.equals(new Integer(1)));
545: assertEquals(false, colorEnum.equals(new Boolean(true)));
546: assertEquals(false, colorEnum.equals(new StringBuffer("test")));
547: assertEquals(false, colorEnum.equals(new Object()));
548: assertEquals(false, colorEnum.equals(null));
549: assertEquals(false, colorEnum.equals(""));
550: assertEquals(false, colorEnum.equals(ColorEnum.getEnum(null)));
551: assertEquals(false, colorEnum.equals(ColorEnum.getEnum("")));
552: assertEquals(false, colorEnum.equals(ColorEnum.getEnum("This ColorEnum does not exist.")));
553: }
554:}
|