GenericTypesTest.java revision cc05ad238516f1303687aba4a978e24e57c0c07a
1/*
2 * Copyright (C) 2008 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 */
16
17package tests.api.java.lang.reflect;
18
19import dalvik.annotation.TestTargets;
20import dalvik.annotation.TestLevel;
21import dalvik.annotation.TestTargetNew;
22import dalvik.annotation.TestTargetClass;
23
24import java.lang.reflect.Constructor;
25import java.lang.reflect.Method;
26import java.lang.reflect.ParameterizedType;
27import java.lang.reflect.Type;
28import java.lang.reflect.TypeVariable;
29
30
31/**
32 * Tests type parameters declared on classes.
33 */
34@TestTargetClass(Constructor.class)
35public class GenericTypesTest extends GenericReflectionTestsBase {
36
37    static class GenericType<T>{
38        T methodGenericType(T t){ return t;}
39        @SuppressWarnings("hiding")
40        <T> T hidingMethodGenericType(T t){ return t;}
41        static <T> T staticMethodGenericType(T t){ return t;}
42    }
43
44    static class MultipleBoundedGenericTypes<T,S extends T>{
45        void multipleBoundedGenericTypesTS(T t, S s){}
46    }
47
48    static class SimpleInheritance <T> extends GenericType<T>{}
49
50    static class ConstructorGenericType<T>{
51        ConstructorGenericType(T t){}
52    }
53
54    static class InnerClassTest<T>{
55        class InnerClass {
56            InnerClass(T t) {}
57            void innerMethod(T t){}
58        }
59    }
60
61    static class ExceptionTest<T extends Exception>{
62        void exceptionTest() throws T{}
63        class InnerClass{
64            void innerExceptionTest() throws T{}
65        }
66    }
67
68    static interface InterfaceTest<T>{}
69    @TestTargetNew(
70        level = TestLevel.PARTIAL,
71        notes = "Check positive functionality.",
72        method = "getGenericParameterTypes",
73        args = {}
74    )
75    @SuppressWarnings("unchecked")
76    public void testConstructorGenericType() throws Exception {
77        Class<? extends ConstructorGenericType> clazz = ConstructorGenericType.class;
78        TypeVariable<Class> typeVariable = getTypeParameter(clazz);
79        Constructor<?> constructor = clazz.getDeclaredConstructor(Object.class);
80        Type[] genericParameterTypes = constructor.getGenericParameterTypes();
81        assertLenghtOne(genericParameterTypes);
82        Type parameterType = genericParameterTypes[0];
83
84        assertEquals(typeVariable, parameterType);
85    }
86    @TestTargetNew(
87        level = TestLevel.PARTIAL,
88        notes = "",
89        method = "getGenericParameterTypes",
90        args = {}
91    )
92    @SuppressWarnings("unchecked")
93    public void testStaticMethodGenericType() throws Exception {
94        Class<? extends GenericType> clazz = GenericType.class;
95        TypeVariable<Class> typeVariable = getTypeParameter(clazz);
96
97        Method method = clazz.getDeclaredMethod("staticMethodGenericType", Object.class);
98        Type[] genericParameterTypes = method.getGenericParameterTypes();
99        assertLenghtOne(genericParameterTypes);
100        Type parameterType = genericParameterTypes[0];
101        assertNotEquals(typeVariable, parameterType);
102        assertInstanceOf(TypeVariable.class, parameterType);
103        assertEquals(method, ((TypeVariable)parameterType).getGenericDeclaration());
104    }
105    @TestTargetNew(
106        level = TestLevel.PARTIAL,
107        notes = "",
108        method = "getGenericParameterTypes",
109        args = {}
110    )
111    @SuppressWarnings("unchecked")
112    public void testHidingMethodGenericType() throws Exception {
113        Class<? extends GenericType> clazz = GenericType.class;
114        TypeVariable<Class> typeVariable = getTypeParameter(clazz);
115
116        Method method = clazz.getDeclaredMethod("hidingMethodGenericType",  Object.class);
117        Type[] genericParameterTypes = method.getGenericParameterTypes();
118        assertLenghtOne(genericParameterTypes);
119        Type parameterType = genericParameterTypes[0];
120        assertNotEquals(typeVariable, parameterType);
121        assertInstanceOf(TypeVariable.class, parameterType);
122        assertEquals(method, ((TypeVariable)parameterType).getGenericDeclaration());
123    }
124
125    static class MultipleGenericTypes<T,S>{
126        void multipleGenericTypesT(T t){}
127        void multipleGenericTypesS(S s){}
128        void multipleGenericTypesTS(T t, S s){}
129    }
130    @TestTargetNew(
131        level = TestLevel.PARTIAL,
132        notes = "",
133        method = "getGenericParameterTypes",
134        args = {}
135    )
136    @SuppressWarnings("unchecked")
137    public void testMultipleGenericTypes() throws Exception {
138        //Type parameters
139        Class<? extends MultipleGenericTypes> clazz = MultipleGenericTypes.class;
140        TypeVariable<?>[] typeParameters = clazz.getTypeParameters();
141        assertEquals(2, typeParameters.length);
142        TypeVariable<?> typeVariableT = typeParameters[0];
143        assertEquals(clazz, typeVariableT.getGenericDeclaration());
144        assertEquals("T", typeVariableT.getName());
145        TypeVariable<?> typeVariableS = typeParameters[1];
146        assertEquals("S", typeVariableS.getName());
147        assertEquals(clazz, typeVariableS.getGenericDeclaration());
148
149        // multipleGenericTypesT
150        Method multipleGenericTypesT = clazz.getDeclaredMethod("multipleGenericTypesT", new Class[]{Object.class});
151        Type[] multipleGenericTypesTTypes = multipleGenericTypesT.getGenericParameterTypes();
152        assertLenghtOne(multipleGenericTypesTTypes);
153        Type multipleGenericTypesTType = multipleGenericTypesTTypes[0];
154        assertEquals(typeVariableT, multipleGenericTypesTType);
155
156        // multipleGenericTypesS
157        Method multipleGenericTypesS = clazz.getDeclaredMethod("multipleGenericTypesS", new Class[]{Object.class});
158        Type[] multipleGenericTypesSTypes = multipleGenericTypesS.getGenericParameterTypes();
159        assertLenghtOne(multipleGenericTypesSTypes);
160        Type multipleGenericTypesSType = multipleGenericTypesSTypes[0];
161        assertEquals(typeVariableS, multipleGenericTypesSType);
162
163        // multipleGenericTypesS
164        Method multipleGenericTypesTS = clazz.getDeclaredMethod("multipleGenericTypesTS", new Class[]{Object.class, Object.class});
165        Type[] multipleGenericTypesTSTypes = multipleGenericTypesTS.getGenericParameterTypes();
166        assertEquals(2, multipleGenericTypesTSTypes.length);
167        Type multipleGenericTypesTSTypeT = multipleGenericTypesTSTypes[0];
168        assertEquals(typeVariableT, multipleGenericTypesTSTypeT);
169        Type multipleGenericTypesTSTypeS = multipleGenericTypesTSTypes[1];
170        assertEquals(typeVariableS, multipleGenericTypesTSTypeS);
171    }
172
173    @TestTargetNew(
174        level = TestLevel.COMPLETE,
175        notes = "",
176        method = "getTypeParameters",
177        args = {}
178    )
179    @SuppressWarnings("unchecked")
180    public void testMultipleBoundedGenericTypes() throws Exception {
181        //Type parameters
182        Class<? extends MultipleBoundedGenericTypes> clazz = MultipleBoundedGenericTypes.class;
183        TypeVariable<?>[] typeParameters = clazz.getTypeParameters();
184        assertEquals(2, typeParameters.length);
185        TypeVariable<?> typeVariableT = typeParameters[0];
186        assertEquals(clazz, typeVariableT.getGenericDeclaration());
187        assertEquals("T", typeVariableT.getName());
188        TypeVariable<?> typeVariableS = typeParameters[1];
189        assertEquals("S", typeVariableS.getName());
190        assertEquals(clazz, typeVariableS.getGenericDeclaration());
191        Type[] boundsS = typeVariableS.getBounds();
192        assertLenghtOne(boundsS);
193        Type boundS = boundsS[0];
194        assertEquals(typeVariableT, boundS);
195    }
196    @TestTargetNew(
197        level = TestLevel.PARTIAL,
198        notes = "",
199        method = "getGenericParameterTypes",
200        args = {}
201    )
202    @SuppressWarnings("unchecked")
203    public void testSimpleInheritance() throws Exception {
204        Class<? extends SimpleInheritance> clazz = SimpleInheritance.class;
205        TypeVariable<Class> subTypeVariable = getTypeParameter(clazz);
206
207        assertInstanceOf(ParameterizedType.class, clazz.getGenericSuperclass());
208        ParameterizedType parameterizedSuperType = (ParameterizedType) clazz.getGenericSuperclass();
209        assertInstanceOf(Class.class, parameterizedSuperType.getRawType());
210
211        TypeVariable<Class> superTypeParameter = getTypeParameter((Class<?>)parameterizedSuperType.getRawType());
212        TypeVariable<Class> typeParameter = getTypeParameter(GenericType.class);
213        assertEquals(superTypeParameter, typeParameter);
214
215        assertNotEquals(subTypeVariable, superTypeParameter);
216
217        Type[] actualTypeArguments = parameterizedSuperType.getActualTypeArguments();
218        assertLenghtOne(actualTypeArguments);
219        assertInstanceOf(TypeVariable.class, actualTypeArguments[0]);
220        TypeVariable actualSuperTypeVariable = (TypeVariable) actualTypeArguments[0];
221        assertEquals(subTypeVariable, actualSuperTypeVariable);
222    }
223    @TestTargetNew(
224        level = TestLevel.PARTIAL,
225        notes = "Doesn't check exceptions.",
226        method = "getGenericParameterTypes",
227        args = {}
228    )
229    @SuppressWarnings("unchecked")
230    public void testInnerClassTest() throws Exception {
231        Class<? extends InnerClassTest> clazz =InnerClassTest.class;
232        TypeVariable<Class> typeVariable = getTypeParameter(clazz);
233
234        Class<?>[] declaredClasses = clazz.getDeclaredClasses();
235        assertLenghtOne(declaredClasses);
236        Class<?> innerClazz = declaredClasses[0];
237        assertEquals(InnerClassTest.InnerClass.class, innerClazz);
238
239        //constructor
240        Constructor<?>[] declaredConstructors = innerClazz.getDeclaredConstructors();
241        assertLenghtOne(declaredConstructors);
242        Constructor<?> declaredConstructor = declaredConstructors[0];
243        Type[] genericParameterTypes = declaredConstructor.getGenericParameterTypes();
244        assertLenghtOne(genericParameterTypes);
245        assertEquals(typeVariable, genericParameterTypes[0]);
246        assertInstanceOf(TypeVariable.class, genericParameterTypes[0]);
247        TypeVariable<?> constructorTypeVariable = (TypeVariable<?>) genericParameterTypes[0];
248        assertEquals(clazz ,constructorTypeVariable.getGenericDeclaration());
249
250        //method
251        Method declaredMethods = innerClazz.getDeclaredMethod("innerMethod", Object.class);
252        Type[] methodParameterTypes = declaredMethods.getGenericParameterTypes();
253        assertLenghtOne(methodParameterTypes);
254        assertEquals(typeVariable, methodParameterTypes[0]);
255        assertInstanceOf(TypeVariable.class, methodParameterTypes[0]);
256        TypeVariable<?> methodTypeVariable = (TypeVariable<?>) methodParameterTypes[0];
257        assertEquals(clazz, methodTypeVariable.getGenericDeclaration());
258    }
259    @TestTargetNew(
260        level = TestLevel.PARTIAL,
261        notes = "Exceptions are not verified.",
262        method = "getGenericExceptionTypes",
263        args = {}
264    )
265    @SuppressWarnings("unchecked")
266    public void testException() throws Exception {
267        Class<? extends ExceptionTest> clazz = ExceptionTest.class;
268        TypeVariable<Class> typeVariable = getTypeParameter(clazz);
269        Method method = clazz.getDeclaredMethod("exceptionTest");
270        Type[] genericExceptionTypes = method.getGenericExceptionTypes();
271        assertLenghtOne(genericExceptionTypes);
272        assertEquals(typeVariable, genericExceptionTypes[0]);
273
274        Class<?>[] declaredClasses = clazz.getDeclaredClasses();
275        assertLenghtOne(declaredClasses);
276        Class<?> innerClazz = declaredClasses[0];
277        assertEquals(ExceptionTest.InnerClass.class, innerClazz);
278
279        //method
280        Method declaredMethods = innerClazz.getDeclaredMethod("innerExceptionTest");
281        Type[] exceptionTypes = declaredMethods.getGenericExceptionTypes();
282        assertLenghtOne(exceptionTypes);
283        assertEquals(typeVariable, exceptionTypes[0]);
284        assertInstanceOf(TypeVariable.class, exceptionTypes[0]);
285        TypeVariable<?> methodTypeVariable = (TypeVariable<?>) exceptionTypes[0];
286        assertEquals(clazz, methodTypeVariable.getGenericDeclaration());
287    }
288}
289