jaroslav@355: /** jaroslav@355: * Back 2 Browser Bytecode Translator jaroslav@355: * Copyright (C) 2012 Jaroslav Tulach jaroslav@355: * jaroslav@355: * This program is free software: you can redistribute it and/or modify jaroslav@355: * it under the terms of the GNU General Public License as published by jaroslav@355: * the Free Software Foundation, version 2 of the License. jaroslav@355: * jaroslav@355: * This program is distributed in the hope that it will be useful, jaroslav@355: * but WITHOUT ANY WARRANTY; without even the implied warranty of jaroslav@355: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the jaroslav@355: * GNU General Public License for more details. jaroslav@355: * jaroslav@355: * You should have received a copy of the GNU General Public License jaroslav@355: * along with this program. Look for COPYING file in the top folder. jaroslav@355: * If not, see http://opensource.org/licenses/GPL-2.0. jaroslav@355: */ jaroslav@355: package org.apidesign.bck2brwsr.tck; jaroslav@355: jaroslav@655: import java.lang.annotation.Retention; jaroslav@655: import java.lang.annotation.RetentionPolicy; jaroslav@392: import java.lang.reflect.Method; jaroslav@392: import java.util.Arrays; jaroslav@392: import java.util.Collections; jaroslav@392: import java.util.List; jaroslav@392: import org.apidesign.bck2brwsr.core.JavaScriptBody; jaroslav@355: import org.apidesign.bck2brwsr.vmtest.Compare; jaroslav@355: import org.apidesign.bck2brwsr.vmtest.VMTest; jaroslav@355: import org.testng.annotations.Factory; jaroslav@355: jaroslav@355: /** jaroslav@355: * jaroslav@355: * @author Jaroslav Tulach jaroslav@355: */ jaroslav@355: public class ReflectionTest { jaroslav@412: @Compare public boolean nonNullThis() { jaroslav@412: return this == null; jaroslav@412: } jaroslav@412: jaroslav@355: @Compare public String intType() { jaroslav@355: return Integer.TYPE.toString(); jaroslav@355: } jaroslav@355: jaroslav@413: @Compare public String voidType() throws Exception { jaroslav@413: return void.class.toString(); jaroslav@413: } jaroslav@413: jaroslav@355: @Compare public String longClass() { jaroslav@355: return long.class.toString(); jaroslav@355: } jaroslav@355: jaroslav@649: @Compare public boolean isRunnableInterface() { jaroslav@649: return Runnable.class.isInterface(); jaroslav@649: } jaroslav@649: jaroslav@886: @Compare public boolean isAssignableToPrimitiveType() { jaroslav@886: return boolean.class.isAssignableFrom(Runnable.class); jaroslav@886: } jaroslav@886: jaroslav@886: @Compare public boolean isAssignableFromPrimitiveType() { jaroslav@886: return Runnable.class.isAssignableFrom(boolean.class); jaroslav@886: } jaroslav@886: jaroslav@886: @Compare public boolean isAssignableLongFromInt() { jaroslav@886: return long.class.isAssignableFrom(int.class); jaroslav@886: } jaroslav@886: jaroslav@886: @Compare public boolean isAssignableIntFromLong() { jaroslav@886: return int.class.isAssignableFrom(long.class); jaroslav@886: } jaroslav@886: jaroslav@649: @Compare public String isRunnableHasRunMethod() throws NoSuchMethodException { jaroslav@649: return Runnable.class.getMethod("run").getName(); jaroslav@649: } jaroslav@1312: jaroslav@1312: @Compare public String isRunnableDeclaresRunMethod() throws NoSuchMethodException { jaroslav@1312: return Runnable.class.getDeclaredMethod("run").getName(); jaroslav@1312: } jaroslav@649: jaroslav@392: @Compare public String namesOfMethods() { jaroslav@392: StringBuilder sb = new StringBuilder(); jaroslav@392: String[] arr = new String[20]; jaroslav@392: int i = 0; jaroslav@392: for (Method m : StaticUse.class.getMethods()) { jaroslav@392: arr[i++] = m.getName(); jaroslav@392: } jaroslav@392: for (String s : sort(arr, i)) { jaroslav@392: sb.append(s).append("\n"); jaroslav@392: } jaroslav@392: return sb.toString(); jaroslav@392: } jaroslav@655: jaroslav@655: @Compare public String namesOfDeclaringClassesOfMethods() { jaroslav@655: StringBuilder sb = new StringBuilder(); jaroslav@655: String[] arr = new String[20]; jaroslav@655: int i = 0; jaroslav@655: for (Method m : StaticUse.class.getMethods()) { jaroslav@655: arr[i++] = m.getName() + "@" + m.getDeclaringClass().getName(); jaroslav@655: } jaroslav@655: for (String s : sort(arr, i)) { jaroslav@655: sb.append(s).append("\n"); jaroslav@655: } jaroslav@655: return sb.toString(); jaroslav@655: } jaroslav@392: jaroslav@413: @Compare public String cannotCallNonStaticMethodWithNull() throws Exception { jaroslav@416: StaticUse.class.getMethod("instanceMethod").invoke(null); jaroslav@416: return "should not happen"; jaroslav@416: } jaroslav@962: jaroslav@962: @Compare public String classCastException() { jaroslav@962: try { jaroslav@962: Integer i = (Integer)StaticUseSub.getNonNull(); jaroslav@962: return "" + i.intValue(); jaroslav@962: } catch (ClassCastException ex) { jaroslav@962: return ex.getClass().getName(); jaroslav@962: } jaroslav@962: } jaroslav@416: jaroslav@938: @Compare public String methodThatThrowsException() throws Exception { jaroslav@938: StaticUse.class.getMethod("instanceMethod").invoke(new StaticUse()); jaroslav@938: return "should not happen"; jaroslav@938: } jaroslav@938: jaroslav@416: @Compare public Object voidReturnType() throws Exception { jaroslav@416: return StaticUse.class.getMethod("instanceMethod").getReturnType(); jaroslav@413: } jaroslav@413: jaroslav@655: @Retention(RetentionPolicy.RUNTIME) jaroslav@655: @interface Ann { jaroslav@655: } jaroslav@655: jaroslav@655: @Compare public String annoClass() throws Exception { jaroslav@655: Retention r = Ann.class.getAnnotation(Retention.class); jaroslav@655: assert r != null : "Annotation is present"; jaroslav@655: assert r.value() == RetentionPolicy.RUNTIME : "Policy value is OK: " + r.value(); jaroslav@655: return r.annotationType().getName(); jaroslav@655: } jaroslav@655: jaroslav@661: @Compare public boolean isAnnotation() { jaroslav@661: return Ann.class.isAnnotation(); jaroslav@661: } jaroslav@661: @Compare public boolean isNotAnnotation() { jaroslav@661: return String.class.isAnnotation(); jaroslav@661: } jaroslav@661: @Compare public boolean isNotAnnotationEnum() { jaroslav@661: return E.class.isAnnotation(); jaroslav@661: } jaroslav@586: enum E { A, B }; jaroslav@586: @Compare public boolean isEnum() { jaroslav@586: return E.A.getClass().isEnum(); jaroslav@586: } jaroslav@586: jaroslav@586: @Compare public boolean isNotEnum() { jaroslav@586: return "".getClass().isEnum(); jaroslav@586: } jaroslav@586: jaroslav@394: @Compare public String newInstanceFails() throws InstantiationException { jaroslav@394: try { jaroslav@775: return "success: " + StaticUseSub.class.newInstance(); jaroslav@394: } catch (IllegalAccessException ex) { jaroslav@394: return ex.getClass().getName(); jaroslav@394: } jaroslav@394: } jaroslav@394: jaroslav@418: @Compare public String paramTypes() throws Exception { jaroslav@418: Method plus = StaticUse.class.getMethod("plus", int.class, Integer.TYPE); jaroslav@418: final Class[] pt = plus.getParameterTypes(); jaroslav@418: return pt[0].getName(); jaroslav@418: } jaroslav@420: @Compare public String paramTypesNotFound() throws Exception { jaroslav@420: return StaticUse.class.getMethod("plus", int.class, double.class).toString(); jaroslav@420: } jaroslav@418: @Compare public int methodWithArgs() throws Exception { jaroslav@418: Method plus = StaticUse.class.getMethod("plus", int.class, Integer.TYPE); jaroslav@418: return (Integer)plus.invoke(null, 2, 3); jaroslav@418: } jaroslav@418: jaroslav@448: @Compare public String classGetNameForByte() { jaroslav@448: return byte.class.getName(); jaroslav@448: } jaroslav@448: @Compare public String classGetNameForBaseObject() { jaroslav@448: return newObject().getClass().getName(); jaroslav@448: } jaroslav@448: @Compare public String classGetNameForJavaObject() { jaroslav@448: return new Object().getClass().getName(); jaroslav@448: } jaroslav@448: @Compare public String classGetNameForObjectArray() { jaroslav@448: return (new Object[3]).getClass().getName(); jaroslav@448: } jaroslav@448: @Compare public String classGetNameForSimpleIntArray() { jaroslav@448: return (new int[3]).getClass().getName(); jaroslav@448: } jaroslav@448: @Compare public boolean sameClassGetNameForSimpleCharArray() { jaroslav@448: return (new char[3]).getClass() == (new char[34]).getClass(); jaroslav@448: } jaroslav@448: @Compare public String classGetNameForMultiIntArray() { jaroslav@448: return (new int[3][4][5][6][7][8][9]).getClass().getName(); jaroslav@448: } jaroslav@453: @Compare public String classGetNameForMultiIntArrayInner() { jaroslav@453: final int[][][][][][][] arr = new int[3][4][5][6][7][8][9]; jaroslav@453: int[][][][][][] subarr = arr[0]; jaroslav@453: int[][][][][] subsubarr = subarr[0]; jaroslav@453: return subsubarr.getClass().getName(); jaroslav@453: } jaroslav@448: @Compare public String classGetNameForMultiStringArray() { jaroslav@448: return (new String[3][4][5][6][7][8][9]).getClass().getName(); jaroslav@448: } jaroslav@448: jaroslav@449: @Compare public String classForByte() throws Exception { jaroslav@449: return Class.forName("[Z").getName(); jaroslav@449: } jaroslav@452: jaroslav@452: @Compare public String classForUnknownArray() { jaroslav@452: try { jaroslav@452: return Class.forName("[W").getName(); jaroslav@452: } catch (Exception ex) { jaroslav@452: return ex.getClass().getName(); jaroslav@452: } jaroslav@452: } jaroslav@452: jaroslav@452: @Compare public String classForUnknownDeepArray() { jaroslav@452: try { jaroslav@452: return Class.forName("[[[[[W").getName(); jaroslav@452: } catch (Exception ex) { jaroslav@452: return ex.getClass().getName(); jaroslav@452: } jaroslav@452: } jaroslav@449: jaroslav@449: @Compare public String componentGetNameForObjectArray() { jaroslav@449: return (new Object[3]).getClass().getComponentType().getName(); jaroslav@449: } jaroslav@449: @Compare public boolean sameComponentGetNameForObjectArray() { jaroslav@449: return (new Object[3]).getClass().getComponentType() == Object.class; jaroslav@449: } jaroslav@449: @Compare public String componentGetNameForSimpleIntArray() { jaroslav@449: return (new int[3]).getClass().getComponentType().getName(); jaroslav@449: } jaroslav@449: @Compare public String componentGetNameForMultiIntArray() { jaroslav@449: return (new int[3][4][5][6][7][8][9]).getClass().getComponentType().getName(); jaroslav@449: } jaroslav@449: @Compare public String componentGetNameForMultiStringArray() { jaroslav@449: Class c = (new String[3][4][5][6][7][8][9]).getClass(); jaroslav@449: StringBuilder sb = new StringBuilder(); jaroslav@449: for (;;) { jaroslav@449: sb.append(c.getName()).append("\n"); jaroslav@449: c = c.getComponentType(); jaroslav@449: if (c == null) { jaroslav@449: break; jaroslav@449: } jaroslav@449: } jaroslav@449: return sb.toString(); jaroslav@449: } jaroslav@449: jaroslav@448: @Compare public boolean isArray() { jaroslav@448: return new Object[0].getClass().isArray(); jaroslav@448: } jaroslav@448: jaroslav@392: @JavaScriptBody(args = { "arr", "len" }, body="var a = arr.slice(0, len); a.sort(); return a;") jaroslav@392: private static String[] sort(String[] arr, int len) { jaroslav@392: List list = Arrays.asList(arr).subList(0, len); jaroslav@392: Collections.sort(list); jaroslav@392: return list.toArray(new String[0]); jaroslav@392: } jaroslav@355: jaroslav@448: @JavaScriptBody(args = {}, body = "return new Object();") jaroslav@448: private static Object newObject() { jaroslav@448: return new Object(); jaroslav@448: } jaroslav@448: jaroslav@355: @Factory jaroslav@355: public static Object[] create() { jaroslav@355: return VMTest.create(ReflectionTest.class); jaroslav@355: } jaroslav@355: jaroslav@355: }