1/*
2 * Copyright (C) 2011 The Android Open Source Project
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 */
16package libcore.java.lang.reflect.annotations;
17
18import junit.framework.TestCase;
19
20import java.lang.annotation.Annotation;
21import java.lang.annotation.Retention;
22import java.lang.annotation.RetentionPolicy;
23import java.util.Arrays;
24import libcore.java.lang.reflect.annotations.AnnotatedElementTestSupport.AnnotationA;
25import libcore.java.lang.reflect.annotations.AnnotatedElementTestSupport.AnnotationB;
26
27import dalvik.system.VMRuntime;
28
29/**
30 * Tests for the behavior of Annotation instances at runtime.
31 */
32public class AnnotationsTest extends TestCase {
33
34    enum Breakfast { WAFFLES, PANCAKES }
35
36    @Retention(RetentionPolicy.RUNTIME)
37    public @interface HasDefaultsAnnotation {
38        byte a() default 5;
39        short b() default 6;
40        int c() default 7;
41        long d() default 8;
42        float e() default 9.0f;
43        double f() default 10.0;
44        char g() default 'k';
45        boolean h() default true;
46        Breakfast i() default Breakfast.WAFFLES;
47        AnnotationA j() default @AnnotationA();
48        String k() default "maple";
49        Class l() default AnnotationB.class;
50        int[] m() default { 1, 2, 3 };
51        Breakfast[] n() default { Breakfast.WAFFLES, Breakfast.PANCAKES };
52        Breakfast o();
53        int p();
54    }
55
56    public void testAnnotationDefaults() throws Exception {
57        assertEquals((byte) 5, defaultValue("a"));
58        assertEquals((short) 6, defaultValue("b"));
59        assertEquals(7, defaultValue("c"));
60        assertEquals(8L, defaultValue("d"));
61        assertEquals(9.0f, defaultValue("e"));
62        assertEquals(10.0, defaultValue("f"));
63        assertEquals('k', defaultValue("g"));
64        assertEquals(true, defaultValue("h"));
65        assertEquals(Breakfast.WAFFLES, defaultValue("i"));
66        assertEquals("@" + AnnotationA.class.getName() + "()", defaultValue("j").toString());
67        assertEquals("maple", defaultValue("k"));
68        assertEquals(AnnotationB.class, defaultValue("l"));
69        assertEquals("[1, 2, 3]", Arrays.toString((int[]) defaultValue("m")));
70        assertEquals("[WAFFLES, PANCAKES]", Arrays.toString((Breakfast[]) defaultValue("n")));
71        assertEquals(null, defaultValue("o"));
72        assertEquals(null, defaultValue("p"));
73    }
74
75    private static Object defaultValue(String name) throws NoSuchMethodException {
76        return HasDefaultsAnnotation.class.getMethod(name).getDefaultValue();
77    }
78
79    @Retention(RetentionPolicy.CLASS)
80    public @interface ClassRetentionAnnotation {}
81
82    @Retention(RetentionPolicy.RUNTIME)
83    public @interface RuntimeRetentionAnnotation {}
84
85    @Retention(RetentionPolicy.SOURCE)
86    public @interface SourceRetentionAnnotation {}
87
88    @ClassRetentionAnnotation @RuntimeRetentionAnnotation @SourceRetentionAnnotation
89    public static class RetentionAnnotations {}
90
91    public void testRetentionPolicy() {
92        // b/29500035
93        int savedTargetSdkVersion = VMRuntime.getRuntime().getTargetSdkVersion();
94        try {
95            // Test N and later behavior
96            VMRuntime.getRuntime().setTargetSdkVersion(24);
97            Annotation classRetentionAnnotation =
98                RetentionAnnotations.class.getAnnotation(ClassRetentionAnnotation.class);
99            assertNull(classRetentionAnnotation);
100
101            // Test pre-N behavior
102            VMRuntime.getRuntime().setTargetSdkVersion(23);
103            classRetentionAnnotation =
104                RetentionAnnotations.class.getAnnotation(ClassRetentionAnnotation.class);
105            assertNotNull(classRetentionAnnotation);
106        } finally {
107            VMRuntime.getRuntime().setTargetSdkVersion(savedTargetSdkVersion);
108        }
109        assertNotNull(RetentionAnnotations.class.getAnnotation(RuntimeRetentionAnnotation.class));
110        assertNull(RetentionAnnotations.class.getAnnotation(SourceRetentionAnnotation.class));
111    }
112}
113