package org.springframework.roo.classpath.details.annotations.populator;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import org.apache.commons.lang3.Validate;
import org.junit.Test;
/**
* Convenience superclass for unit-testing subclasses of
* {@link AbstractAnnotationValues}
*
* @author Andrew Swan
* @since 1.2.0
* @param <A> the annotation type
* @param <V> the annotation values class
*/
public abstract class AnnotationValuesTestCase<A, V extends AbstractAnnotationValues> {
/**
* Subclasses must return the class of annotation whose value class is being
* tested
*
* @return a non-<code>null</code> annotation type
*/
protected abstract Class<A> getAnnotationClass();
/**
* Subclasses must return the values class being tested
*
* @return a non-<code>null</code> class
*/
protected abstract Class<V> getValuesClass();
@Test
public void testAllAnnotationAttributesHaveAValueField() {
final Class<A> annotationClass = getAnnotationClass();
assertTrue("Invalid annotation class " + annotationClass, annotationClass.isAnnotation());
for (final Method method : annotationClass.getDeclaredMethods()) {
// Look for a field of this name in the values class or any
// superclass
final Field valueField = findField(getValuesClass(), method.getName());
assertNotNull("No value field found for annotation attribute " + method, valueField);
final int fieldModifiers = valueField.getModifiers();
assertFalse("Value field " + valueField + " is final", Modifier.isFinal(fieldModifiers));
assertNotNull("Value field " + valueField + " is not auto-populated",
valueField.getAnnotation(AutoPopulate.class));
}
}
private Field findField(final Class<?> clazz, final String name) {
Validate.notNull(clazz, "Class must not be null");
Validate.notNull(name, "Either name or type of the field must be specified");
Class<?> searchType = clazz;
while (!Object.class.equals(searchType) && searchType != null) {
final Field[] fields = searchType.getDeclaredFields();
for (final Field field : fields) {
if (name.equals(field.getName())) {
return field;
}
}
searchType = searchType.getSuperclass();
}
return null;
}
}