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.EqualsTester; 23 import com.google.common.testing.GcFinalization; 24 import com.google.common.testing.NullPointerTester; 25 import com.google.common.testing.SerializableTester; 26 27 import junit.framework.TestCase; 28 29 import java.lang.annotation.Retention; 30 import java.lang.annotation.RetentionPolicy; 31 import java.lang.ref.WeakReference; 32 import java.lang.reflect.Field; 33 import java.net.URLClassLoader; 34 import java.util.HashSet; 35 import java.util.Set; 36 37 /** 38 * Tests for {@link Enums}. 39 * 40 * @author Steve McKay 41 */ 42 @GwtCompatible(emulated = true) 43 public class EnumsTest extends TestCase { 44 45 private enum TestEnum { 46 CHEETO, 47 HONDA, 48 POODLE, 49 } 50 51 private enum OtherEnum {} 52 testValueOfFunction()53 public void testValueOfFunction() { 54 Function<String, TestEnum> function = Enums.valueOfFunction(TestEnum.class); 55 assertEquals(TestEnum.CHEETO, function.apply("CHEETO")); 56 assertEquals(TestEnum.HONDA, function.apply("HONDA")); 57 assertEquals(TestEnum.POODLE, function.apply("POODLE")); 58 } 59 testValueOfFunction_caseSensitive()60 public void testValueOfFunction_caseSensitive() { 61 Function<String, TestEnum> function = Enums.valueOfFunction(TestEnum.class); 62 assertNull(function.apply("cHEETO")); 63 assertNull(function.apply("Honda")); 64 assertNull(function.apply("poodlE")); 65 } 66 testValueOfFunction_nullWhenNoMatchingConstant()67 public void testValueOfFunction_nullWhenNoMatchingConstant() { 68 Function<String, TestEnum> function = Enums.valueOfFunction(TestEnum.class); 69 assertNull(function.apply("WOMBAT")); 70 } 71 testValueOfFunction_equals()72 public void testValueOfFunction_equals() { 73 new EqualsTester() 74 .addEqualityGroup( 75 Enums.valueOfFunction(TestEnum.class), Enums.valueOfFunction(TestEnum.class)) 76 .addEqualityGroup(Enums.valueOfFunction(OtherEnum.class)) 77 .testEquals(); 78 } 79 80 @GwtIncompatible("SerializableTester") testValueOfFunction_serialization()81 public void testValueOfFunction_serialization() { 82 Function<String, TestEnum> function = Enums.valueOfFunction(TestEnum.class); 83 SerializableTester.reserializeAndAssert(function); 84 } 85 testGetIfPresent()86 public void testGetIfPresent() { 87 assertEquals(Optional.of(TestEnum.CHEETO), Enums.getIfPresent(TestEnum.class, "CHEETO")); 88 assertEquals(Optional.of(TestEnum.HONDA), Enums.getIfPresent(TestEnum.class, "HONDA")); 89 assertEquals(Optional.of(TestEnum.POODLE), Enums.getIfPresent(TestEnum.class, "POODLE")); 90 91 assertTrue(Enums.getIfPresent(TestEnum.class, "CHEETO").isPresent()); 92 assertTrue(Enums.getIfPresent(TestEnum.class, "HONDA").isPresent()); 93 assertTrue(Enums.getIfPresent(TestEnum.class, "POODLE").isPresent()); 94 95 assertEquals(TestEnum.CHEETO, Enums.getIfPresent(TestEnum.class, "CHEETO").get()); 96 assertEquals(TestEnum.HONDA, Enums.getIfPresent(TestEnum.class, "HONDA").get()); 97 assertEquals(TestEnum.POODLE, Enums.getIfPresent(TestEnum.class, "POODLE").get()); 98 } 99 testGetIfPresent_caseSensitive()100 public void testGetIfPresent_caseSensitive() { 101 assertFalse(Enums.getIfPresent(TestEnum.class, "cHEETO").isPresent()); 102 assertFalse(Enums.getIfPresent(TestEnum.class, "Honda").isPresent()); 103 assertFalse(Enums.getIfPresent(TestEnum.class, "poodlE").isPresent()); 104 } 105 testGetIfPresent_whenNoMatchingConstant()106 public void testGetIfPresent_whenNoMatchingConstant() { 107 assertEquals(Optional.absent(), Enums.getIfPresent(TestEnum.class, "WOMBAT")); 108 } 109 110 @GwtIncompatible("weak references") testGetIfPresent_doesNotPreventClassUnloading()111 public void testGetIfPresent_doesNotPreventClassUnloading() throws Exception { 112 WeakReference<?> shadowLoaderReference = doTestClassUnloading(); 113 GcFinalization.awaitClear(shadowLoaderReference); 114 } 115 116 // Create a second ClassLoader and use it to get a second version of the TestEnum class. 117 // Run Enums.getIfPresent on that other TestEnum and then return a WeakReference containing the 118 // new ClassLoader. If Enums.getIfPresent does caching that prevents the shadow TestEnum 119 // (and therefore its ClassLoader) from being unloaded, then this WeakReference will never be 120 // cleared. 121 @GwtIncompatible("weak references") doTestClassUnloading()122 private WeakReference<?> doTestClassUnloading() throws Exception { 123 URLClassLoader myLoader = (URLClassLoader) getClass().getClassLoader(); 124 URLClassLoader shadowLoader = new URLClassLoader(myLoader.getURLs(), null); 125 @SuppressWarnings("unchecked") 126 Class<TestEnum> shadowTestEnum = 127 (Class<TestEnum>) Class.forName(TestEnum.class.getName(), false, shadowLoader); 128 assertNotSame(shadowTestEnum, TestEnum.class); 129 Set<TestEnum> shadowConstants = new HashSet<TestEnum>(); 130 for (TestEnum constant : TestEnum.values()) { 131 Optional<TestEnum> result = Enums.getIfPresent(shadowTestEnum, constant.name()); 132 assertTrue(result.isPresent()); 133 shadowConstants.add(result.get()); 134 } 135 assertEquals(ImmutableSet.copyOf(shadowTestEnum.getEnumConstants()), shadowConstants); 136 Optional<TestEnum> result = Enums.getIfPresent(shadowTestEnum, "blibby"); 137 assertFalse(result.isPresent()); 138 return new WeakReference<ClassLoader>(shadowLoader); 139 } 140 testStringConverter_convert()141 public void testStringConverter_convert() { 142 Converter<String, TestEnum> converter = Enums.stringConverter(TestEnum.class); 143 assertEquals(TestEnum.CHEETO, converter.convert("CHEETO")); 144 assertEquals(TestEnum.HONDA, converter.convert("HONDA")); 145 assertEquals(TestEnum.POODLE, converter.convert("POODLE")); 146 assertNull(converter.convert(null)); 147 assertNull(converter.reverse().convert(null)); 148 } 149 testStringConverter_convertError()150 public void testStringConverter_convertError() { 151 Converter<String, TestEnum> converter = Enums.stringConverter(TestEnum.class); 152 try { 153 converter.convert("xxx"); 154 fail(); 155 } catch (IllegalArgumentException expected) { 156 } 157 } 158 testStringConverter_reverse()159 public void testStringConverter_reverse() { 160 Converter<String, TestEnum> converter = Enums.stringConverter(TestEnum.class); 161 assertEquals("CHEETO", converter.reverse().convert(TestEnum.CHEETO)); 162 assertEquals("HONDA", converter.reverse().convert(TestEnum.HONDA)); 163 assertEquals("POODLE", converter.reverse().convert(TestEnum.POODLE)); 164 } 165 166 @GwtIncompatible("NullPointerTester") testStringConverter_nullPointerTester()167 public void testStringConverter_nullPointerTester() throws Exception { 168 Converter<String, TestEnum> converter = Enums.stringConverter(TestEnum.class); 169 NullPointerTester tester = new NullPointerTester(); 170 tester.testAllPublicInstanceMethods(converter); 171 } 172 testStringConverter_nullConversions()173 public void testStringConverter_nullConversions() { 174 Converter<String, TestEnum> converter = Enums.stringConverter(TestEnum.class); 175 assertNull(converter.convert(null)); 176 assertNull(converter.reverse().convert(null)); 177 } 178 179 @GwtIncompatible("Class.getName()") testStringConverter_toString()180 public void testStringConverter_toString() { 181 assertEquals( 182 "Enums.stringConverter(com.google.common.base.EnumsTest$TestEnum.class)", 183 Enums.stringConverter(TestEnum.class).toString()); 184 } 185 testStringConverter_serialization()186 public void testStringConverter_serialization() { 187 SerializableTester.reserializeAndAssert(Enums.stringConverter(TestEnum.class)); 188 } 189 190 @GwtIncompatible("NullPointerTester") testNullPointerExceptions()191 public void testNullPointerExceptions() { 192 NullPointerTester tester = new NullPointerTester(); 193 tester.testAllPublicStaticMethods(Enums.class); 194 } 195 196 @Retention(RetentionPolicy.RUNTIME) 197 private @interface ExampleAnnotation {} 198 199 private enum AnEnum { 200 @ExampleAnnotation FOO, 201 BAR 202 } 203 204 @GwtIncompatible("reflection") testGetField()205 public void testGetField() { 206 Field foo = Enums.getField(AnEnum.FOO); 207 assertEquals("FOO", foo.getName()); 208 assertTrue(foo.isAnnotationPresent(ExampleAnnotation.class)); 209 210 Field bar = Enums.getField(AnEnum.BAR); 211 assertEquals("BAR", bar.getName()); 212 assertFalse(bar.isAnnotationPresent(ExampleAnnotation.class)); 213 } 214 } 215