GenericTypesTest.java revision ddc0d4c2f8d3fea4ddaf6e611ffd73a1169447e8
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("Fails in CTS but passes under run-core-tests")
205    public void testSimpleInheritance() throws Exception {
206        Class<? extends SimpleInheritance> clazz = SimpleInheritance.class;
207        TypeVariable<Class> subTypeVariable = getTypeParameter(clazz);
208
209        assertInstanceOf(ParameterizedType.class, clazz.getGenericSuperclass());
210        ParameterizedType parameterizedSuperType = (ParameterizedType) clazz.getGenericSuperclass();
211        assertInstanceOf(Class.class, parameterizedSuperType.getRawType());
212
213        TypeVariable<Class> superTypeParameter = getTypeParameter((Class<?>)parameterizedSuperType.getRawType());
214        TypeVariable<Class> typeParameter = getTypeParameter(GenericType.class);
215        assertEquals(superTypeParameter, typeParameter);
216
217        assertNotEquals(subTypeVariable, superTypeParameter);
218
219        Type[] actualTypeArguments = parameterizedSuperType.getActualTypeArguments();
220        assertLenghtOne(actualTypeArguments);
221        assertInstanceOf(TypeVariable.class, actualTypeArguments[0]);
222        TypeVariable actualSuperTypeVariable = (TypeVariable) actualTypeArguments[0];
223        assertEquals(subTypeVariable, actualSuperTypeVariable);
224    }
225    @TestTargetNew(
226        level = TestLevel.PARTIAL,
227        notes = "Doesn't check exceptions.",
228        method = "getGenericParameterTypes",
229        args = {}
230    )
231    @SuppressWarnings("unchecked")
232    public void testInnerClassTest() throws Exception {
233        Class<? extends InnerClassTest> clazz =InnerClassTest.class;
234        TypeVariable<Class> typeVariable = getTypeParameter(clazz);
235
236        Class<?>[] declaredClasses = clazz.getDeclaredClasses();
237        assertLenghtOne(declaredClasses);
238        Class<?> innerClazz = declaredClasses[0];
239        assertEquals(InnerClassTest.InnerClass.class, innerClazz);
240
241        //constructor
242        Constructor<?>[] declaredConstructors = innerClazz.getDeclaredConstructors();
243        assertLenghtOne(declaredConstructors);
244        Constructor<?> declaredConstructor = declaredConstructors[0];
245        Type[] genericParameterTypes = declaredConstructor.getGenericParameterTypes();
246        assertLenghtOne(genericParameterTypes);
247        assertEquals(typeVariable, genericParameterTypes[0]);
248        assertInstanceOf(TypeVariable.class, genericParameterTypes[0]);
249        TypeVariable<?> constructorTypeVariable = (TypeVariable<?>) genericParameterTypes[0];
250        assertEquals(clazz ,constructorTypeVariable.getGenericDeclaration());
251
252        //method
253        Method declaredMethods = innerClazz.getDeclaredMethod("innerMethod", Object.class);
254        Type[] methodParameterTypes = declaredMethods.getGenericParameterTypes();
255        assertLenghtOne(methodParameterTypes);
256        assertEquals(typeVariable, methodParameterTypes[0]);
257        assertInstanceOf(TypeVariable.class, methodParameterTypes[0]);
258        TypeVariable<?> methodTypeVariable = (TypeVariable<?>) methodParameterTypes[0];
259        assertEquals(clazz, methodTypeVariable.getGenericDeclaration());
260    }
261    @TestTargetNew(
262        level = TestLevel.PARTIAL,
263        notes = "Exceptions are not verified.",
264        method = "getGenericExceptionTypes",
265        args = {}
266    )
267    @SuppressWarnings("unchecked")
268    public void testException() throws Exception {
269        Class<? extends ExceptionTest> clazz = ExceptionTest.class;
270        TypeVariable<Class> typeVariable = getTypeParameter(clazz);
271        Method method = clazz.getDeclaredMethod("exceptionTest");
272        Type[] genericExceptionTypes = method.getGenericExceptionTypes();
273        assertLenghtOne(genericExceptionTypes);
274        assertEquals(typeVariable, genericExceptionTypes[0]);
275
276        Class<?>[] declaredClasses = clazz.getDeclaredClasses();
277        assertLenghtOne(declaredClasses);
278        Class<?> innerClazz = declaredClasses[0];
279        assertEquals(ExceptionTest.InnerClass.class, innerClazz);
280
281        //method
282        Method declaredMethods = innerClazz.getDeclaredMethod("innerExceptionTest");
283        Type[] exceptionTypes = declaredMethods.getGenericExceptionTypes();
284        assertLenghtOne(exceptionTypes);
285        assertEquals(typeVariable, exceptionTypes[0]);
286        assertInstanceOf(TypeVariable.class, exceptionTypes[0]);
287        TypeVariable<?> methodTypeVariable = (TypeVariable<?>) exceptionTypes[0];
288        assertEquals(clazz, methodTypeVariable.getGenericDeclaration());
289    }
290}
291