package com.netflix.governator.lifecycle;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.hamcrest.Matchers.emptyIterable;
import static org.hamcrest.Matchers.is;
import static org.objectweb.asm.ClassReader.SKIP_CODE;
import org.hamcrest.Matchers;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.objectweb.asm.ClassReader;
import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.Collections;
import java.util.Set;
import java.util.TreeSet;
public class TestAnnotationFinder {
JavaClasspath cp;
String a = "governator.test.A";
String b = "governator.test.B";
@Before
public void before()
{
cp = new JavaClasspath();
cp.compile(
"package governator.test;" +
"public @interface A {}",
"package governator.test;" +
"public @interface B {}");
}
@After
public void after()
{
cp.cleanup();
}
@Test
public void testFindAnnotationsOnClasses()
{
cp.compile(
"package governator.test;" +
"@A public class Foo {}"
);
assertThat(scan("governator.test.Foo", a).getAnnotatedClasses(), is(Matchers.<Class<?>>iterableWithSize(1)));
assertThat(scan("governator.test.Foo", b).getAnnotatedClasses(), is(emptyIterable()));
}
@Test
public void testFindAnnotationsOnFields()
{
cp.compile(
"package governator.test;" +
"public class Foo {" +
" @A private String f1;" +
" @A transient String f2;" +
" @A static String f3;" +
" @A static int f4;" +
"}"
);
AnnotationFinder finder = scan("governator.test.Foo", a);
Set<String> matchingFields = new TreeSet<>();
for (Field field : finder.getAnnotatedFields())
matchingFields.add(field.getName());
assertThat(matchingFields, containsInAnyOrder("f1", "f2", "f3", "f4"));
}
@Test
public void testFindAnnotationsOnMethods()
{
cp.compile(
"package governator.test;" +
"import java.util.Collection;" +
"public class Foo {" +
" @A private void m1() {}" +
" @A void m2(String p) {}" +
" @A void m3(String[] p) {}" +
" @A void m4(Collection<String> p) {}" +
" @A void m5(int p) {}" +
"}"
);
AnnotationFinder finder = scan("governator.test.Foo", a);
Set<String> matchingMethods = new TreeSet<>();
for (Method method : finder.getAnnotatedMethods())
matchingMethods.add(method.getName());
assertThat(matchingMethods, containsInAnyOrder("m1", "m2", "m3", "m4", "m5"));
}
@Test
public void testFindAnnotationsOnConstructors()
{
cp.compile(
"package governator.test;" +
"import java.util.Collection;" +
"public class Foo {" +
" @A private Foo() {}" +
" @A Foo(String p) {}" +
" @A Foo(String[] p) {}" +
" @A Foo(Collection<String> p) {}" +
" @A Foo(byte p) {}" +
"}"
);
assertThat(scan("governator.test.Foo", a).getAnnotatedConstructors(), is(Matchers.<Constructor>iterableWithSize(5)));
}
@Test
public void testInnerClasses()
{
Collection<String> compile = cp.compile(
"package governator.test;" +
"public class Foo {" +
" @A class Inner {}" +
" @A static class StaticInner {}" +
"}"
);
assertThat(scan("governator.test.Foo$Inner", a).getAnnotatedClasses(),
is(Matchers.<Class<?>>iterableWithSize(1)));
assertThat(scan("governator.test.Foo$StaticInner", a).getAnnotatedClasses(),
is(Matchers.<Class<?>>iterableWithSize(1)));
}
private AnnotationFinder scan(String clazz, String annotation) {
Class<? extends Annotation> aClass = cp.loadClass(annotation);
AnnotationFinder finder = new AnnotationFinder(cp.getClassLoader(), Collections.<Class<? extends Annotation>>singletonList(aClass));
new ClassReader(cp.classBytes(clazz)).accept(finder, SKIP_CODE);
return finder;
}
}