package net.bytebuddy.implementation.auxiliary;
import net.bytebuddy.test.utility.CallTraceable;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import java.lang.reflect.Constructor;
import java.util.Arrays;
import java.util.Collection;
import java.util.concurrent.Callable;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
@RunWith(Parameterized.class)
public class MethodCallProxySingleArgumentTest<T extends CallTraceable> extends AbstractMethodCallProxyTest {
private static final String STRING_VALUE = "foo";
private static final boolean BOOLEAN_VALUE = true;
private static final byte BYTE_VALUE = 42;
private static final short SHORT_VALUE = 42;
private static final char CHAR_VALUE = '@';
private static final int INT_VALUE = 42;
private static final long LONG_VALUE = 42L;
private static final float FLOAT_VALUE = 42f;
private static final double DOUBLE_VALUE = 42d;
private static final Object NULL_VALUE = null;
private final Object value;
private final Class<T> targetType;
private final Class<?> valueType;
public MethodCallProxySingleArgumentTest(Object value, Class<T> targetType, Class<?> valueType) {
this.value = value;
this.targetType = targetType;
this.valueType = valueType;
}
@Parameterized.Parameters
public static Collection<Object[]> data() {
return Arrays.asList(new Object[][]{
{STRING_VALUE, StringTarget.class, String.class},
{BOOLEAN_VALUE, BooleanTarget.class, boolean.class},
{BYTE_VALUE, ByteTarget.class, byte.class},
{SHORT_VALUE, ShortTarget.class, short.class},
{CHAR_VALUE, CharTarget.class, char.class},
{INT_VALUE, IntTarget.class, int.class},
{LONG_VALUE, LongTarget.class, long.class},
{FLOAT_VALUE, FloatTarget.class, float.class},
{DOUBLE_VALUE, DoubleTarget.class, double.class},
{NULL_VALUE, NullTarget.class, Void.class}
});
}
@Test
public void testRunMethod() throws Exception {
Class<?> auxiliaryType = proxyOnlyDeclaredMethodOf(targetType);
Constructor<?> constructor = auxiliaryType.getDeclaredConstructor(targetType, valueType);
constructor.setAccessible(true);
T proxiedInstance = targetType.getDeclaredConstructor().newInstance();
((Runnable) constructor.newInstance(proxiedInstance, value)).run();
proxiedInstance.assertOnlyCall(FOO, value);
}
@Test
public void testCallMethod() throws Exception {
Class<?> auxiliaryType = proxyOnlyDeclaredMethodOf(targetType);
Constructor<?> constructor = auxiliaryType.getDeclaredConstructor(targetType, valueType);
constructor.setAccessible(true);
T proxiedInstance = targetType.getDeclaredConstructor().newInstance();
assertThat(((Callable<?>) constructor.newInstance(proxiedInstance, value)).call(), is(value));
proxiedInstance.assertOnlyCall(FOO, value);
}
@SuppressWarnings("unused")
public static class StringTarget extends CallTraceable {
public String foo(String s) {
register(FOO, s);
return s;
}
}
@SuppressWarnings("unused")
public static class BooleanTarget extends CallTraceable {
public boolean foo(boolean b) {
register(FOO, b);
return b;
}
}
@SuppressWarnings("unused")
public static class ByteTarget extends CallTraceable {
public byte foo(byte b) {
register(FOO, b);
return b;
}
}
@SuppressWarnings("unused")
public static class ShortTarget extends CallTraceable {
public short foo(short s) {
register(FOO, s);
return s;
}
}
@SuppressWarnings("unused")
public static class CharTarget extends CallTraceable {
public char foo(char c) {
register(FOO, c);
return c;
}
}
@SuppressWarnings("unused")
public static class IntTarget extends CallTraceable {
public int foo(int i) {
register(FOO, i);
return i;
}
}
@SuppressWarnings("unused")
public static class LongTarget extends CallTraceable {
public long foo(long l) {
register(FOO, l);
return l;
}
}
@SuppressWarnings("unused")
public static class FloatTarget extends CallTraceable {
public float foo(float f) {
register(FOO, f);
return f;
}
}
@SuppressWarnings("unused")
public static class DoubleTarget extends CallTraceable {
public double foo(double d) {
register(FOO, d);
return d;
}
}
@SuppressWarnings("unused")
public static class NullTarget extends CallTraceable {
public void foo(Void v) {
register(FOO, v);
}
}
}