1 /* 2 * Copyright (C) 2010 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 libcore.java.lang.reflect; 18 19 import java.lang.reflect.Method; 20 import java.util.Arrays; 21 import java.util.Collection; 22 import java.util.Collections; 23 import java.util.HashSet; 24 import java.util.Set; 25 import junit.framework.TestCase; 26 27 public class MethodOverridesTest extends TestCase { 28 29 public void testName() throws NoSuchMethodException { 30 Method method = StringBuilder.class.getMethod("append", char.class); 31 assertEquals("append", method.getName()); 32 } 33 34 public void testParameterTypes() throws NoSuchMethodException { 35 Method method = StringBuilder.class.getMethod("append", char.class); 36 assertEquals(Arrays.<Class<?>>asList(char.class), 37 Arrays.asList(method.getParameterTypes())); 38 } 39 40 public void testDeclaringClass() throws NoSuchMethodException { 41 Method method = StringBuilder.class.getMethod("append", char.class); 42 assertEquals(StringBuilder.class, method.getDeclaringClass()); 43 } 44 45 public void testReturnType() throws NoSuchMethodException { 46 Method method = StringBuilder.class.getMethod("append", char.class); 47 assertEquals(StringBuilder.class, method.getReturnType()); 48 } 49 50 public void testThrownExceptions() throws NoSuchMethodException { 51 Method method = StringBuilder.class.getMethod("append", char.class); 52 assertEquals(Collections.<Class<?>>emptyList(), Arrays.asList(method.getExceptionTypes())); 53 } 54 55 public void testGetMethodsIncludesInheritedMethods() { 56 Set<String> signatures = signatures(Sub.class.getMethods()); 57 assertContains(signatures, "void notOverridden[] throws []"); 58 } 59 60 public void testGetDeclaredMethodsDoesNotIncludeInheritedMethods() { 61 Set<String> signatures = signatures(Sub.class.getDeclaredMethods()); 62 assertFalse(signatures.contains("void notOverridden[] throws []")); 63 } 64 65 public void testGetDeclaringClassReturnsOverridingClass() throws NoSuchMethodException { 66 assertEquals(Sub.class, Sub.class.getMethod("unchanged").getDeclaringClass()); 67 assertEquals(Sub.class, Sub.class.getDeclaredMethod("unchanged").getDeclaringClass()); 68 } 69 70 public void testGetMethodsDoesNotIncludeExceptionChanges() throws NoSuchMethodException { 71 Set<String> signatures = signatures(Sub.class.getMethods()); 72 assertContains(signatures, "void thrower[] throws []"); 73 assertFalse(signatures.contains("void thrower[] throws [java.lang.Exception]")); 74 assertEquals(Sub.class, Sub.class.getMethod("thrower").getDeclaringClass()); 75 } 76 77 public void testGetMethodsIncludesSyntheticMethods() throws NoSuchMethodException { 78 Set<String> signatures = signatures(Sub.class.getMethods()); 79 assertContains(signatures, "java.lang.String returner[] throws []"); 80 assertContains(signatures, "java.lang.Object returner[] throws []"); 81 82 Method method = Sub.class.getMethod("returner"); 83 assertEquals(Sub.class, method.getDeclaringClass()); 84 assertFalse(method.isSynthetic()); 85 } 86 87 public void testGetDeclaredMethodsIncludesSyntheticMethods() throws NoSuchMethodException { 88 Set<String> signatures = signatures(Sub.class.getDeclaredMethods()); 89 assertContains(signatures, "java.lang.String returner[] throws []"); 90 assertContains(signatures, "java.lang.Object returner[] throws []"); 91 92 Method method = Sub.class.getMethod("returner"); 93 assertEquals(Sub.class, method.getDeclaringClass()); 94 assertFalse(method.isSynthetic()); 95 } 96 97 public void testSubclassChangesVisibility() throws NoSuchMethodException { 98 Method[] methods = Sub.class.getMethods(); 99 int count = 0; 100 for (Method method : methods) { 101 if (signature(method).equals("void visibility[] throws []")) { 102 assertEquals(Sub.class, method.getDeclaringClass()); 103 assertFalse(method.isSynthetic()); 104 count++; 105 } 106 } 107 assertEquals(1, count); 108 109 Method method = Sub.class.getMethod("visibility"); 110 assertEquals(Sub.class, method.getDeclaringClass()); 111 assertFalse(method.isSynthetic()); 112 } 113 114 public void testMoreVisibleSubclassChangesVisibility() throws NoSuchMethodException { 115 Method[] methods = PublicSub.class.getMethods(); 116 int count = 0; 117 for (Method method : methods) { 118 if (signature(method).equals("void unchanged[] throws []")) { 119 assertEquals(PublicSub.class, method.getDeclaringClass()); 120 assertTrue(method.isSynthetic()); 121 count++; 122 } 123 } 124 assertEquals(1, count); 125 126 Method method = PublicSub.class.getMethod("unchanged"); 127 assertEquals(PublicSub.class, method.getDeclaringClass()); 128 assertTrue(method.isSynthetic()); 129 } 130 131 public static class Super { 132 public void notOverridden() {} 133 public void unchanged() {} 134 public void thrower() throws Exception {} 135 public Object returner() { 136 return null; 137 } 138 protected void visibility() {} 139 } 140 141 public static class Sub extends Super { 142 @Override public void unchanged() {} 143 @Override public void thrower() {} 144 @Override public String returner() { 145 return null; 146 } 147 @Override public void visibility() {} 148 } 149 150 static class PackageSuper { 151 public void unchanged() {} 152 } 153 154 public static class PublicSub extends PackageSuper {} 155 156 /** 157 * Returns a method signature of this form: 158 * {@code java.lang.String concat[class java.lang.String] throws []}. 159 */ 160 private String signature(Method method) { 161 return method.getReturnType().getName() + " " + method.getName() 162 + Arrays.toString(method.getParameterTypes()) 163 + " throws " + Arrays.toString(method.getExceptionTypes()); 164 } 165 166 private Set<String> signatures(Method[] methods) { 167 Set<String> signatures = new HashSet<String>(); 168 for (Method method : methods) { 169 signatures.add(signature(method)); 170 } 171 return signatures; 172 } 173 174 private <T> void assertContains(Collection<T> elements, T value) { 175 assertTrue("Expected " + value + " in " + elements, elements.contains(value)); 176 } 177 } 178