1 /*
2  * Copyright (C) 2011 The Guava Authors
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.google.common.base;
18 
19 import com.google.common.annotations.GwtCompatible;
20 import com.google.common.annotations.GwtIncompatible;
21 import com.google.common.collect.ImmutableSet;
22 import com.google.common.testing.GcFinalization;
23 import com.google.common.testing.NullPointerTester;
24 import com.google.common.testing.SerializableTester;
25 
26 import junit.framework.TestCase;
27 
28 import java.lang.annotation.Retention;
29 import java.lang.annotation.RetentionPolicy;
30 import java.lang.ref.WeakReference;
31 import java.lang.reflect.Field;
32 import java.net.URLClassLoader;
33 import java.util.HashSet;
34 import java.util.Set;
35 
36 /**
37  * Tests for {@link Enums}.
38  *
39  * @author Steve McKay
40  */
41 @GwtCompatible(emulated = true)
42 public class EnumsTest extends TestCase {
43 
44   private enum TestEnum {
45     CHEETO,
46     HONDA,
47     POODLE,
48   }
49 
50   private enum OtherEnum {}
51 
testGetIfPresent()52   public void testGetIfPresent() {
53     assertEquals(Optional.of(TestEnum.CHEETO), Enums.getIfPresent(TestEnum.class, "CHEETO"));
54     assertEquals(Optional.of(TestEnum.HONDA), Enums.getIfPresent(TestEnum.class, "HONDA"));
55     assertEquals(Optional.of(TestEnum.POODLE), Enums.getIfPresent(TestEnum.class, "POODLE"));
56 
57     assertTrue(Enums.getIfPresent(TestEnum.class, "CHEETO").isPresent());
58     assertTrue(Enums.getIfPresent(TestEnum.class, "HONDA").isPresent());
59     assertTrue(Enums.getIfPresent(TestEnum.class, "POODLE").isPresent());
60 
61     assertEquals(TestEnum.CHEETO, Enums.getIfPresent(TestEnum.class, "CHEETO").get());
62     assertEquals(TestEnum.HONDA, Enums.getIfPresent(TestEnum.class, "HONDA").get());
63     assertEquals(TestEnum.POODLE, Enums.getIfPresent(TestEnum.class, "POODLE").get());
64   }
65 
testGetIfPresent_caseSensitive()66   public void testGetIfPresent_caseSensitive() {
67     assertFalse(Enums.getIfPresent(TestEnum.class, "cHEETO").isPresent());
68     assertFalse(Enums.getIfPresent(TestEnum.class, "Honda").isPresent());
69     assertFalse(Enums.getIfPresent(TestEnum.class, "poodlE").isPresent());
70   }
71 
testGetIfPresent_whenNoMatchingConstant()72   public void testGetIfPresent_whenNoMatchingConstant() {
73     assertEquals(Optional.absent(), Enums.getIfPresent(TestEnum.class, "WOMBAT"));
74   }
75 
76   @GwtIncompatible("weak references")
testGetIfPresent_doesNotPreventClassUnloading()77   public void testGetIfPresent_doesNotPreventClassUnloading() throws Exception {
78     WeakReference<?> shadowLoaderReference = doTestClassUnloading();
79     GcFinalization.awaitClear(shadowLoaderReference);
80   }
81 
82   // Create a second ClassLoader and use it to get a second version of the TestEnum class.
83   // Run Enums.getIfPresent on that other TestEnum and then return a WeakReference containing the
84   // new ClassLoader. If Enums.getIfPresent does caching that prevents the shadow TestEnum
85   // (and therefore its ClassLoader) from being unloaded, then this WeakReference will never be
86   // cleared.
87   @GwtIncompatible("weak references")
doTestClassUnloading()88   private WeakReference<?> doTestClassUnloading() throws Exception {
89     URLClassLoader myLoader = (URLClassLoader) getClass().getClassLoader();
90     URLClassLoader shadowLoader = new URLClassLoader(myLoader.getURLs(), null);
91     @SuppressWarnings("unchecked")
92     Class<TestEnum> shadowTestEnum =
93         (Class<TestEnum>) Class.forName(TestEnum.class.getName(), false, shadowLoader);
94     assertNotSame(shadowTestEnum, TestEnum.class);
95     Set<TestEnum> shadowConstants = new HashSet<TestEnum>();
96     for (TestEnum constant : TestEnum.values()) {
97       Optional<TestEnum> result = Enums.getIfPresent(shadowTestEnum, constant.name());
98       assertTrue(result.isPresent());
99       shadowConstants.add(result.get());
100     }
101     assertEquals(ImmutableSet.copyOf(shadowTestEnum.getEnumConstants()), shadowConstants);
102     Optional<TestEnum> result = Enums.getIfPresent(shadowTestEnum, "blibby");
103     assertFalse(result.isPresent());
104     return new WeakReference<ClassLoader>(shadowLoader);
105   }
106 
testStringConverter_convert()107   public void testStringConverter_convert() {
108     Converter<String, TestEnum> converter = Enums.stringConverter(TestEnum.class);
109     assertEquals(TestEnum.CHEETO, converter.convert("CHEETO"));
110     assertEquals(TestEnum.HONDA, converter.convert("HONDA"));
111     assertEquals(TestEnum.POODLE, converter.convert("POODLE"));
112     assertNull(converter.convert(null));
113     assertNull(converter.reverse().convert(null));
114   }
115 
testStringConverter_convertError()116   public void testStringConverter_convertError() {
117     Converter<String, TestEnum> converter = Enums.stringConverter(TestEnum.class);
118     try {
119       converter.convert("xxx");
120       fail();
121     } catch (IllegalArgumentException expected) {
122     }
123   }
124 
testStringConverter_reverse()125   public void testStringConverter_reverse() {
126     Converter<String, TestEnum> converter = Enums.stringConverter(TestEnum.class);
127     assertEquals("CHEETO", converter.reverse().convert(TestEnum.CHEETO));
128     assertEquals("HONDA", converter.reverse().convert(TestEnum.HONDA));
129     assertEquals("POODLE", converter.reverse().convert(TestEnum.POODLE));
130   }
131 
132   @GwtIncompatible("NullPointerTester")
testStringConverter_nullPointerTester()133   public void testStringConverter_nullPointerTester() throws Exception {
134     Converter<String, TestEnum> converter = Enums.stringConverter(TestEnum.class);
135     NullPointerTester tester = new NullPointerTester();
136     tester.testAllPublicInstanceMethods(converter);
137   }
138 
testStringConverter_nullConversions()139   public void testStringConverter_nullConversions() {
140     Converter<String, TestEnum> converter = Enums.stringConverter(TestEnum.class);
141     assertNull(converter.convert(null));
142     assertNull(converter.reverse().convert(null));
143   }
144 
145   @GwtIncompatible("Class.getName()")
testStringConverter_toString()146   public void testStringConverter_toString() {
147     assertEquals(
148         "Enums.stringConverter(com.google.common.base.EnumsTest$TestEnum.class)",
149         Enums.stringConverter(TestEnum.class).toString());
150   }
151 
testStringConverter_serialization()152   public void testStringConverter_serialization() {
153     SerializableTester.reserializeAndAssert(Enums.stringConverter(TestEnum.class));
154   }
155 
156   @GwtIncompatible("NullPointerTester")
testNullPointerExceptions()157   public void testNullPointerExceptions() {
158     NullPointerTester tester = new NullPointerTester();
159     tester.testAllPublicStaticMethods(Enums.class);
160   }
161 
162   @Retention(RetentionPolicy.RUNTIME)
163   private @interface ExampleAnnotation {}
164 
165   private enum AnEnum {
166     @ExampleAnnotation FOO,
167     BAR
168   }
169 
170   @GwtIncompatible("reflection")
testGetField()171   public void testGetField() {
172     Field foo = Enums.getField(AnEnum.FOO);
173     assertEquals("FOO", foo.getName());
174     assertTrue(foo.isAnnotationPresent(ExampleAnnotation.class));
175 
176     Field bar = Enums.getField(AnEnum.BAR);
177     assertEquals("BAR", bar.getName());
178     assertFalse(bar.isAnnotationPresent(ExampleAnnotation.class));
179   }
180 }
181