Home | History | Annotate | Download | only in reflect
      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