package xapi.test.gwt.reflect;
import static xapi.log.X_Log.error;
import static xapi.log.X_Log.trace;
import static com.google.gwt.reflect.shared.GwtReflect.*;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import xapi.annotation.reflect.KeepClass;
import xapi.annotation.reflect.KeepConstructor;
import xapi.annotation.reflect.KeepField;
import xapi.annotation.reflect.KeepMethod;
import xapi.inject.X_Inject;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.dom.client.Document;
@KeepConstructor
@KeepMethod
@KeepField
@KeepClass(
keepPackage = true,
keepCodeSource = true
)
public class MagicClassEntryPoint implements EntryPoint{
//this boolean will only be set if everything else succeeds.
private boolean passed = false;
boolean ctor0 = false;
public MagicClassEntryPoint() {
ctor0 = true;
trace("Empty ctor");
}
private static boolean ctor1 = false;
public MagicClassEntryPoint(boolean b, byte B, short s, char c,
int i, long l, float f, double d) {
ctor1 = true;
trace("Primitive ctor",b,B,c,s,i,l,f,d);
}
protected static boolean ctor2 = false;
public MagicClassEntryPoint(Boolean b, Byte B, Short s, Character c,
Integer i, Long l, Float f, Double d) {
ctor2 = true;
trace("Object ctor",b,B,c,s,i,l,f,d);
}
protected static boolean ctor3 = false;
public MagicClassEntryPoint(String str, int i, Integer I, Object o
, JavaScriptObject jso, float f, Float F, short s, Short S) {
ctor3 = true;
trace("ctor w/ params",str,i,I,o);
}
public void onModuleLoad() {
Class<MagicClassEntryPoint> cls = magicClass(MagicClassEntryPoint.class);
//test the big ugly ctor
try {
Constructor<MagicClassEntryPoint> ctor = cls.getConstructor(String.class, int.class, Integer.class,
Object.class, JavaScriptObject.class, float.class, Float.class,
short.class, Short.class);
ctor.newInstance("", 1,2,new Object(),
JavaScriptObject.createObject(),0.5,2.5,6,7);
}catch(Exception e) {
error("ERROR",e);
}
//test the primitive ctor
try {
Constructor<MagicClassEntryPoint> ctor = cls.getConstructor(boolean.class,
byte.class, short.class, char.class, int.class,
long.class,float.class,double.class);
// primitives
ctor.newInstance(true, 0, 2,
'a',3, 4L,
5.5f, 6.6);
// non-primitives
ctor.newInstance(Boolean.TRUE, new Byte("1"), new Short("2"),
new Character('a'),new Integer(3), new Long(4),
new Float(5.5), new Double(6.6));
}catch(Exception e) {
error("ERROR",e);
}
//test the object ctor
try {
Constructor<MagicClassEntryPoint> ctor = cls.getConstructor(Boolean.class,
Byte.class, Short.class, Character.class,
Integer.class,Long.class,Float.class,Double.class);
ctor.newInstance(false, (byte)1, (short)2, 'a',
3, 4L, 5.5f, 6.6);
}catch(Exception e) {
error("ERROR",e);
}
for (Constructor<?> c : cls.getConstructors()) {
try {
trace((MagicClassEntryPoint)c.newInstance());
} catch (Exception e) {
error(e);
}
}
//constructors passed.
//now lets grab the methods and use them...
//...to perform asserts on our fields!!
Method[] methods = cls.getMethods();
Method testAsserts = null;
//call all of them EXCEPT onModuleLoad, as recursion sickness is no fun!
for (Method m : methods) {
if (!"onModuleLoad".equals(m.getName())) {
if ("testAsserts".equals(m.getName())) {
testAsserts = m;
}else
try {
m.invoke(this, 2, 2, 3, "four");
} catch (Exception e) {
error(e);
}
}
}
//make sure methods retain type data.
Class<?>[] params = testAsserts.getParameterTypes();
assertEqual(params[0], X_Inject.class);
assertEqual(params[1], Long.class);
assertEqual(params[2], long.class);
assertEqual(params[3], Void.class);
try {
//first, let's grab our Boolean field and change it from null to true
Field field = cls.getField("field0");
if (field.get(this) != null) {
error("Boolean field did not return null");
}
field.set(this, true);
assertEqual(field.getType(), Boolean.class);
//Now, let's check all of our fields, except for the passed variable;
//that variable is only set by the testAsserts() method,
//which we call by reflection at the very end
Field[] fields = cls.getFields();
for (Field f : fields) {
if ("passed".equals(f.getName()))
continue;
if (!f.getBoolean(this)) {
error("Field "+f.getName()+" was not set to true!!");
}
}
//now, let's grab all our fields, and assert they are true!
}catch(Exception e) {
error("Error testing fields", e);
}
//finished our functional tests,
//now invoke our asserts method
try {
testAsserts.invoke(this);
}catch(Exception e) {
error("Failed assertions!", e);
throw new RuntimeException(e);
}
// String codeSource = MagicClassEntryPoint.class.getProtectionDomain().getCodeSource().getLocation().toExternalForm();
// Assert.assertTrue("Metadata missing", codeSource.contains(MagicClassEntryPoint.class.getSimpleName()));
//finally, since we can't trust our reflection tests,
//let's manually check.
if (!passed) {//can't be set unless testAsserts() was called and passed.
error("One or more tests have failed.");
throw new RuntimeException("Test Failed");
}
}
private void assertEqual(Object one, Object two) {
if (one == two)
return;
if (one.equals(two))
return;
error("Objects not equal!",one,two);
throw new AssertionError("Expected "+one+"; received "+two);
}
private boolean method0 = false;
public void method0(int i, short s, Long l, String val) {
method0 = true;
trace("method0", i, s, l, val);
}
private static boolean method1 = false;
public static void method1(int i, short s, Long l, String val) {
method1 = true;
trace("method1", i, s, l, val);
}
private Boolean field0;
@SuppressWarnings("unused")
private void testAsserts(X_Inject inject, Long L, long l, Void Void) {
passed = true;
ArrayList<String> errors = new ArrayList<String>();
if (!ctor0) {
passed = false;
String err = "Constructor 0 was not called!";
errors.add(err);
error(err);
}
if (!ctor1) {
passed = false;
String err = "Constructor 1 was not called!";
errors.add(err);
error(err);
}
if (!ctor2) {
passed = false;
String err = "Constructor 2 was not called!";
errors.add(err);
error(err);
}
if (!ctor3) {
passed = false;
String err = "Constructor 3 was not called!";
errors.add(err);
error(err);
}
if (!method0) {
passed = false;
String err = "Method 0 was not called!";
errors.add(err);
error(err);
}
if (!method1) {
passed = false;
String err = "Method 1 was not called!";
errors.add(err);
error(err);
}
if (!field0) {
passed = false;
String err = "Field 0 was not updated!";
errors.add(err);
error(err);
}
Document.get().getBody().setInnerHTML("Tests Have "
+(passed?"Passed":"Failed; check console for details."));
if (!passed)
throw new RuntimeException("Failed test");
trace("Success == ",passed);
}
}