1710813b3b4078a814480bd5f5b2e0bc7958336d9Jesse Wilson/*
2710813b3b4078a814480bd5f5b2e0bc7958336d9Jesse Wilson * Copyright (C) 2010 The Android Open Source Project
3710813b3b4078a814480bd5f5b2e0bc7958336d9Jesse Wilson *
4710813b3b4078a814480bd5f5b2e0bc7958336d9Jesse Wilson * Licensed under the Apache License, Version 2.0 (the "License");
5710813b3b4078a814480bd5f5b2e0bc7958336d9Jesse Wilson * you may not use this file except in compliance with the License.
6710813b3b4078a814480bd5f5b2e0bc7958336d9Jesse Wilson * You may obtain a copy of the License at
7710813b3b4078a814480bd5f5b2e0bc7958336d9Jesse Wilson *
8710813b3b4078a814480bd5f5b2e0bc7958336d9Jesse Wilson *      http://www.apache.org/licenses/LICENSE-2.0
9710813b3b4078a814480bd5f5b2e0bc7958336d9Jesse Wilson *
10710813b3b4078a814480bd5f5b2e0bc7958336d9Jesse Wilson * Unless required by applicable law or agreed to in writing, software
11710813b3b4078a814480bd5f5b2e0bc7958336d9Jesse Wilson * distributed under the License is distributed on an "AS IS" BASIS,
12710813b3b4078a814480bd5f5b2e0bc7958336d9Jesse Wilson * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13710813b3b4078a814480bd5f5b2e0bc7958336d9Jesse Wilson * See the License for the specific language governing permissions and
14710813b3b4078a814480bd5f5b2e0bc7958336d9Jesse Wilson * limitations under the License.
15710813b3b4078a814480bd5f5b2e0bc7958336d9Jesse Wilson */
16710813b3b4078a814480bd5f5b2e0bc7958336d9Jesse Wilson
174557728efb66c455a52b7669a8eefef7a9e54854Jesse Wilsonpackage libcore.java.lang.reflect;
18710813b3b4078a814480bd5f5b2e0bc7958336d9Jesse Wilson
19710813b3b4078a814480bd5f5b2e0bc7958336d9Jesse Wilsonimport java.io.IOException;
204557728efb66c455a52b7669a8eefef7a9e54854Jesse Wilsonimport java.lang.reflect.Constructor;
214557728efb66c455a52b7669a8eefef7a9e54854Jesse Wilsonimport java.lang.reflect.Method;
224557728efb66c455a52b7669a8eefef7a9e54854Jesse Wilsonimport java.lang.reflect.Type;
234557728efb66c455a52b7669a8eefef7a9e54854Jesse Wilsonimport java.lang.reflect.TypeVariable;
24710813b3b4078a814480bd5f5b2e0bc7958336d9Jesse Wilsonimport java.util.Arrays;
25710813b3b4078a814480bd5f5b2e0bc7958336d9Jesse Wilsonimport java.util.List;
26710813b3b4078a814480bd5f5b2e0bc7958336d9Jesse Wilsonimport junit.framework.TestCase;
27710813b3b4078a814480bd5f5b2e0bc7958336d9Jesse Wilson
28710813b3b4078a814480bd5f5b2e0bc7958336d9Jesse Wilsonpublic final class GenericExceptionsTest extends TestCase {
29710813b3b4078a814480bd5f5b2e0bc7958336d9Jesse Wilson
30710813b3b4078a814480bd5f5b2e0bc7958336d9Jesse Wilson    public void testGenericExceptionsOfMethodsWithTypeParameters() throws Exception {
31710813b3b4078a814480bd5f5b2e0bc7958336d9Jesse Wilson        Method method = Thrower.class.getMethod("parameterizedMethod");
32710813b3b4078a814480bd5f5b2e0bc7958336d9Jesse Wilson        assertEquals(Arrays.<Type>asList(IOException.class),
33710813b3b4078a814480bd5f5b2e0bc7958336d9Jesse Wilson                Arrays.asList(method.getGenericExceptionTypes()));
34710813b3b4078a814480bd5f5b2e0bc7958336d9Jesse Wilson    }
35710813b3b4078a814480bd5f5b2e0bc7958336d9Jesse Wilson
36710813b3b4078a814480bd5f5b2e0bc7958336d9Jesse Wilson    public void testGenericExceptionsOfMethodsWithGenericParameters() throws Exception {
37710813b3b4078a814480bd5f5b2e0bc7958336d9Jesse Wilson        Method method = Thrower.class.getMethod("genericParameters", List.class);
38710813b3b4078a814480bd5f5b2e0bc7958336d9Jesse Wilson        assertEquals(Arrays.<Type>asList(IOException.class),
39710813b3b4078a814480bd5f5b2e0bc7958336d9Jesse Wilson                Arrays.asList(method.getGenericExceptionTypes()));
40710813b3b4078a814480bd5f5b2e0bc7958336d9Jesse Wilson    }
41710813b3b4078a814480bd5f5b2e0bc7958336d9Jesse Wilson
42710813b3b4078a814480bd5f5b2e0bc7958336d9Jesse Wilson    public void testGenericExceptionsOfConstructorsWithTypeParameters() throws Exception {
4398a7a76fe5c0dd5ff949b38da809368681169205Jesse Wilson        Constructor constructor = Thrower.class.getConstructor();
44710813b3b4078a814480bd5f5b2e0bc7958336d9Jesse Wilson        assertEquals(Arrays.<Type>asList(IOException.class),
4598a7a76fe5c0dd5ff949b38da809368681169205Jesse Wilson                Arrays.asList(constructor.getGenericExceptionTypes()));
46710813b3b4078a814480bd5f5b2e0bc7958336d9Jesse Wilson    }
47710813b3b4078a814480bd5f5b2e0bc7958336d9Jesse Wilson
48710813b3b4078a814480bd5f5b2e0bc7958336d9Jesse Wilson    public void testGenericExceptionsOfConstructorsWithGenericParameters() throws Exception {
4998a7a76fe5c0dd5ff949b38da809368681169205Jesse Wilson        Constructor constructor = Thrower.class.getConstructor(List.class);
50710813b3b4078a814480bd5f5b2e0bc7958336d9Jesse Wilson        assertEquals(Arrays.<Type>asList(IOException.class),
5198a7a76fe5c0dd5ff949b38da809368681169205Jesse Wilson                Arrays.asList(constructor.getGenericExceptionTypes()));
5298a7a76fe5c0dd5ff949b38da809368681169205Jesse Wilson    }
5398a7a76fe5c0dd5ff949b38da809368681169205Jesse Wilson
5498a7a76fe5c0dd5ff949b38da809368681169205Jesse Wilson    public void testConstructorThrowingTypeVariable() throws Exception {
5598a7a76fe5c0dd5ff949b38da809368681169205Jesse Wilson        Constructor constructor = ThrowerT.class.getConstructor();
5698a7a76fe5c0dd5ff949b38da809368681169205Jesse Wilson        TypeVariable typeVariable = getOnlyValue(constructor.getGenericExceptionTypes(),
5798a7a76fe5c0dd5ff949b38da809368681169205Jesse Wilson                TypeVariable.class);
5898a7a76fe5c0dd5ff949b38da809368681169205Jesse Wilson        assertEquals("T", typeVariable.getName());
5998a7a76fe5c0dd5ff949b38da809368681169205Jesse Wilson        assertEquals(Arrays.<Type>asList(Throwable.class), Arrays.asList(typeVariable.getBounds()));
6098a7a76fe5c0dd5ff949b38da809368681169205Jesse Wilson    }
6198a7a76fe5c0dd5ff949b38da809368681169205Jesse Wilson
6298a7a76fe5c0dd5ff949b38da809368681169205Jesse Wilson    public void testMethodThrowingTypeVariable() throws Exception {
6398a7a76fe5c0dd5ff949b38da809368681169205Jesse Wilson        Method method = ThrowerT.class.getMethod("throwsTypeVariable");
6498a7a76fe5c0dd5ff949b38da809368681169205Jesse Wilson        TypeVariable typeVariable = getOnlyValue(method.getGenericExceptionTypes(),
6598a7a76fe5c0dd5ff949b38da809368681169205Jesse Wilson                TypeVariable.class);
6698a7a76fe5c0dd5ff949b38da809368681169205Jesse Wilson        assertEquals("T", typeVariable.getName());
6798a7a76fe5c0dd5ff949b38da809368681169205Jesse Wilson        assertEquals(Arrays.<Type>asList(Throwable.class), Arrays.asList(typeVariable.getBounds()));
6898a7a76fe5c0dd5ff949b38da809368681169205Jesse Wilson    }
6998a7a76fe5c0dd5ff949b38da809368681169205Jesse Wilson
7098a7a76fe5c0dd5ff949b38da809368681169205Jesse Wilson    public void testThrowingMethodTypeParameter() throws Exception {
7198a7a76fe5c0dd5ff949b38da809368681169205Jesse Wilson        Method method = ThrowerT.class.getMethod("throwsMethodTypeParameter");
7298a7a76fe5c0dd5ff949b38da809368681169205Jesse Wilson        TypeVariable typeVariable = getOnlyValue(method.getGenericExceptionTypes(),
7398a7a76fe5c0dd5ff949b38da809368681169205Jesse Wilson                TypeVariable.class);
7498a7a76fe5c0dd5ff949b38da809368681169205Jesse Wilson        assertEquals("X", typeVariable.getName());
7598a7a76fe5c0dd5ff949b38da809368681169205Jesse Wilson        assertEquals(Arrays.<Type>asList(Exception.class), Arrays.asList(typeVariable.getBounds()));
7698a7a76fe5c0dd5ff949b38da809368681169205Jesse Wilson    }
7798a7a76fe5c0dd5ff949b38da809368681169205Jesse Wilson
7898a7a76fe5c0dd5ff949b38da809368681169205Jesse Wilson    public void testThrowingMethodThrowsEverything() throws Exception {
7998a7a76fe5c0dd5ff949b38da809368681169205Jesse Wilson        Method method = ThrowerT.class.getMethod("throwsEverything");
8098a7a76fe5c0dd5ff949b38da809368681169205Jesse Wilson        Type[] exceptions = method.getGenericExceptionTypes();
8198a7a76fe5c0dd5ff949b38da809368681169205Jesse Wilson        TypeVariable t = (TypeVariable) exceptions[0];
8298a7a76fe5c0dd5ff949b38da809368681169205Jesse Wilson        assertEquals(3, exceptions.length);
8398a7a76fe5c0dd5ff949b38da809368681169205Jesse Wilson        assertEquals("T", t.getName());
8498a7a76fe5c0dd5ff949b38da809368681169205Jesse Wilson        assertEquals(Arrays.<Type>asList(Throwable.class), Arrays.asList(t.getBounds()));
8598a7a76fe5c0dd5ff949b38da809368681169205Jesse Wilson        assertEquals(Exception.class, exceptions[1]);
8698a7a76fe5c0dd5ff949b38da809368681169205Jesse Wilson        TypeVariable x = (TypeVariable) exceptions[2];
8798a7a76fe5c0dd5ff949b38da809368681169205Jesse Wilson        assertEquals("X", x.getName());
8898a7a76fe5c0dd5ff949b38da809368681169205Jesse Wilson        assertEquals(Arrays.<Type>asList(Exception.class), Arrays.asList(x.getBounds()));
8998a7a76fe5c0dd5ff949b38da809368681169205Jesse Wilson    }
9098a7a76fe5c0dd5ff949b38da809368681169205Jesse Wilson
9198a7a76fe5c0dd5ff949b38da809368681169205Jesse Wilson    private <T> T getOnlyValue(Object[] array, Class<T> expectedType) {
9298a7a76fe5c0dd5ff949b38da809368681169205Jesse Wilson        assertEquals("Expected a " + expectedType.getName() + " but was " + Arrays.toString(array),
9398a7a76fe5c0dd5ff949b38da809368681169205Jesse Wilson                1, array.length);
9498a7a76fe5c0dd5ff949b38da809368681169205Jesse Wilson        assertTrue("Expected a " + expectedType.getName() + " but was " + array[0],
9598a7a76fe5c0dd5ff949b38da809368681169205Jesse Wilson                expectedType.isInstance(array[0]));
9698a7a76fe5c0dd5ff949b38da809368681169205Jesse Wilson        return expectedType.cast(array[0]);
97710813b3b4078a814480bd5f5b2e0bc7958336d9Jesse Wilson    }
98710813b3b4078a814480bd5f5b2e0bc7958336d9Jesse Wilson
99710813b3b4078a814480bd5f5b2e0bc7958336d9Jesse Wilson    static class Thrower {
10098a7a76fe5c0dd5ff949b38da809368681169205Jesse Wilson        public <T> Thrower() throws IOException {}
10198a7a76fe5c0dd5ff949b38da809368681169205Jesse Wilson        public Thrower(List<?> unused) throws IOException {}
102710813b3b4078a814480bd5f5b2e0bc7958336d9Jesse Wilson        public <T> void parameterizedMethod() throws IOException {}
103710813b3b4078a814480bd5f5b2e0bc7958336d9Jesse Wilson        public void genericParameters(List<?> unused) throws IOException {}
104710813b3b4078a814480bd5f5b2e0bc7958336d9Jesse Wilson    }
10598a7a76fe5c0dd5ff949b38da809368681169205Jesse Wilson
10698a7a76fe5c0dd5ff949b38da809368681169205Jesse Wilson    static class ThrowerT<T extends Throwable> {
10798a7a76fe5c0dd5ff949b38da809368681169205Jesse Wilson        public ThrowerT() throws T {}
10898a7a76fe5c0dd5ff949b38da809368681169205Jesse Wilson        public void throwsTypeVariable() throws T {}
10998a7a76fe5c0dd5ff949b38da809368681169205Jesse Wilson        public <X extends Exception> void throwsMethodTypeParameter() throws X {}
11098a7a76fe5c0dd5ff949b38da809368681169205Jesse Wilson        public <X extends Exception> void throwsEverything() throws T, Exception, X{}
11198a7a76fe5c0dd5ff949b38da809368681169205Jesse Wilson    }
112710813b3b4078a814480bd5f5b2e0bc7958336d9Jesse Wilson}
113