package com.example.test.reflect2;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import com.example.test.reflect1.MethodRecordingObject;
abstract public class InvokeTestHarness implements Runnable {
abstract public void checkInvocation(Object obj, String method, Object expectedReturnValue, Object... arguments);
abstract public void checkProxyInvocation(MethodRecordingObject obj, String method, String expectedSignature, Object... arguments);
abstract public void onFailure(AbstractTestItem<?> item, TestFailure tf);
static public class TestFailure extends RuntimeException
{
public TestFailure(RuntimeException re)
{
super(re);
}
public TestFailure(String msg)
{
super(msg);
}
}
abstract static public class AbstractTestItem<T> {
final private T obj;
final private String method;
final private List<?> arguments;
public AbstractTestItem(T obj, String method, Object... args)
{
this.obj = obj;
this.method = method;
List<Object> alist = new ArrayList<Object>();
for (Object arg : args)
alist.add(arg);
this.arguments = Collections.unmodifiableList(alist);
}
public T getObject() { return this.obj; }
public String getMethodName() { return this.method; }
public Object[] getArgumentsArray() { return this.arguments.toArray(new Object[0]); }
abstract public void run(InvokeTestHarness harness);
protected void appendArguments(StringBuilder sb)
{
boolean first = true;
for (Object arg : arguments)
{
if (first)
first = false;
else
sb.append(",");
sb.append(arg);
}
}
protected void appendCall(StringBuilder sb)
{
sb.append(getObject())
.append(".")
.append(getMethodName())
.append("(");
appendArguments(sb);
sb.append(")");
}
}
static public class TestItem extends AbstractTestItem<Object>
{
final private Object expectedReturnValue;
public Object getExpectedReturnValue() { return this.expectedReturnValue; }
public TestItem(Object obj, String method, Object expectedReturnValue, Object... args)
{
super(obj, method, args);
this.expectedReturnValue = expectedReturnValue;
}
@Override public void run(InvokeTestHarness harness)
{
harness.checkInvocation(getObject(), getMethodName(), getExpectedReturnValue(), getArgumentsArray());
}
@Override public String toString() {
StringBuilder sb = new StringBuilder();
appendCall(sb);
sb.append("\nexpected return value: ");
sb.append(getExpectedReturnValue());
return sb.toString();
}
}
static public class MethodRecordingTestItem extends AbstractTestItem<MethodRecordingObject>
{
final private String expectedSignature;
public String getExpectedSignature() { return this.expectedSignature; }
public MethodRecordingTestItem(MethodRecordingObject obj, String method, String expectedSignature, Object... args)
{
super(obj, method, args);
this.expectedSignature = expectedSignature;
}
@Override public void run(InvokeTestHarness harness)
{
harness.checkProxyInvocation(getObject(), getMethodName(), getExpectedSignature(), getArgumentsArray());
}
@Override public String toString() {
StringBuilder sb = new StringBuilder();
appendCall(sb);
sb.append("\nexpected signature: ");
sb.append(getExpectedSignature());
return sb.toString();
}
}
static public class TestItemListBuilder
{
final private List<AbstractTestItem<?>> items;
private Object obj = null;
private String methodName = null;
public TestItemListBuilder()
{
this.items = new ArrayList<AbstractTestItem<?>>();
}
public TestItemListBuilder setObject(Object obj) { this.obj = obj; return this; }
public TestItemListBuilder setMethodName(String method) { this.methodName = method; return this; }
public TestItemListBuilder addTestItem(Object obj1, String method1, Object expectedReturnValue, Object... args)
{
this.items.add(new TestItem(obj1, method1, expectedReturnValue, args));
return this;
}
public TestItemListBuilder addItem(Object expectedReturnValue, Object... args)
{
this.items.add(new TestItem(this.obj, this.methodName, expectedReturnValue, args));
return this;
}
public TestItemListBuilder addRecordingTest(MethodRecordingObject obj, String method, String expectedSignature, Object... args)
{
this.items.add(new MethodRecordingTestItem(obj, method, expectedSignature, args));
return this;
}
public TestItemListBuilder addRecordingItem(String expectedSignature, Object... args)
{
MethodRecordingObject mro = (MethodRecordingObject) this.obj;
this.items.add(new MethodRecordingTestItem(mro, this.methodName, expectedSignature, args));
return this;
}
public List<AbstractTestItem<?>> build() { return this.items; }
}
static public TestItemListBuilder testItemsBuilder() { return new TestItemListBuilder(); }
final private List<AbstractTestItem<?>> testItems;
public InvokeTestHarness(List<AbstractTestItem<?>> testItems)
{
this.testItems = Collections.unmodifiableList(new ArrayList<AbstractTestItem<?>>(testItems));
}
@Override public void run()
{
for (AbstractTestItem<?> item : this.testItems)
{
try
{
item.run(this);
}
catch (TestFailure tf)
{
onFailure(item, tf);
}
}
}
}