1/*
2 * Copyright (C) 2009 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 libcore.java.lang.reflect;
18
19import java.lang.reflect.Constructor;
20import java.lang.reflect.Parameter;
21
22import junit.framework.TestCase;
23
24public final class ConstructorTest extends TestCase {
25    public void test_getExceptionTypes() throws Exception {
26        Constructor<?> constructor = ConstructorTestHelper.class.getConstructor(new Class[0]);
27        Class[] exceptions = constructor.getExceptionTypes();
28        assertEquals(1, exceptions.length);
29        assertEquals(IndexOutOfBoundsException.class, exceptions[0]);
30        // Check that corrupting our array doesn't affect other callers.
31        exceptions[0] = NullPointerException.class;
32        exceptions = constructor.getExceptionTypes();
33        assertEquals(1, exceptions.length);
34        assertEquals(IndexOutOfBoundsException.class, exceptions[0]);
35    }
36
37    public void test_getParameterTypes() throws Exception {
38        Class[] expectedParameters = new Class[0];
39        Constructor<?> constructor = ConstructorTestHelper.class.getConstructor(expectedParameters);
40        assertEquals(0, constructor.getParameterTypes().length);
41
42        expectedParameters = new Class[] { Object.class };
43        constructor = ConstructorTestHelper.class.getConstructor(expectedParameters);
44        Class[] parameters = constructor.getParameterTypes();
45        assertEquals(1, parameters.length);
46        assertEquals(expectedParameters[0], parameters[0]);
47        // Check that corrupting our array doesn't affect other callers.
48        parameters[0] = String.class;
49        parameters = constructor.getParameterTypes();
50        assertEquals(1, parameters.length);
51        assertEquals(expectedParameters[0], parameters[0]);
52    }
53
54    public void test_getParameterCount() throws Exception {
55        Class[] expectedParameters = new Class[0];
56        Constructor<?> constructor = ConstructorTestHelper.class.getConstructor(expectedParameters);
57        assertEquals(0, constructor.getParameterCount());
58
59        expectedParameters = new Class[] { Object.class };
60        constructor = ConstructorTestHelper.class.getConstructor(expectedParameters);
61        int count = constructor.getParameterCount();
62        assertEquals(1, count);
63    }
64
65    public void test_getParameters() throws Exception {
66        Class[] expectedParameters = new Class[0];
67        Constructor<?> constructor = ConstructorTestHelper.class.getConstructor(expectedParameters);
68        assertEquals(0, constructor.getParameters().length);
69
70        expectedParameters = new Class[] { Object.class };
71        constructor = ConstructorTestHelper.class.getConstructor(expectedParameters);
72
73        // Test the information available via other Constructor methods. See ParameterTest and
74        // annotations.ParameterTest for more in-depth Parameter testing.
75        Parameter[] parameters = constructor.getParameters();
76        assertEquals(1, parameters.length);
77        assertEquals(Object.class, parameters[0].getType());
78
79        // Check that corrupting our array doesn't affect other callers.
80        parameters[0] = null;
81        parameters = constructor.getParameters();
82        assertEquals(1, parameters.length);
83        assertEquals(Object.class, parameters[0].getType());
84    }
85
86    public void testGetConstructorWithNullArgumentsArray() throws Exception {
87        Constructor<?> constructor = ConstructorTestHelper.class.getConstructor((Class[]) null);
88        assertEquals(0, constructor.getParameterTypes().length);
89    }
90
91    public void testGetConstructorWithNullArgument() throws Exception {
92        try {
93            ConstructorTestHelper.class.getConstructor(new Class[] { null });
94            fail();
95        } catch (NoSuchMethodException expected) {
96        }
97    }
98
99    public void testGetConstructorReturnsDoesNotReturnPrivateConstructor() throws Exception {
100        try {
101            ConstructorTestHelper.class.getConstructor(Object.class, Object.class);
102            fail();
103        } catch (NoSuchMethodException expected) {
104        }
105    }
106
107    public void testGetDeclaredConstructorReturnsPrivateConstructor() throws Exception {
108        Constructor<?> constructor = ConstructorTestHelper.class.getDeclaredConstructor(
109                Object.class, Object.class);
110        assertEquals(2, constructor.getParameterTypes().length);
111    }
112
113    public void testEqualConstructorEqualsAndHashCode() throws Exception {
114        Constructor<?> c1 = ConstructorTestHelper.class.getConstructor();
115        Constructor<?> c2 = ConstructorTestHelper.class.getConstructor();
116        assertEquals(c1, c2);
117        assertEquals(c1.hashCode(), c2.hashCode());
118    }
119
120    public void testHashCodeSpec() throws Exception {
121        Constructor<?> c1 = ConstructorTestHelper.class.getConstructor();
122        assertEquals(ConstructorTestHelper.class.getName().hashCode(), c1.hashCode());
123    }
124
125    public void testDifferentConstructorEqualsAndHashCode() throws Exception {
126        Constructor<?> c1 = ConstructorTestHelper.class.getConstructor();
127        Constructor<?> c2 = ConstructorTestHelper.class.getConstructor(Object.class);
128        assertFalse(c1.equals(c2));
129    }
130
131    public void testToString() throws Exception {
132        checkToString(
133                "public libcore.java.lang.reflect.ConstructorTest$ConstructorTestHelper() throws java.lang.IndexOutOfBoundsException",
134                ConstructorTestHelper.class);
135        checkToString(
136                "public libcore.java.lang.reflect.ConstructorTest$ConstructorTestHelper(java.lang.Object)",
137                ConstructorTestHelper.class, Object.class);
138        checkToString(
139                "private libcore.java.lang.reflect.ConstructorTest$ConstructorTestHelper(java.lang.Object,java.lang.Object)",
140                ConstructorTestHelper.class, Object.class, Object.class);
141        checkToString(
142                "public libcore.java.lang.reflect.ConstructorTest$GenericConstructorTestHelper() throws java.lang.Exception",
143                GenericConstructorTestHelper.class);
144        checkToString(
145                "public libcore.java.lang.reflect.ConstructorTest$GenericConstructorTestHelper(java.lang.String)",
146                GenericConstructorTestHelper.class, String.class);
147        checkToString(
148                "public libcore.java.lang.reflect.ConstructorTest$GenericConstructorTestHelper(java.lang.String,java.lang.Integer)",
149                GenericConstructorTestHelper.class, String.class, Integer.class);
150    }
151
152    private static void checkToString(String expected, Class<?> clazz, Class... constructorArgTypes)
153            throws Exception {
154        Constructor c = clazz.getDeclaredConstructor(constructorArgTypes);
155        assertEquals(expected, c.toString());
156    }
157
158    public void testToGenericString() throws Exception {
159        checkToGenericString(
160                "public libcore.java.lang.reflect.ConstructorTest$ConstructorTestHelper() throws java.lang.IndexOutOfBoundsException",
161                ConstructorTestHelper.class);
162        checkToGenericString(
163                "public libcore.java.lang.reflect.ConstructorTest$ConstructorTestHelper(java.lang.Object)",
164                ConstructorTestHelper.class, Object.class);
165        checkToGenericString(
166                "private libcore.java.lang.reflect.ConstructorTest$ConstructorTestHelper(java.lang.Object,java.lang.Object)",
167                ConstructorTestHelper.class, Object.class, Object.class);
168        checkToGenericString(
169                "public libcore.java.lang.reflect.ConstructorTest$GenericConstructorTestHelper() throws E",
170                GenericConstructorTestHelper.class);
171        checkToGenericString(
172                "public libcore.java.lang.reflect.ConstructorTest$GenericConstructorTestHelper(A)",
173                GenericConstructorTestHelper.class, String.class);
174        checkToGenericString(
175                "public <B> libcore.java.lang.reflect.ConstructorTest$GenericConstructorTestHelper(A,B)",
176                GenericConstructorTestHelper.class, String.class, Integer.class);
177    }
178
179    private static void checkToGenericString(String expected, Class<?> clazz,
180            Class... constructorArgTypes) throws Exception {
181        Constructor c = clazz.getDeclaredConstructor(constructorArgTypes);
182        assertEquals(expected, c.toGenericString());
183    }
184
185    static class ConstructorTestHelper {
186        public ConstructorTestHelper() throws IndexOutOfBoundsException { }
187        public ConstructorTestHelper(Object o) { }
188        private ConstructorTestHelper(Object a, Object b) { }
189    }
190
191    static class GenericConstructorTestHelper<A extends String, E extends Exception> {
192        public GenericConstructorTestHelper() throws E { }
193        public GenericConstructorTestHelper(A a) { }
194        public <B extends Integer> GenericConstructorTestHelper(A a, B b) { }
195    }
196}
197