package net.bytebuddy.implementation.auxiliary;
import net.bytebuddy.ClassFileVersion;
import net.bytebuddy.description.method.MethodDescription;
import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.dynamic.DynamicType;
import net.bytebuddy.dynamic.loading.ClassLoadingStrategy;
import net.bytebuddy.implementation.Implementation;
import net.bytebuddy.implementation.MethodAccessorFactory;
import net.bytebuddy.test.utility.MockitoRule;
import org.hamcrest.CoreMatchers;
import org.junit.Rule;
import org.junit.rules.TestRule;
import org.mockito.Mock;
import org.objectweb.asm.Opcodes;
import java.util.concurrent.Callable;
import static net.bytebuddy.matcher.ElementMatchers.isConstructor;
import static net.bytebuddy.matcher.ElementMatchers.not;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.mockito.Mockito.*;
public class AbstractMethodCallProxyTest {
protected static final String FOO = "foo";
@Rule
public TestRule mockitoRule = new MockitoRule(this);
@Mock
private Implementation.SpecialMethodInvocation specialMethodInvocation;
@Mock
private MethodAccessorFactory methodAccessorFactory;
protected Class<?> proxyOnlyDeclaredMethodOf(Class<?> proxyTarget) throws Exception {
MethodDescription.InDefinedShape proxyMethod = new TypeDescription.ForLoadedType(proxyTarget)
.getDeclaredMethods().filter(not(isConstructor())).getOnly();
when(methodAccessorFactory.registerAccessorFor(specialMethodInvocation, MethodAccessorFactory.AccessType.DEFAULT)).thenReturn(proxyMethod);
String auxiliaryTypeName = getClass().getName() + "$" + proxyTarget.getSimpleName() + "$Proxy";
DynamicType dynamicType = new MethodCallProxy(specialMethodInvocation, false).make(auxiliaryTypeName,
ClassFileVersion.ofThisVm(),
methodAccessorFactory);
DynamicType.Unloaded<?> unloaded = (DynamicType.Unloaded<?>) dynamicType;
Class<?> auxiliaryType = unloaded.load(getClass().getClassLoader(), ClassLoadingStrategy.Default.WRAPPER).getLoaded();
assertThat(auxiliaryType.getName(), is(auxiliaryTypeName));
verify(methodAccessorFactory).registerAccessorFor(specialMethodInvocation, MethodAccessorFactory.AccessType.DEFAULT);
verifyNoMoreInteractions(methodAccessorFactory);
verifyZeroInteractions(specialMethodInvocation);
assertThat(auxiliaryType.getModifiers(), is(Opcodes.ACC_SYNTHETIC));
assertThat(Callable.class.isAssignableFrom(auxiliaryType), is(true));
assertThat(Runnable.class.isAssignableFrom(auxiliaryType), is(true));
assertThat(auxiliaryType.getDeclaredConstructors().length, is(1));
assertThat(auxiliaryType.getDeclaredMethods().length, is(2));
assertThat(auxiliaryType.getDeclaredFields().length, is(proxyMethod.getParameters().size() + (proxyMethod.isStatic() ? 0 : 1)));
int fieldIndex = 0;
if (!proxyMethod.isStatic()) {
assertThat(auxiliaryType.getDeclaredFields()[fieldIndex++].getType(), CoreMatchers.<Class<?>>is(proxyTarget));
}
for (Class<?> parameterType : proxyTarget.getDeclaredMethods()[0].getParameterTypes()) {
assertThat(auxiliaryType.getDeclaredFields()[fieldIndex++].getType(), CoreMatchers.<Class<?>>is(parameterType));
}
return auxiliaryType;
}
}