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