• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
17 package android.core;
18 
19 import android.test.suitebuilder.annotation.MediumTest;
20 import android.test.suitebuilder.annotation.SmallTest;
21 import android.widget.Button;
22 import junit.framework.TestCase;
23 
24 import java.lang.reflect.Constructor;
25 import java.lang.reflect.Field;
26 import java.lang.reflect.Method;
27 import java.lang.reflect.Modifier;
28 import java.util.HashSet;
29 import java.util.Set;
30 
31 
32 class ClassWithPrivateConstructor {
ClassWithPrivateConstructor()33     private ClassWithPrivateConstructor() {
34     }
35 }
36 
37 public class ClassTest extends TestCase {
38 
39     @SmallTest
testClass()40     public void testClass() throws Exception {
41         // Now, never mind the fact that most of this stuff has to work
42         // for the test harness to get this far....
43 
44         //System.out.println("Class.forName()");
45         Class helloClass = Class.forName(ClassTest.class.getName());
46 
47         //System.out.println("Class.newInstance()");
48         Object instance = helloClass.newInstance();
49         assertNotNull(instance);
50 
51         //System.out.println("Class.forName() nonexisting class");
52         try {
53             Class.forName("this.class.DoesNotExist");
54             fail("unexpected success");
55         } catch (ClassNotFoundException ex) {
56             // expected
57         }
58 
59         //System.out.println("Class.newInstance() private constructor");
60         try {
61             Class.forName("android.core.ClassWithPrivateConstructor").newInstance();
62             fail("unexpected success");
63         } catch (IllegalAccessException ex) {
64             // this is expected
65         }
66 
67         //System.out.println("Class.getDeclaredMethod()");
68 
69         Method method = helloClass.getDeclaredMethod("method", (Class[]) null);
70 
71         method.invoke(new ClassTest(), (Object[]) null);
72 
73         //System.out.println("Class.getDeclaredMethod() w/ args");
74 
75         method = helloClass.getDeclaredMethod("methodWithArgs", Object.class);
76 
77         Object invokeArgs[] = new Object[1];
78         invokeArgs[0] = "Hello";
79         Object ret = method.invoke(new ClassTest(), invokeArgs);
80         assertEquals(ret, invokeArgs[0]);
81 
82         //System.out.println("Class.getDeclaredMethod() -- private");
83 
84         method = helloClass.getDeclaredMethod("privateMethod", (Class[]) null);
85 
86         method.invoke(new ClassTest(), (Object[]) null);
87         //fail("unexpected success");
88         // TODO: I think this actually *should* succeed, because the
89         // call to the private method is being made from the same class.
90         // This needs to be replaced with a private call to a different
91         // class.
92 
93         //System.out.println("Class.getSuperclass");
94         Class objectClass = Class.forName("java.lang.Object");
95         assertEquals(helloClass.getSuperclass().getSuperclass().getSuperclass(), objectClass);
96 
97         //System.out.println("Class.isAssignableFrom");
98         assertTrue(objectClass.isAssignableFrom(helloClass));
99         assertFalse(helloClass.isAssignableFrom(objectClass));
100 
101         //System.out.println("Class.getConstructor");
102 
103         Constructor constructor = helloClass.getConstructor((Class[]) null);
104         assertNotNull(constructor);
105 
106         //System.out.println("Class.getModifiers");
107 
108         assertTrue(Modifier.isPublic(helloClass.getModifiers()));
109         //System.out.println("Modifiers: " + Modifier.toString(helloClass.getModifiers()));
110 
111         //System.out.println("Class.getMethod");
112 
113         helloClass.getMethod("method", (Class[]) null);
114 
115         try {
116             Class[] argTypes = new Class[1];
117             argTypes[0] = helloClass;
118             helloClass.getMethod("method", argTypes);
119             fail("unexpected success");
120         } catch (NoSuchMethodException ex) {
121             // exception expected
122         }
123 
124         // Test for public tracker issue 14
125         SimpleClass obj = new SimpleClass();
126         Field field = obj.getClass().getDeclaredField("str");
127         field.set(obj, null);
128     }
129 
130     public class SimpleClass {
131         public String str;
132     }
133 
methodWithArgs(Object o)134     public Object methodWithArgs(Object o) {
135         return o;
136     }
137 
138     boolean methodInvoked;
139 
method()140     public void method() {
141         methodInvoked = true;
142     }
143 
144     boolean privateMethodInvoked;
145 
privateMethod()146     public void privateMethod() {
147         privateMethodInvoked = true;
148     }
149 
150     // Regression for 1018067: Class.getMethods() returns the same method over
151     // and over again from all base classes
152     @MediumTest
testClassGetMethodsNoDupes()153     public void testClassGetMethodsNoDupes() {
154         Method[] methods = Button.class.getMethods();
155         Set<String> set = new HashSet<String>();
156 
157         for (int i = 0; i < methods.length; i++) {
158             String signature = methods[i].toString();
159 
160             int par = signature.indexOf('(');
161             int dot = signature.lastIndexOf('.', par);
162 
163             signature = signature.substring(dot + 1);
164 
165             assertFalse("Duplicate " + signature, set.contains(signature));
166             set.add(signature);
167         }
168     }
169 
170     interface MyInterface {
foo()171         void foo();
172     }
173 
174     interface MyOtherInterface extends MyInterface {
bar()175         void bar();
176     }
177 
178     abstract class MyClass implements MyOtherInterface {
gabba()179         public void gabba() {
180         }
181 
hey()182         public void hey() {
183         }
184     }
185 
186     // Check if we also reflect methods from interfaces
187     @SmallTest
testGetMethodsInterfaces()188     public void testGetMethodsInterfaces() {
189         Method[] methods = MyInterface.class.getMethods();
190         assertTrue("Interface method must be there", hasMethod(methods, ".foo("));
191 
192         methods = MyOtherInterface.class.getMethods();
193         assertTrue("Interface method must be there", hasMethod(methods, ".foo("));
194         assertTrue("Interface method must be there", hasMethod(methods, ".bar("));
195 
196         methods = MyClass.class.getMethods();
197         assertTrue("Interface method must be there", hasMethod(methods, ".foo("));
198         assertTrue("Interface method must be there", hasMethod(methods, ".bar("));
199 
200         assertTrue("Declared method must be there", hasMethod(methods, ".gabba("));
201         assertTrue("Declared method must be there", hasMethod(methods, ".hey("));
202 
203         assertTrue("Inherited method must be there", hasMethod(methods, ".toString("));
204     }
205 
hasMethod(Method[] methods, String signature)206     private boolean hasMethod(Method[] methods, String signature) {
207         for (int i = 0; i < methods.length; i++) {
208             if (methods[i].toString().contains(signature)) {
209                 return true;
210             }
211         }
212 
213         return false;
214     }
215 
216     // Test for Class.getPackage();
217     @SmallTest
testClassGetPackage()218     public void testClassGetPackage() {
219         assertNotNull("Package must be non-null", getClass().getPackage());
220         assertEquals("Package must have expected name", "android.core", getClass().getPackage().getName());
221         assertEquals("Package must have expected title", "Unknown", getClass().getPackage().getSpecificationTitle());
222 
223         Package p = java.lang.Object.class.getPackage();
224         assertNotNull("Package must be non-null", p);
225         assertEquals("Package must have expected name", "java.lang", p.getName());
226         assertSame("Package object must be same for each call", p, java.lang.Object.class.getPackage());
227     }
228 
229     // Regression test for #1123708: Problem with getCanonicalName(),
230     // getSimpleName(), and getPackage().
231     //
232     // A couple of interesting cases need to be checked: Top-level classes,
233     // member classes, local classes, and anonymous classes. Also, boundary
234     // cases with '$' in the class names are checked, since the '$' is used
235     // as the separator between outer and inner class, so this might lead
236     // to problems (it did in the previous implementation).
237     //
238     // Caution: Adding local or anonymous classes elsewhere in this
239     // file might affect the test.
240     private class MemberClass {
241         // This space intentionally left blank.
242     }
243 
244     private class Mi$o$oup {
245         // This space intentionally left blank.
246     }
247 
248     @SmallTest
testVariousClassNames()249     public void testVariousClassNames() {
250         Class<?> clazz = this.getClass();
251         String pkg = (clazz.getPackage() == null ? "" : clazz.getPackage().getName() + ".");
252 
253         // Simple, top-level class
254 
255         assertEquals("Top-level class name must be correct", pkg + "ClassTest", clazz.getName());
256         assertEquals("Top-level class simple name must be correct", "ClassTest", clazz.getSimpleName());
257         assertEquals("Top-level class canonical name must be correct", pkg + "ClassTest", clazz.getCanonicalName());
258 
259         clazz = MemberClass.class;
260 
261         assertEquals("Member class name must be correct", pkg + "ClassTest$MemberClass", clazz.getName());
262         assertEquals("Member class simple name must be correct", "MemberClass", clazz.getSimpleName());
263         assertEquals("Member class canonical name must be correct", pkg + "ClassTest.MemberClass", clazz.getCanonicalName());
264 
265         class LocalClass {
266             // This space intentionally left blank.
267         }
268 
269         clazz = LocalClass.class;
270 
271         assertEquals("Local class name must be correct", pkg + "ClassTest$1LocalClass", clazz.getName());
272         assertEquals("Local class simple name must be correct", "LocalClass", clazz.getSimpleName());
273         assertNull("Local class canonical name must be null", clazz.getCanonicalName());
274 
275         clazz = new Object() { }.getClass();
276 
277         assertEquals("Anonymous class name must be correct", pkg + "ClassTest$1", clazz.getName());
278         assertEquals("Anonymous class simple name must be empty", "", clazz.getSimpleName());
279         assertNull("Anonymous class canonical name must be null", clazz.getCanonicalName());
280 
281         // Weird special cases with dollar in name.
282 
283         clazz = Mou$$aka.class;
284 
285         assertEquals("Top-level class name must be correct", pkg + "Mou$$aka", clazz.getName());
286         assertEquals("Top-level class simple name must be correct", "Mou$$aka", clazz.getSimpleName());
287         assertEquals("Top-level class canonical name must be correct", pkg + "Mou$$aka", clazz.getCanonicalName());
288 
289         clazz = Mi$o$oup.class;
290 
291         assertEquals("Member class name must be correct", pkg + "ClassTest$Mi$o$oup", clazz.getName());
292         assertEquals("Member class simple name must be correct", "Mi$o$oup", clazz.getSimpleName());
293         assertEquals("Member class canonical name must be correct", pkg + "ClassTest.Mi$o$oup", clazz.getCanonicalName());
294 
295         class Ma$hedPotatoe$ {
296             // This space intentionally left blank.
297         }
298 
299         clazz = Ma$hedPotatoe$.class;
300 
301         assertEquals("Member class name must be correct", pkg + "ClassTest$1Ma$hedPotatoe$", clazz.getName());
302         assertEquals("Member class simple name must be correct", "Ma$hedPotatoe$", clazz.getSimpleName());
303         assertNull("Member class canonical name must be null", clazz.getCanonicalName());
304     }
305 
306     @SmallTest
testLocalMemberClass()307     public void testLocalMemberClass() {
308         Class<?> clazz = this.getClass();
309 
310         assertFalse("Class must not be member", clazz.isMemberClass());
311         assertFalse("Class must not be local", clazz.isLocalClass());
312 
313         clazz = MemberClass.class;
314 
315         assertTrue("Class must be member", clazz.isMemberClass());
316         assertFalse("Class must not be local", clazz.isLocalClass());
317 
318         class OtherLocalClass {
319             // This space intentionally left blank.
320         }
321 
322         clazz = OtherLocalClass.class;
323 
324         assertFalse("Class must not be member", clazz.isMemberClass());
325         assertTrue("Class must be local", clazz.isLocalClass());
326 
327         clazz = new Object() { }.getClass();
328 
329         assertFalse("Class must not be member", clazz.isMemberClass());
330         assertFalse("Class must not be local", clazz.isLocalClass());
331     }
332 
333 }
334 
335 class Mou$$aka {
336     // This space intentionally left blank.
337 }
338