1 /* 2 * Copyright (C) 2008 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.collect.testing.features; 18 19 import junit.framework.TestCase; 20 21 import java.lang.annotation.Annotation; 22 import java.lang.annotation.Inherited; 23 import java.lang.annotation.Retention; 24 import java.lang.annotation.RetentionPolicy; 25 import java.lang.reflect.Method; 26 27 /** 28 * Since annotations have some reusability issues that force copy and paste 29 * all over the place, it's worth having a test to ensure that all our Feature 30 * enums have their annotations correctly set up. 31 * 32 * @author George van den Driessche 33 */ 34 public class FeatureEnumTest extends TestCase { assertGoodTesterAnnotation( Class<? extends Annotation> annotationClass)35 private static void assertGoodTesterAnnotation( 36 Class<? extends Annotation> annotationClass) { 37 assertNotNull( 38 String.format("%s must be annotated with @TesterAnnotation.", 39 annotationClass), 40 annotationClass.getAnnotation(TesterAnnotation.class)); 41 final Retention retentionPolicy = 42 annotationClass.getAnnotation(Retention.class); 43 assertNotNull( 44 String.format("%s must have a @Retention annotation.", annotationClass), 45 retentionPolicy); 46 assertEquals( 47 String.format("%s must have RUNTIME RetentionPolicy.", annotationClass), 48 RetentionPolicy.RUNTIME, retentionPolicy.value()); 49 assertNotNull( 50 String.format("%s must be inherited.", annotationClass), 51 annotationClass.getAnnotation(Inherited.class)); 52 53 for (String propertyName : new String[]{"value", "absent"}) { 54 Method method = null; 55 try { 56 method = annotationClass.getMethod(propertyName); 57 } catch (NoSuchMethodException e) { 58 fail(String.format("%s must have a property named '%s'.", 59 annotationClass, propertyName)); 60 } 61 final Class<?> returnType = method.getReturnType(); 62 assertTrue(String.format("%s.%s() must return an array.", 63 annotationClass, propertyName), 64 returnType.isArray()); 65 assertSame(String.format("%s.%s() must return an array of %s.", 66 annotationClass, propertyName, annotationClass.getDeclaringClass()), 67 annotationClass.getDeclaringClass(), returnType.getComponentType()); 68 } 69 } 70 71 // This is public so that tests for Feature enums we haven't yet imagined 72 // can reuse it. assertGoodFeatureEnum( Class<E> featureEnumClass)73 public static <E extends Enum<?> & Feature<?>> void assertGoodFeatureEnum( 74 Class<E> featureEnumClass) { 75 final Class<?>[] classes = featureEnumClass.getDeclaredClasses(); 76 for (Class<?> containedClass : classes) { 77 if (containedClass.getSimpleName().equals("Require")) { 78 if (containedClass.isAnnotation()) { 79 assertGoodTesterAnnotation(asAnnotation(containedClass)); 80 } else { 81 fail(String.format("Feature enum %s contains a class named " + 82 "'Require' but it is not an annotation.", featureEnumClass)); 83 } 84 return; 85 } 86 } 87 fail(String.format("Feature enum %s should contain an " + 88 "annotation named 'Require'.", featureEnumClass)); 89 } 90 91 @SuppressWarnings("unchecked") asAnnotation(Class<?> clazz)92 private static Class<? extends Annotation> asAnnotation(Class<?> clazz) { 93 if (clazz.isAnnotation()) { 94 return (Class<? extends Annotation>) clazz; 95 } else { 96 throw new IllegalArgumentException( 97 String.format("%s is not an annotation.", clazz)); 98 } 99 } 100 testFeatureEnums()101 public void testFeatureEnums() throws Exception { 102 assertGoodFeatureEnum(CollectionFeature.class); 103 assertGoodFeatureEnum(ListFeature.class); 104 assertGoodFeatureEnum(SetFeature.class); 105 assertGoodFeatureEnum(CollectionSize.class); 106 assertGoodFeatureEnum(MapFeature.class); 107 } 108 } 109