1 /*
2  *  Licensed to the Apache Software Foundation (ASF) under one or more
3  *  contributor license agreements.  See the NOTICE file distributed with
4  *  this work for additional information regarding copyright ownership.
5  *  The ASF licenses this file to You under the Apache License, Version 2.0
6  *  (the "License"); you may not use this file except in compliance with
7  *  the License.  You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  */
17 
18 package org.apache.harmony.tests.java.lang.reflect;
19 
20 import java.lang.annotation.Annotation;
21 import java.lang.annotation.ElementType;
22 import java.lang.annotation.Retention;
23 import java.lang.annotation.RetentionPolicy;
24 import java.lang.annotation.Target;
25 import java.lang.reflect.Constructor;
26 import java.lang.reflect.Modifier;
27 import java.lang.reflect.Type;
28 import java.lang.reflect.TypeVariable;
29 import java.util.HashSet;
30 import java.util.Set;
31 
32 public class ConstructorTest extends junit.framework.TestCase {
33 
34 
35     @Retention(RetentionPolicy.RUNTIME)
36     @Target( {ElementType.CONSTRUCTOR, ElementType.PARAMETER})
37     static @interface ConstructorTestAnnotationRuntime0 {
38     }
39 
40     @Retention(RetentionPolicy.RUNTIME)
41     @Target( {ElementType.CONSTRUCTOR, ElementType.PARAMETER})
42     static @interface ConstructorTestAnnotationRuntime1 {
43     }
44 
45     @Retention(RetentionPolicy.CLASS)
46     @Target( {ElementType.CONSTRUCTOR, ElementType.PARAMETER})
47     static @interface ConstructorTestAnnotationClass0 {
48     }
49 
50     @Retention(RetentionPolicy.SOURCE)
51     @Target( {ElementType.CONSTRUCTOR, ElementType.PARAMETER})
52     static @interface ConstructorTestAnnotationSource0 {
53     }
54 
55     static class ConstructorTestHelper extends Object {
56         int cval;
57 
58         @ConstructorTestAnnotationRuntime0
59         @ConstructorTestAnnotationRuntime1
60         @ConstructorTestAnnotationClass0
61         @ConstructorTestAnnotationSource0
ConstructorTestHelper()62         public ConstructorTestHelper() throws IndexOutOfBoundsException {
63             cval = 99;
64         }
65 
ConstructorTestHelper( @onstructorTestAnnotationRuntime0 @onstructorTestAnnotationRuntime1 @onstructorTestAnnotationClass0 @onstructorTestAnnotationSource0 Object x)66         public ConstructorTestHelper(
67                 @ConstructorTestAnnotationRuntime0
68                 @ConstructorTestAnnotationRuntime1
69                 @ConstructorTestAnnotationClass0
70                 @ConstructorTestAnnotationSource0 Object x) {
71         }
72 
ConstructorTestHelper(String... x)73         public ConstructorTestHelper(String... x) {
74         }
75 
ConstructorTestHelper(int a)76         private ConstructorTestHelper(int a) {
77         }
78 
ConstructorTestHelper(long a)79         protected ConstructorTestHelper(long a) {
80         }
81 
check()82         public int check() {
83             return cval;
84         }
85     }
86 
87     static class GenericConstructorTestHelper<T, S extends T, E extends Exception> {
GenericConstructorTestHelper(T t, S s)88         public GenericConstructorTestHelper(T t, S s) {}
GenericConstructorTestHelper()89         public GenericConstructorTestHelper() throws E{}
90     }
91 
92     static class NoPublicConstructorTestHelper {
93         // This class has no public constructor.
94     }
95 
96 //    Used to test synthetic constructor.
97 //
98 //    static class Outer {
99 //        private Outer(){}
100 //        class Inner {
101 //            {new Outer();}
102 //        }
103 //    }
104 
test_getParameterAnnotations()105     public void test_getParameterAnnotations() throws Exception {
106         Constructor<ConstructorTestHelper> ctor1 = ConstructorTestHelper.class
107                 .getConstructor(Object.class);
108         Annotation[][] paramAnnotations = ctor1.getParameterAnnotations();
109         assertEquals("Annotations for wrong number of parameters returned", 1,
110                 paramAnnotations.length);
111         assertEquals("Wrong number of annotations returned", 2,
112                 paramAnnotations[0].length);
113 
114         Set<Class<?>> ignoreOrder = new HashSet<Class<?>>();
115         ignoreOrder.add(paramAnnotations[0][0].annotationType());
116         ignoreOrder.add(paramAnnotations[0][1].annotationType());
117 
118         assertTrue("Missing ConstructorTestAnnotationRuntime0", ignoreOrder
119                 .contains(ConstructorTestAnnotationRuntime0.class));
120         assertTrue("Missing ConstructorTestAnnotationRuntime1", ignoreOrder
121                 .contains(ConstructorTestAnnotationRuntime1.class));
122     }
123 
124 
test_getDeclaredAnnotations()125     public void test_getDeclaredAnnotations() throws Exception {
126         Constructor<ConstructorTestHelper> ctor1 = null;
127         ctor1 = ConstructorTestHelper.class.getConstructor(new Class[0]);
128         Annotation[] annotations = ctor1.getDeclaredAnnotations();
129         assertEquals("Wrong number of annotations returned", 2,
130                 annotations.length);
131         Set<Class<?>> ignoreOrder = new HashSet<Class<?>>();
132         ignoreOrder.add(annotations[0].annotationType());
133         ignoreOrder.add(annotations[1].annotationType());
134 
135         assertTrue("Missing ConstructorTestAnnotationRuntime0", ignoreOrder
136                 .contains(ConstructorTestAnnotationRuntime0.class));
137         assertTrue("Missing ConstructorTestAnnotationRuntime1", ignoreOrder
138                 .contains(ConstructorTestAnnotationRuntime1.class));
139     }
140 
test_isVarArgs()141     public void test_isVarArgs() throws Exception {
142         Constructor<ConstructorTestHelper> varArgCtor = ConstructorTestHelper.class
143                 .getConstructor(String[].class);
144         assertTrue("Vararg constructor not recognized", varArgCtor.isVarArgs());
145 
146         Constructor<ConstructorTestHelper> nonVarArgCtor = ConstructorTestHelper.class
147                 .getConstructor(Object.class);
148         assertFalse("Non vararg constructor recognized as vararg constructor",
149                 nonVarArgCtor.isVarArgs());
150     }
151 
test_hashCode()152     public void test_hashCode() throws Exception {
153         Constructor<ConstructorTestHelper> constructor = ConstructorTestHelper.class
154                 .getConstructor();
155         assertEquals(
156                 "The constructor's hashCode is not equal to the hashCode of the name of the declaring class",
157                 ConstructorTestHelper.class.getName().hashCode(), constructor
158                         .hashCode());
159     }
160 
161     @SuppressWarnings("unchecked")
test_toGenericString()162     public void test_toGenericString() throws Exception {
163         Constructor<GenericConstructorTestHelper> genericCtor = GenericConstructorTestHelper.class
164                 .getConstructor(Object.class, Object.class);
165         assertEquals(
166                 "Wrong generic string returned",
167                 "public org.apache.harmony.tests.java.lang.reflect.ConstructorTest$GenericConstructorTestHelper(T,S)",
168                 genericCtor.toGenericString());
169         Constructor<GenericConstructorTestHelper> ctor = GenericConstructorTestHelper.class
170                 .getConstructor();
171         assertEquals(
172                 "Wrong generic string returned",
173                 "public org.apache.harmony.tests.java.lang.reflect.ConstructorTest$GenericConstructorTestHelper() throws E",
174                 ctor.toGenericString());
175     }
176 
test_equalsLjava_lang_Object()177     public void test_equalsLjava_lang_Object() {
178         Constructor<ConstructorTestHelper> ctor1 = null, ctor2 = null;
179         try {
180             ctor1 = ConstructorTestHelper.class.getConstructor(
181                     new Class[0]);
182             ctor2 = ConstructorTestHelper.class.getConstructor(Object.class);
183         } catch (Exception e) {
184             fail("Exception during equals test : " + e.getMessage());
185         }
186         assertTrue("Different Contructors returned equal", !ctor1.equals(ctor2));
187     }
188 
test_getDeclaringClass()189     public void test_getDeclaringClass() {
190         boolean val = false;
191         try {
192             Class<? extends ConstructorTestHelper> pclass = new ConstructorTestHelper().getClass();
193             Constructor<? extends ConstructorTestHelper> ctor = pclass.getConstructor(new Class[0]);
194             val = ctor.getDeclaringClass().equals(pclass);
195         } catch (Exception e) {
196             fail("Exception during test : " + e.getMessage());
197         }
198         assertTrue("Returned incorrect declaring class", val);
199     }
200 
test_getExceptionTypes()201     public void test_getExceptionTypes() {
202         // Test for method java.lang.Class []
203         // java.lang.reflect.Constructor.getExceptionTypes()
204         Class[] exceptions = null;
205         Class<? extends IndexOutOfBoundsException> ex = null;
206         try {
207             Constructor<? extends ConstructorTestHelper> ctor = new ConstructorTestHelper().getClass()
208                     .getConstructor(new Class[0]);
209             exceptions = ctor.getExceptionTypes();
210             ex = new IndexOutOfBoundsException().getClass();
211         } catch (Exception e) {
212             fail("Exception during test : " + e.getMessage());
213         }
214         assertEquals("Returned exception list of incorrect length",
215                 1, exceptions.length);
216         assertTrue("Returned incorrect exception", exceptions[0].equals(ex));
217     }
218 
test_getModifiers()219     public void test_getModifiers() {
220         // Test for method int java.lang.reflect.Constructor.getModifiers()
221         int mod = 0;
222         try {
223             Constructor<? extends ConstructorTestHelper> ctor = new ConstructorTestHelper().getClass()
224                     .getConstructor(new Class[0]);
225             mod = ctor.getModifiers();
226             assertTrue("Returned incorrect modifers for public ctor",
227                     ((mod & Modifier.PUBLIC) == Modifier.PUBLIC)
228                             && ((mod & Modifier.PRIVATE) == 0));
229         } catch (NoSuchMethodException e) {
230             fail("Exception during test : " + e.getMessage());
231         }
232         try {
233             Class[] cl = { int.class };
234             Constructor<? extends ConstructorTestHelper> ctor = new ConstructorTestHelper().getClass()
235                     .getDeclaredConstructor(cl);
236             mod = ctor.getModifiers();
237             assertTrue("Returned incorrect modifers for private ctor",
238                     ((mod & Modifier.PRIVATE) == Modifier.PRIVATE)
239                             && ((mod & Modifier.PUBLIC) == 0));
240         } catch (NoSuchMethodException e) {
241             fail("Exception during test : " + e.getMessage());
242         }
243         try {
244             Class[] cl = { long.class };
245             Constructor<? extends ConstructorTestHelper> ctor = new ConstructorTestHelper().getClass()
246                     .getDeclaredConstructor(cl);
247             mod = ctor.getModifiers();
248             assertTrue("Returned incorrect modifers for private ctor",
249                     ((mod & Modifier.PROTECTED) == Modifier.PROTECTED)
250                             && ((mod & Modifier.PUBLIC) == 0));
251         } catch (NoSuchMethodException e) {
252             fail("NoSuchMethodException during test : " + e.getMessage());
253         }
254     }
255 
test_getName()256     public void test_getName() {
257         // Test for method java.lang.String
258         // java.lang.reflect.Constructor.getName()
259         try {
260             Constructor<? extends ConstructorTestHelper> ctor = new ConstructorTestHelper().getClass()
261                     .getConstructor(new Class[0]);
262             assertTrue(
263                     "Returned incorrect name: " + ctor.getName(),
264                     ctor
265                             .getName()
266                             .equals(
267                                     "org.apache.harmony.tests.java.lang.reflect.ConstructorTest$ConstructorTestHelper"));
268         } catch (Exception e) {
269             fail("Exception obtaining contructor : " + e.getMessage());
270         }
271     }
272 
test_getParameterTypes()273     public void test_getParameterTypes() {
274         // Test for method java.lang.Class []
275         // java.lang.reflect.Constructor.getParameterTypes()
276         Class[] types = null;
277         try {
278             Constructor<? extends ConstructorTestHelper> ctor = new ConstructorTestHelper().getClass()
279                     .getConstructor(new Class[0]);
280             types = ctor.getParameterTypes();
281         } catch (Exception e) {
282             fail("Exception during getParameterTypes test:"
283                     + e.toString());
284         }
285         assertEquals("Incorrect parameter returned", 0, types.length);
286 
287         Class[] parms = null;
288         try {
289             parms = new Class[1];
290             parms[0] = new Object().getClass();
291             Constructor<? extends ConstructorTestHelper> ctor = new ConstructorTestHelper().getClass()
292                     .getConstructor(parms);
293             types = ctor.getParameterTypes();
294         } catch (Exception e) {
295             fail("Exception during getParameterTypes test:"
296                     + e.toString());
297         }
298         assertTrue("Incorrect parameter returned", types[0].equals(parms[0]));
299     }
300 
301     @SuppressWarnings("unchecked")
test_getGenericParameterTypes()302     public void test_getGenericParameterTypes() {
303         Type[] types = null;
304         try {
305             Constructor<? extends ConstructorTestHelper> ctor = new ConstructorTestHelper()
306                     .getClass().getConstructor(new Class[0]);
307             types = ctor.getGenericParameterTypes();
308         } catch (Exception e) {
309             fail("Exception during getParameterTypes test:" + e.toString());
310         }
311         assertEquals("Incorrect parameter returned", 0, types.length);
312 
313         Class<?>[] parms = null;
314         try {
315             parms = new Class[] {Object.class};
316             Constructor<? extends ConstructorTestHelper> ctor = new ConstructorTestHelper()
317                     .getClass().getConstructor(parms);
318             types = ctor.getGenericParameterTypes();
319         } catch (Exception e) {
320             fail("Exception during getParameterTypes test:" + e.toString());
321         }
322         assertTrue("Incorrect parameter returned", types[0].equals(parms[0]));
323 
324 
325         try {
326             Constructor<GenericConstructorTestHelper> constructor = GenericConstructorTestHelper.class
327                     .getConstructor(Object.class, Object.class);
328             types = constructor.getGenericParameterTypes();
329         } catch (Exception e) {
330             fail("Exception during getParameterTypes test:" + e.toString());
331         }
332 
333         assertEquals("Wrong number of parameter types returned", 2,
334                 types.length);
335 
336         assertEquals("Wrong number of parameter types returned", "T",
337                 ((TypeVariable)types[0]).getName());
338         assertEquals("Wrong number of parameter types returned", "S",
339                 ((TypeVariable)types[1]).getName());
340     }
341 
342     @SuppressWarnings("unchecked")
test_getGenericExceptionTypes()343     public void test_getGenericExceptionTypes() {
344         Type[] types = null;
345 
346         try {
347             Constructor<? extends ConstructorTestHelper> ctor = new ConstructorTestHelper()
348                     .getClass().getConstructor(new Class[0]);
349             types = ctor.getGenericExceptionTypes();
350         } catch (Exception e) {
351             fail("Exception during getGenericExceptionTypes test:" + e.toString());
352         }
353         assertEquals("Wrong number of exception types returned", 1, types.length);
354 
355 
356         try {
357             Constructor<GenericConstructorTestHelper> constructor = GenericConstructorTestHelper.class
358                     .getConstructor();
359             types = constructor.getGenericExceptionTypes();
360         } catch (Exception e) {
361             fail("Exception during getGenericExceptionTypes test:"
362                     + e.toString());
363         }
364 
365         assertEquals("Wrong number of exception types returned", 1,
366                 types.length);
367 
368         assertEquals("Wrong exception name returned.", "E",
369                 ((TypeVariable)types[0]).getName());
370 
371     }
372 
373 
test_newInstance$Ljava_lang_Object()374     public void test_newInstance$Ljava_lang_Object() {
375         // Test for method java.lang.Object
376         // java.lang.reflect.Constructor.newInstance(java.lang.Object [])
377 
378         ConstructorTestHelper test = null;
379         try {
380             Constructor<? extends ConstructorTestHelper> ctor = new ConstructorTestHelper().getClass()
381                     .getConstructor(new Class[0]);
382             test = ctor.newInstance((Object[])null);
383         } catch (Exception e) {
384             fail("Failed to create instance : " + e.getMessage());
385         }
386         assertEquals("improper instance created", 99, test.check());
387     }
388 
test_toString()389     public void test_toString() {
390         // Test for method java.lang.String
391         // java.lang.reflect.Constructor.toString()
392         Class[] parms = null;
393         Constructor<? extends ConstructorTestHelper> ctor = null;
394         try {
395             parms = new Class[1];
396             parms[0] = new Object().getClass();
397             ctor = new ConstructorTestHelper().getClass().getConstructor(parms);
398         } catch (Exception e) {
399             fail("Exception during getParameterTypes test:"
400                     + e.toString());
401         }
402         assertTrue(
403                 "Returned incorrect string representation: " + ctor.toString(),
404                 ctor
405                         .toString()
406                         .equals(
407                                 "public org.apache.harmony.tests.java.lang.reflect.ConstructorTest$ConstructorTestHelper(java.lang.Object)"));
408     }
409 
test_getConstructor()410     public void test_getConstructor() throws Exception {
411         // Passing new Class[0] should be equivalent to (Class[]) null.
412         Class<ConstructorTestHelper> c2 = ConstructorTestHelper.class;
413         assertEquals(c2.getConstructor(new Class[0]), c2.getConstructor((Class[]) null));
414         assertEquals(c2.getDeclaredConstructor(new Class[0]),
415                      c2.getDeclaredConstructor((Class[]) null));
416 
417         // We can get a non-public constructor via getDeclaredConstructor...
418         Class<NoPublicConstructorTestHelper> c1 = NoPublicConstructorTestHelper.class;
419         c1.getDeclaredConstructor((Class[]) null);
420         // ...but not with getConstructor (which only returns public constructors).
421         try {
422             c1.getConstructor((Class[]) null);
423             fail("Should throw NoSuchMethodException");
424         } catch (NoSuchMethodException ex) {
425             // Expected.
426         }
427     }
428 
429     /**
430      * Sets up the fixture, for example, open a network connection. This method
431      * is called before a test is executed.
432      */
setUp()433     protected void setUp() {
434     }
435 
436     /**
437      * Tears down the fixture, for example, close a network connection. This
438      * method is called after a test is executed.
439      */
tearDown()440     protected void tearDown() {
441     }
442 }
443