rt/emul/compacttest/src/test/java/org/apidesign/bck2brwsr/tck/ReflectionTest.java
author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
Sun, 20 Mar 2016 09:25:47 +0100
changeset 1900 7865a00c30ef
parent 1838 493d5960d520
child 1902 c3dee54ecc15
permissions -rw-r--r--
Let Class.getDeclaredMethods filter out methods from Class.getMethods
     1 /**
     2  * Back 2 Browser Bytecode Translator
     3  * Copyright (C) 2012-2015 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
     4  *
     5  * This program is free software: you can redistribute it and/or modify
     6  * it under the terms of the GNU General Public License as published by
     7  * the Free Software Foundation, version 2 of the License.
     8  *
     9  * This program is distributed in the hope that it will be useful,
    10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    12  * GNU General Public License for more details.
    13  *
    14  * You should have received a copy of the GNU General Public License
    15  * along with this program. Look for COPYING file in the top folder.
    16  * If not, see http://opensource.org/licenses/GPL-2.0.
    17  */
    18 package org.apidesign.bck2brwsr.tck;
    19 
    20 import java.lang.annotation.Retention;
    21 import java.lang.annotation.RetentionPolicy;
    22 import java.lang.reflect.Constructor;
    23 import java.lang.reflect.Method;
    24 import java.lang.reflect.Proxy;
    25 import java.util.Arrays;
    26 import java.util.Collections;
    27 import java.util.List;
    28 import org.apidesign.bck2brwsr.core.JavaScriptBody;
    29 import org.apidesign.bck2brwsr.vmtest.Compare;
    30 import org.apidesign.bck2brwsr.vmtest.VMTest;
    31 import org.testng.annotations.Factory;
    32 
    33 /**
    34  *
    35  * @author Jaroslav Tulach <jtulach@netbeans.org>
    36  */
    37 public class ReflectionTest {
    38     @Compare public boolean nonNullThis() {
    39         return this == null;
    40     }
    41     
    42     @Compare public String intType() {
    43         return Integer.TYPE.toString();
    44     }
    45 
    46     @Compare public String voidType() throws Exception {
    47         return void.class.toString();
    48     }
    49 
    50     @Compare public String longClass() {
    51         return long.class.toString();
    52     }
    53     
    54     @Compare public boolean isRunnableInterface() {
    55         return Runnable.class.isInterface();
    56     }
    57 
    58     @Compare public boolean isAssignableToPrimitiveType() {
    59         return boolean.class.isAssignableFrom(Runnable.class);
    60     }
    61 
    62     @Compare public boolean isAssignableFromPrimitiveType() {
    63         return Runnable.class.isAssignableFrom(boolean.class);
    64     }
    65 
    66     @Compare public boolean isAssignableLongFromInt() {
    67         return long.class.isAssignableFrom(int.class);
    68     }
    69 
    70     @Compare public boolean isAssignableIntFromLong() {
    71         return int.class.isAssignableFrom(long.class);
    72     }
    73 
    74     @Compare public String isRunnableHasRunMethod() throws NoSuchMethodException {
    75         return Runnable.class.getMethod("run").getName();
    76     }
    77 
    78     @Compare public String isRunnableDeclaresRunMethod() throws NoSuchMethodException {
    79         return Runnable.class.getDeclaredMethod("run").getName();
    80     }
    81     
    82     @Compare public String intValue() throws Exception {
    83         return Integer.class.getConstructor(int.class).newInstance(10).toString();
    84     }
    85     
    86     @Compare public String getMethodWithArray() throws Exception {
    87         return Proxy.class.getMethod("getProxyClass", ClassLoader.class, Class[].class).getName();
    88     }
    89     
    90     @Compare public String namesOfMethods() {
    91         StringBuilder sb = new StringBuilder();
    92         String[] arr = new String[20];
    93         int i = 0;
    94         for (Method m : StaticUse.class.getMethods()) {
    95             arr[i++] = m.getName();
    96         }
    97         for (String s : sort(arr, i)) {
    98             sb.append(s).append("\n");
    99         }
   100         return sb.toString();
   101     }
   102 
   103     @Compare
   104     public String namesOfDeclaredMethods() {
   105         StringBuilder sb = new StringBuilder();
   106         String[] arr = new String[20];
   107         Method[] methods = StaticUse.class.getDeclaredMethods();
   108         if (methods.length != 2) {
   109             throw new IllegalStateException("Expecting just two methods, was: " + methods.length);
   110         }
   111         int i = 0;
   112         for (Method m : methods) {
   113             arr[i++] = m.getName();
   114         }
   115         for (String s : sort(arr, i)) {
   116             sb.append(s).append("\n");
   117         }
   118         return sb.toString();
   119     }
   120 
   121     @Compare public String paramsOfConstructors() {
   122         StringBuilder sb = new StringBuilder();
   123         String[] arr = new String[20];
   124         int i = 0;
   125         for (Constructor<?> m : StaticUse.class.getConstructors()) {
   126             arr[i++] = m.getName();
   127         }
   128         for (String s : sort(arr, i)) {
   129             sb.append(s).append("\n");
   130         }
   131         return sb.toString();
   132     }
   133 
   134     @Compare public String namesOfDeclaringClassesOfMethods() {
   135         StringBuilder sb = new StringBuilder();
   136         String[] arr = new String[20];
   137         int i = 0;
   138         for (Method m : StaticUse.class.getMethods()) {
   139             arr[i++] = m.getName() + "@" + m.getDeclaringClass().getName();
   140         }
   141         for (String s : sort(arr, i)) {
   142             sb.append(s).append("\n");
   143         }
   144         return sb.toString();
   145     }
   146     
   147     @Compare public String cannotCallNonStaticMethodWithNull() throws Exception {
   148         StaticUse.class.getMethod("instanceMethod").invoke(null);
   149         return "should not happen";
   150     }
   151     
   152     @Compare public String classCastException() {
   153         try {
   154             Integer i = (Integer)StaticUseSub.getNonNull();
   155             return "" + i.intValue();
   156         } catch (ClassCastException ex) {
   157             return ex.getClass().getName();
   158         }
   159     }
   160 
   161     @Compare public String methodThatThrowsException() throws Exception {
   162         StaticUse.class.getMethod("instanceMethod").invoke(new StaticUse());
   163         return "should not happen";
   164     }
   165 
   166     @Compare public Object voidReturnType() throws Exception {
   167         return StaticUse.class.getMethod("instanceMethod").getReturnType();
   168     }
   169     
   170     @Retention(RetentionPolicy.RUNTIME)
   171     @interface Ann {
   172     }
   173     
   174     @Compare public String annoClass() throws Exception {
   175         Retention r = Ann.class.getAnnotation(Retention.class);
   176         assert r != null : "Annotation is present";
   177         assert r.value() == RetentionPolicy.RUNTIME : "Policy value is OK: " + r.value();
   178         return r.annotationType().getName();
   179     }
   180     
   181     @Compare public boolean isAnnotation() {
   182         return Ann.class.isAnnotation();
   183     }
   184     @Compare public boolean isNotAnnotation() {
   185         return String.class.isAnnotation();
   186     }
   187     @Compare public boolean isNotAnnotationEnum() {
   188         return E.class.isAnnotation();
   189     }
   190     enum E { A, B };
   191     @Compare public boolean isEnum() {
   192         return E.A.getClass().isEnum();
   193     }
   194 
   195     @Compare public boolean isNotEnum() {
   196         return "".getClass().isEnum();
   197     }
   198     
   199     @Compare public String newInstanceFails() {
   200         try {
   201             return "success: " + StaticUseSub.class.newInstance();
   202         } catch (IllegalAccessException ex) {
   203             return "failure";
   204         } catch (InstantiationException ex) {
   205             return "failure";
   206         }
   207     }
   208     
   209     @Compare public String paramTypes() throws Exception {
   210         Method plus = StaticUse.class.getMethod("plus", int.class, Integer.TYPE);
   211         final Class[] pt = plus.getParameterTypes();
   212         return pt[0].getName();
   213     }
   214     @Compare public String paramTypesNotFound() throws Exception {
   215         return StaticUse.class.getMethod("plus", int.class, double.class).toString();
   216     }
   217     @Compare public int methodWithArgs() throws Exception {
   218         Method plus = StaticUse.class.getMethod("plus", int.class, Integer.TYPE);
   219         return (Integer)plus.invoke(null, 2, 3);
   220     }
   221     
   222     @Compare public String classGetNameForByte() {
   223          return byte.class.getName();
   224     }
   225     @Compare public String classGetNameForBaseObject() {
   226         return newObject().getClass().getName();
   227     }
   228     @Compare public String classGetNameForJavaObject() {
   229         return new Object().getClass().getName();
   230     }
   231     @Compare public String classGetNameForObjectArray() {
   232         return (new Object[3]).getClass().getName();
   233     }
   234     @Compare public String classGetNameForSimpleIntArray() {
   235         return (new int[3]).getClass().getName();
   236     }
   237     @Compare public boolean sameClassGetNameForSimpleCharArray() {
   238         return (new char[3]).getClass() == (new char[34]).getClass();
   239     }
   240     @Compare public String classGetNameForMultiIntArray() {
   241         return (new int[3][4][5][6][7][8][9]).getClass().getName();
   242     }
   243     @Compare public String classGetNameForMultiIntArrayInner() {
   244         final int[][][][][][][] arr = new int[3][4][5][6][7][8][9];
   245         int[][][][][][] subarr = arr[0];
   246         int[][][][][] subsubarr = subarr[0];
   247         return subsubarr.getClass().getName();
   248     }
   249     @Compare public String classGetNameForMultiStringArray() {
   250         return (new String[3][4][5][6][7][8][9]).getClass().getName();
   251     }
   252     
   253     @Compare public String classForByte() throws Exception {
   254         return Class.forName("[Z").getName();
   255     }
   256 
   257     @Compare public String classForUnknownArray() {
   258         try {
   259             return Class.forName("[W").getName();
   260         } catch (Exception ex) {
   261             return ex.getClass().getName();
   262         }
   263     }
   264     
   265     @Compare public String classForUnknownDeepArray() {
   266         try {
   267             return Class.forName("[[[[[W").getName();
   268         } catch (Exception ex) {
   269             return ex.getClass().getName();
   270         }
   271     }
   272     
   273     @Compare public int callAbst() throws Exception {
   274         class Impl extends Abst {
   275             @Override
   276             public int abst() {
   277                 return 10;
   278             }
   279         }
   280         Abst impl = new Impl();
   281         return (int) Abst.class.getMethod("abst").invoke(impl);
   282     }
   283     
   284     @Compare public String componentGetNameForObjectArray() {
   285         return (new Object[3]).getClass().getComponentType().getName();
   286     }
   287     @Compare public boolean sameComponentGetNameForObjectArray() {
   288         return (new Object[3]).getClass().getComponentType() == Object.class;
   289     }
   290     @Compare public String componentGetNameForSimpleIntArray() {
   291         return (new int[3]).getClass().getComponentType().getName();
   292     }
   293     @Compare public String componentGetNameForMultiIntArray() {
   294         return (new int[3][4][5][6][7][8][9]).getClass().getComponentType().getName();
   295     }
   296     @Compare public String componentGetNameForMultiStringArray() {
   297         Class<?> c = (new String[3][4][5][6][7][8][9]).getClass();
   298         StringBuilder sb = new StringBuilder();
   299         for (;;) {
   300             sb.append(c.getName()).append("\n");
   301             c = c.getComponentType();
   302             if (c == null) {
   303                 break;
   304             }
   305         }
   306         return sb.toString();
   307     }
   308     
   309     @Compare public boolean isArray() {
   310         return new Object[0].getClass().isArray();
   311     }
   312 
   313     @Compare public String copyDataViaReflection() throws Exception {
   314         Data d = new Data();
   315         d.setName("Hello world!");
   316 
   317         Method getter = d.getClass().getMethod("getName");
   318         Object val = getter.invoke(d);
   319 
   320         Data clone = new Data();
   321         Method setter = d.getClass().getMethod("setName", String.class);
   322         setter.invoke(clone, val);
   323 
   324         return clone.getName();
   325     }
   326 
   327     @Compare public String copyStaticDataViaReflection() throws Exception {
   328         Data.setStatic("Hello world!");
   329 
   330         Method getter = Data.class.getMethod("getStatic");
   331         Object val = getter.invoke(null);
   332 
   333         Method setter = Data.class.getMethod("setStatic", String.class);
   334         setter.invoke(null, val);
   335 
   336         return Data.getStatic();
   337     }
   338     
   339     @JavaScriptBody(args = { "arr", "len" }, body="var a = arr.slice(0, len); a.sort(); return a;")
   340     private static String[] sort(String[] arr, int len) {
   341         List<String> list = Arrays.asList(arr).subList(0, len);
   342         Collections.sort(list);
   343         return list.toArray(new String[0]);
   344     }
   345     
   346     @JavaScriptBody(args = {}, body = "return new Object();")
   347     private static Object newObject() {
   348         return new Object();
   349     }
   350     
   351     @Factory
   352     public static Object[] create() {
   353         return VMTest.create(ReflectionTest.class);
   354     }
   355     
   356     public static abstract class Abst {
   357         public abstract int abst();
   358     }
   359 
   360     public static final class Data {
   361         private String name;
   362         private static String nameStatic;
   363 
   364         public String getName() {
   365             return name;
   366         }
   367 
   368         public void setName(String name) {
   369             this.name = name;
   370         }
   371 
   372         public static String getStatic() {
   373             return nameStatic;
   374         }
   375 
   376         public static void setStatic(String n) {
   377             nameStatic = n;
   378         }
   379     }
   380 }