summaryrefslogtreecommitdiffstats
path: root/luni/src/test/java/libcore/java/lang/reflect/AnnotationsTest.java
diff options
context:
space:
mode:
Diffstat (limited to 'luni/src/test/java/libcore/java/lang/reflect/AnnotationsTest.java')
-rw-r--r--luni/src/test/java/libcore/java/lang/reflect/AnnotationsTest.java277
1 files changed, 275 insertions, 2 deletions
diff --git a/luni/src/test/java/libcore/java/lang/reflect/AnnotationsTest.java b/luni/src/test/java/libcore/java/lang/reflect/AnnotationsTest.java
index c23775e..4cc69ba 100644
--- a/luni/src/test/java/libcore/java/lang/reflect/AnnotationsTest.java
+++ b/luni/src/test/java/libcore/java/lang/reflect/AnnotationsTest.java
@@ -16,6 +16,7 @@
package libcore.java.lang.reflect;
+import java.io.IOException;
import java.lang.annotation.Annotation;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
@@ -23,7 +24,11 @@ import java.lang.annotation.RetentionPolicy;
import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.Proxy;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
@@ -56,7 +61,13 @@ public final class AnnotationsTest extends TestCase {
public void testParameterAnnotations() throws Exception {
Method method = Type.class.getMethod("method", String.class, String.class);
- Annotation[][] parameterAnnotations = method.getParameterAnnotations();
+ Annotation[][] noParameterAnnotations = method.getParameterAnnotations();
+ assertEquals(2, noParameterAnnotations.length);
+ assertEquals(set(), annotationsToTypes(noParameterAnnotations[0]));
+ assertEquals(set(), annotationsToTypes(noParameterAnnotations[1]));
+
+ Method parameters = Type.class.getMethod("parameters", String.class, String.class);
+ Annotation[][] parameterAnnotations = parameters.getParameterAnnotations();
assertEquals(2, parameterAnnotations.length);
assertEquals(set(AnnotationB.class, AnnotationD.class),
annotationsToTypes(parameterAnnotations[0]));
@@ -64,6 +75,206 @@ public final class AnnotationsTest extends TestCase {
annotationsToTypes(parameterAnnotations[1]));
}
+ public void testAnnotationDefaults() throws Exception {
+ assertEquals((byte) 5, defaultValue("a"));
+ assertEquals((short) 6, defaultValue("b"));
+ assertEquals(7, defaultValue("c"));
+ assertEquals(8L, defaultValue("d"));
+ assertEquals(9.0f, defaultValue("e"));
+ assertEquals(10.0, defaultValue("f"));
+ assertEquals('k', defaultValue("g"));
+ assertEquals(true, defaultValue("h"));
+ assertEquals(Breakfast.WAFFLES, defaultValue("i"));
+ assertEquals("@" + AnnotationA.class.getName() + "()", defaultValue("j").toString());
+ assertEquals("maple", defaultValue("k"));
+ assertEquals(AnnotationB.class, defaultValue("l"));
+ assertEquals("[1, 2, 3]", Arrays.toString((int[]) defaultValue("m")));
+ assertEquals("[WAFFLES, PANCAKES]", Arrays.toString((Breakfast[]) defaultValue("n")));
+ assertEquals(null, defaultValue("o"));
+ assertEquals(null, defaultValue("p"));
+ }
+
+ private Object defaultValue(String name) throws NoSuchMethodException {
+ return HasDefaultsAnnotation.class.getMethod(name).getDefaultValue();
+ }
+
+ public void testGetEnclosingClass() {
+ assertNull(AnnotationsTest.class.getEnclosingClass());
+ assertEquals(AnnotationsTest.class, Foo.class.getEnclosingClass());
+ assertEquals(AnnotationsTest.class, HasMemberClassesInterface.class.getEnclosingClass());
+ assertEquals(HasMemberClassesInterface.class,
+ HasMemberClassesInterface.D.class.getEnclosingClass());
+ assertEquals(AnnotationsTest.class, Foo.class.getEnclosingClass());
+ }
+
+ public void testGetDeclaringClass() {
+ assertNull(AnnotationsTest.class.getDeclaringClass());
+ assertEquals(AnnotationsTest.class, Foo.class.getDeclaringClass());
+ assertEquals(AnnotationsTest.class, HasMemberClassesInterface.class.getDeclaringClass());
+ assertEquals(HasMemberClassesInterface.class,
+ HasMemberClassesInterface.D.class.getDeclaringClass());
+ }
+
+ public void testGetEnclosingClassIsTransitiveForClassesDefinedInAMethod() {
+ class C {}
+ assertEquals(AnnotationsTest.class, C.class.getEnclosingClass());
+ }
+
+ public void testGetDeclaringClassIsNotTransitiveForClassesDefinedInAMethod() {
+ class C {}
+ assertEquals(null, C.class.getDeclaringClass());
+ }
+
+ public void testGetEnclosingMethodIsNotTransitive() {
+ class C {
+ class D {}
+ }
+ assertEquals(null, C.D.class.getEnclosingMethod());
+ }
+
+ public void testStaticFieldAnonymousClass() {
+ // The class declared in the <clinit> is enclosed by the <clinit>'s class.
+ // http://b/11245138
+ assertEquals(AnnotationsTest.class, staticAnonymous.getClass().getEnclosingClass());
+ // However, because it is anonymous, it has no declaring class.
+ // https://code.google.com/p/android/issues/detail?id=61003
+ assertNull(staticAnonymous.getClass().getDeclaringClass());
+ // Because the class is declared in <clinit> which is not exposed through reflection,
+ // it has no enclosing method or constructor.
+ assertNull(staticAnonymous.getClass().getEnclosingMethod());
+ assertNull(staticAnonymous.getClass().getEnclosingConstructor());
+ }
+
+ public void testGetEnclosingMethodOfTopLevelClass() {
+ assertNull(AnnotationsTest.class.getEnclosingMethod());
+ }
+
+ public void testGetEnclosingConstructorOfTopLevelClass() {
+ assertNull(AnnotationsTest.class.getEnclosingConstructor());
+ }
+
+ public void testClassEnclosedByConstructor() throws Exception {
+ Foo foo = new Foo("string");
+ assertEquals(Foo.class, foo.c.getEnclosingClass());
+ assertEquals(Foo.class.getDeclaredConstructor(String.class),
+ foo.c.getEnclosingConstructor());
+ assertNull(foo.c.getEnclosingMethod());
+ assertNull(foo.c.getDeclaringClass());
+ }
+
+ public void testClassEnclosedByMethod() throws Exception {
+ Foo foo = new Foo();
+ foo.foo("string");
+ assertEquals(Foo.class, foo.c.getEnclosingClass());
+ assertNull(foo.c.getEnclosingConstructor());
+ assertEquals(Foo.class.getDeclaredMethod("foo", String.class),
+ foo.c.getEnclosingMethod());
+ assertNull(foo.c.getDeclaringClass());
+ }
+
+ public void testGetClasses() throws Exception {
+ // getClasses() doesn't include classes inherited from interfaces!
+ assertSetEquals(HasMemberClasses.class.getClasses(),
+ HasMemberClassesSuperclass.B.class, HasMemberClasses.H.class);
+ }
+
+ public void testGetDeclaredClasses() throws Exception {
+ assertSetEquals(HasMemberClasses.class.getDeclaredClasses(),
+ HasMemberClasses.G.class, HasMemberClasses.H.class, HasMemberClasses.I.class,
+ HasMemberClasses.J.class, HasMemberClasses.K.class, HasMemberClasses.L.class);
+ }
+
+ public void testConstructorGetExceptions() throws Exception {
+ assertSetEquals(HasThrows.class.getConstructor().getExceptionTypes(),
+ IOException.class, InvocationTargetException.class, IllegalStateException.class);
+ assertSetEquals(HasThrows.class.getConstructor(Void.class).getExceptionTypes());
+ }
+
+ public void testClassMethodGetExceptions() throws Exception {
+ assertSetEquals(HasThrows.class.getMethod("foo").getExceptionTypes(),
+ IOException.class, InvocationTargetException.class, IllegalStateException.class);
+ assertSetEquals(HasThrows.class.getMethod("foo", Void.class).getExceptionTypes());
+ }
+
+ public void testProxyMethodGetExceptions() throws Exception {
+ InvocationHandler emptyInvocationHandler = new InvocationHandler() {
+ @Override public Object invoke(Object proxy, Method method, Object[] args) {
+ return null;
+ }
+ };
+
+ Object proxy = Proxy.newProxyInstance(getClass().getClassLoader(),
+ new Class[] { ThrowsInterface.class }, emptyInvocationHandler);
+ assertSetEquals(proxy.getClass().getMethod("foo").getExceptionTypes(),
+ IOException.class, InvocationTargetException.class, IllegalStateException.class);
+ assertSetEquals(proxy.getClass().getMethod("foo", Void.class).getExceptionTypes());
+ }
+
+ public void testClassModifiers() {
+ int modifiers = AnnotationsTest.class.getModifiers();
+ assertTrue(Modifier.isPublic(modifiers));
+ assertFalse(Modifier.isProtected(modifiers));
+ assertFalse(Modifier.isPrivate(modifiers));
+ assertFalse(Modifier.isAbstract(modifiers));
+ assertFalse(Modifier.isStatic(modifiers));
+ assertTrue(Modifier.isFinal(modifiers));
+ assertFalse(Modifier.isStrict(modifiers));
+ }
+
+ public void testInnerClassModifiers() {
+ int modifiers = Foo.class.getModifiers();
+ assertFalse(Modifier.isPublic(modifiers));
+ assertFalse(Modifier.isProtected(modifiers));
+ assertTrue(Modifier.isPrivate(modifiers));
+ assertFalse(Modifier.isAbstract(modifiers));
+ assertTrue(Modifier.isStatic(modifiers));
+ assertFalse(Modifier.isFinal(modifiers));
+ assertFalse(Modifier.isStrict(modifiers));
+ }
+
+ public void testAnonymousClassModifiers() {
+ int modifiers = staticAnonymous.getClass().getModifiers();
+ assertFalse(Modifier.isPublic(modifiers));
+ assertFalse(Modifier.isProtected(modifiers));
+ assertFalse(Modifier.isPrivate(modifiers));
+ assertFalse(Modifier.isAbstract(modifiers));
+ assertTrue(Modifier.isStatic(modifiers));
+ assertFalse(Modifier.isFinal(modifiers));
+ assertFalse(Modifier.isStrict(modifiers));
+ }
+
+ public void testInnerClassName() {
+ assertEquals("AnnotationsTest", AnnotationsTest.class.getSimpleName());
+ assertEquals("Foo", Foo.class.getSimpleName());
+ assertEquals("", staticAnonymous.getClass().getSimpleName());
+ }
+
+ public void testIsAnonymousClass() {
+ assertFalse(AnnotationsTest.class.isAnonymousClass());
+ assertFalse(Foo.class.isAnonymousClass());
+ assertTrue(staticAnonymous.getClass().isAnonymousClass());
+ }
+
+ private static final Object staticAnonymous = new Object() {};
+
+ private static class Foo {
+ Class<?> c;
+ private Foo() {
+ }
+ private Foo(String s) {
+ c = new Object() {}.getClass();
+ }
+ private Foo(int i) {
+ c = new Object() {}.getClass();
+ }
+ private void foo(String s) {
+ c = new Object() {}.getClass();
+ }
+ private void foo(int i) {
+ c = new Object() {}.getClass();
+ }
+ }
+
@Retention(RetentionPolicy.RUNTIME)
public @interface AnnotationA {}
@@ -81,12 +292,68 @@ public final class AnnotationsTest extends TestCase {
public static class Type {
@AnnotationA @AnnotationC public Type() {}
@AnnotationA @AnnotationD public String field;
- @AnnotationB @AnnotationC public void method(@AnnotationB @AnnotationD String parameter1,
+ @AnnotationB @AnnotationC public void method(String parameter1, String parameter2) {}
+ @AnnotationB @AnnotationC public void parameters(@AnnotationB @AnnotationD String parameter1,
@AnnotationC @AnnotationD String parameter2) {}
}
public static class ExtendsType extends Type {}
+ static enum Breakfast { WAFFLES, PANCAKES }
+
+ @Retention(RetentionPolicy.RUNTIME)
+ public @interface HasDefaultsAnnotation {
+ byte a() default 5;
+ short b() default 6;
+ int c() default 7;
+ long d() default 8;
+ float e() default 9.0f;
+ double f() default 10.0;
+ char g() default 'k';
+ boolean h() default true;
+ Breakfast i() default Breakfast.WAFFLES;
+ AnnotationA j() default @AnnotationA();
+ String k() default "maple";
+ Class l() default AnnotationB.class;
+ int[] m() default { 1, 2, 3 };
+ Breakfast[] n() default { Breakfast.WAFFLES, Breakfast.PANCAKES };
+ Breakfast o();
+ int p();
+ }
+
+ static class HasMemberClassesSuperclass {
+ class A {}
+ public class B {}
+ static class C {}
+ }
+
+ public interface HasMemberClassesInterface {
+ class D {}
+ public class E {}
+ static class F {}
+ }
+
+ public static class HasMemberClasses extends HasMemberClassesSuperclass
+ implements HasMemberClassesInterface {
+ class G {}
+ public class H {}
+ static class I {}
+ enum J {}
+ interface K {}
+ @interface L {}
+ }
+
+ public static class HasThrows {
+ public HasThrows() throws IOException, InvocationTargetException, IllegalStateException {}
+ public HasThrows(Void v) {}
+ public void foo() throws IOException, InvocationTargetException, IllegalStateException {}
+ public void foo(Void v) {}
+ }
+
+ public static interface ThrowsInterface {
+ void foo() throws IOException, InvocationTargetException, IllegalStateException;
+ void foo(Void v);
+ }
private void assertAnnotatedElement(
AnnotatedElement element, Class<? extends Annotation>... expectedAnnotations) {
@@ -134,4 +401,10 @@ public final class AnnotationsTest extends TestCase {
private <T> Set<T> set(T... instances) {
return new HashSet<T>(Arrays.asList(instances));
}
+
+ private void assertSetEquals(Object[] actual, Object... expected) {
+ Set<Object> actualSet = new HashSet<Object>(Arrays.asList(actual));
+ Set<Object> expectedSet = new HashSet<Object>(Arrays.asList(expected));
+ assertEquals(expectedSet, actualSet);
+ }
}