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