package net.bytebuddy.dynamic.scaffold;
import net.bytebuddy.description.ModifierReviewable;
import net.bytebuddy.description.NamedElement;
import net.bytebuddy.description.TypeVariableSource;
import net.bytebuddy.description.annotation.AnnotationDescription;
import net.bytebuddy.description.annotation.AnnotationSource;
import net.bytebuddy.description.annotation.AnnotationValue;
import net.bytebuddy.description.field.FieldDescription;
import net.bytebuddy.description.method.MethodDescription;
import net.bytebuddy.description.method.ParameterDescription;
import net.bytebuddy.description.modifier.ModifierContributor;
import net.bytebuddy.description.type.*;
import net.bytebuddy.dynamic.TargetType;
import net.bytebuddy.dynamic.Transformer;
import net.bytebuddy.implementation.Implementation;
import net.bytebuddy.implementation.LoadedTypeInitializer;
import net.bytebuddy.implementation.bytecode.ByteCodeAppender;
import net.bytebuddy.implementation.bytecode.StackSize;
import net.bytebuddy.test.packaging.PackagePrivateType;
import net.bytebuddy.test.utility.MockitoRule;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TestRule;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import java.io.Serializable;
import java.lang.annotation.Target;
import java.util.Arrays;
import java.util.Collections;
import static net.bytebuddy.matcher.ElementMatchers.named;
import static org.hamcrest.CoreMatchers.*;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.mockito.Mockito.*;
public class InstrumentedTypeDefaultTest {
private static final String FOO = "foo", BAR = "bar", QUX = "qux", BAZ = "baz", ILLEGAL_NAME = "<>";
private static final int ILLEGAL_MODIFIERS = -1, OTHER_MODIFIERS = 42;
@Rule
public TestRule mockitoRule = new MockitoRule(this);
@Mock
private MethodVisitor methodVisitor;
@Mock
private Implementation.Context implementationContext;
@Mock
private AnnotationDescription annotationDescription;
protected static InstrumentedType.WithFlexibleName makePlainInstrumentedType() {
return new InstrumentedType.Default(FOO + "." + BAZ,
ModifierReviewable.EMPTY_MASK,
TypeDescription.Generic.OBJECT,
Collections.<TypeVariableToken>emptyList(),
Collections.<TypeDescription.Generic>emptyList(),
Collections.<FieldDescription.Token>emptyList(),
Collections.<MethodDescription.Token>emptyList(),
Collections.<AnnotationDescription>emptyList(),
TypeInitializer.None.INSTANCE,
LoadedTypeInitializer.NoOp.INSTANCE,
TypeDescription.UNDEFINED,
MethodDescription.UNDEFINED,
TypeDescription.UNDEFINED,
Collections.<TypeDescription>emptyList(),
false,
false,
false);
}
@Test
@SuppressWarnings("unchecked")
public void testWithTypeVariable() throws Exception {
TypeDescription.Generic boundType = mock(TypeDescription.Generic.class);
when(boundType.asGenericType()).thenReturn(boundType);
when(boundType.accept(Mockito.any(TypeDescription.Generic.Visitor.class))).thenReturn(boundType);
TypeDescription rawBoundType = mock(TypeDescription.class);
when(boundType.asErasure()).thenReturn(rawBoundType);
when(rawBoundType.getName()).thenReturn(FOO);
InstrumentedType instrumentedType = makePlainInstrumentedType();
assertThat(instrumentedType.getTypeVariables().size(), is(0));
instrumentedType = instrumentedType.withTypeVariable(new TypeVariableToken(BAR, Collections.singletonList(boundType)));
assertThat(instrumentedType.getTypeVariables().size(), is(1));
TypeDescription.Generic typeVariable = instrumentedType.getTypeVariables().get(0);
assertThat(typeVariable.getTypeName(), is(BAR));
assertThat(typeVariable.getTypeVariableSource(), sameInstance((TypeVariableSource) instrumentedType));
assertThat(typeVariable.getUpperBounds(), is(Collections.singletonList(boundType)));
}
@Test
public void testWithTypeVariableWithInstrumentedType() throws Exception {
InstrumentedType instrumentedType = makePlainInstrumentedType();
assertThat(instrumentedType.getTypeVariables().size(), is(0));
instrumentedType = instrumentedType.withTypeVariable(new TypeVariableToken(BAR, Collections.singletonList(TargetType.DESCRIPTION.asGenericType())));
assertThat(instrumentedType.getTypeVariables().size(), is(1));
TypeDescription.Generic typeVariable = instrumentedType.getTypeVariables().get(0);
assertThat(typeVariable.getTypeName(), is(BAR));
assertThat(typeVariable.getTypeVariableSource(), sameInstance((TypeVariableSource) instrumentedType));
assertThat(typeVariable.getUpperBounds(), is(Collections.singletonList(instrumentedType.asGenericType())));
}
@Test
@SuppressWarnings("unchecked")
public void testWithTypeVariableTransformed() throws Exception {
TypeDescription.Generic boundType = mock(TypeDescription.Generic.class);
when(boundType.asGenericType()).thenReturn(boundType);
when(boundType.accept(Mockito.any(TypeDescription.Generic.Visitor.class))).thenReturn(boundType);
TypeDescription rawBoundType = mock(TypeDescription.class);
when(boundType.asErasure()).thenReturn(rawBoundType);
when(rawBoundType.getName()).thenReturn(FOO);
InstrumentedType.WithFlexibleName instrumentedType = makePlainInstrumentedType();
assertThat(instrumentedType.getTypeVariables().size(), is(0));
instrumentedType = instrumentedType.withTypeVariable(new TypeVariableToken(BAR, Collections.singletonList(boundType)));
Transformer<TypeVariableToken> transformer = mock(Transformer.class);
TypeDescription.Generic otherBoundType = mock(TypeDescription.Generic.class);
when(otherBoundType.asGenericType()).thenReturn(otherBoundType);
when(otherBoundType.accept(Mockito.any(TypeDescription.Generic.Visitor.class))).thenReturn(otherBoundType);
TypeDescription rawOtherBoundType = mock(TypeDescription.class);
when(otherBoundType.asErasure()).thenReturn(rawOtherBoundType);
when(transformer.transform(instrumentedType, new TypeVariableToken(BAR, Collections.singletonList(boundType))))
.thenReturn(new TypeVariableToken(QUX, Collections.singletonList(otherBoundType)));
instrumentedType = instrumentedType.withTypeVariables(named(BAR), transformer);
assertThat(instrumentedType.getTypeVariables().size(), is(1));
TypeDescription.Generic typeVariable = instrumentedType.getTypeVariables().get(0);
assertThat(typeVariable.getTypeName(), is(QUX));
assertThat(typeVariable.getTypeVariableSource(), sameInstance((TypeVariableSource) instrumentedType));
assertThat(typeVariable.getUpperBounds(), is(Collections.singletonList(otherBoundType)));
}
@Test
@SuppressWarnings("unchecked")
public void testWithField() throws Exception {
TypeDescription.Generic fieldType = mock(TypeDescription.Generic.class);
when(fieldType.accept(Mockito.any(TypeDescription.Generic.Visitor.class))).thenReturn(fieldType);
TypeDescription rawFieldType = mock(TypeDescription.class);
when(fieldType.asErasure()).thenReturn(rawFieldType);
when(rawFieldType.getName()).thenReturn(FOO);
InstrumentedType instrumentedType = makePlainInstrumentedType();
assertThat(instrumentedType.getDeclaredFields().size(), is(0));
instrumentedType = instrumentedType.withField(new FieldDescription.Token(BAR, Opcodes.ACC_PUBLIC, fieldType));
assertThat(instrumentedType.getDeclaredFields().size(), is(1));
FieldDescription.InDefinedShape fieldDescription = instrumentedType.getDeclaredFields().get(0);
assertThat(fieldDescription.getType(), is(fieldType));
assertThat(fieldDescription.getModifiers(), is(Opcodes.ACC_PUBLIC));
assertThat(fieldDescription.getName(), is(BAR));
assertThat(fieldDescription.getDeclaringType(), sameInstance((TypeDescription) instrumentedType));
}
@Test
public void testWithFieldOfInstrumentedType() throws Exception {
InstrumentedType instrumentedType = makePlainInstrumentedType();
assertThat(instrumentedType.getDeclaredFields().size(), is(0));
instrumentedType = instrumentedType.withField(new FieldDescription.Token(BAR, Opcodes.ACC_PUBLIC, TargetType.DESCRIPTION.asGenericType()));
assertThat(instrumentedType.getDeclaredFields().size(), is(1));
FieldDescription.InDefinedShape fieldDescription = instrumentedType.getDeclaredFields().get(0);
assertThat(fieldDescription.getType().asErasure(), sameInstance((TypeDescription) instrumentedType));
assertThat(fieldDescription.getModifiers(), is(Opcodes.ACC_PUBLIC));
assertThat(fieldDescription.getName(), is(BAR));
assertThat(fieldDescription.getDeclaringType(), sameInstance((TypeDescription) instrumentedType));
}
@Test
public void testWithFieldOfInstrumentedTypeAsArray() throws Exception {
InstrumentedType instrumentedType = makePlainInstrumentedType();
assertThat(instrumentedType.getDeclaredFields().size(), is(0));
instrumentedType = instrumentedType.withField(new FieldDescription.Token(BAR, Opcodes.ACC_PUBLIC,
new TypeDescription.Generic.OfGenericArray.Latent(TargetType.DESCRIPTION.asGenericType(), new AnnotationSource.Explicit(annotationDescription))));
assertThat(instrumentedType.getDeclaredFields().size(), is(1));
FieldDescription.InDefinedShape fieldDescription = instrumentedType.getDeclaredFields().get(0);
assertThat(fieldDescription.getType().getSort(), is(TypeDefinition.Sort.NON_GENERIC));
assertThat(fieldDescription.getType().asErasure().isArray(), is(true));
assertThat(fieldDescription.getType().asErasure().getComponentType(), sameInstance((TypeDescription) instrumentedType));
assertThat(fieldDescription.getModifiers(), is(Opcodes.ACC_PUBLIC));
assertThat(fieldDescription.getName(), is(BAR));
assertThat(fieldDescription.getType().getDeclaredAnnotations().size(), is(1));
assertThat(fieldDescription.getType().getDeclaredAnnotations().getOnly(), is(annotationDescription));
assertThat(fieldDescription.getDeclaringType(), sameInstance((TypeDescription) instrumentedType));
}
@Test
@SuppressWarnings("unchecked")
public void testWithMethod() throws Exception {
TypeDescription.Generic returnType = mock(TypeDescription.Generic.class);
when(returnType.accept(Mockito.any(TypeDescription.Generic.Visitor.class))).thenReturn(returnType);
TypeDescription rawReturnType = mock(TypeDescription.class);
when(returnType.asErasure()).thenReturn(rawReturnType);
when(rawReturnType.getName()).thenReturn(FOO);
TypeDescription.Generic parameterType = mock(TypeDescription.Generic.class);
when(parameterType.accept(Mockito.any(TypeDescription.Generic.Visitor.class))).thenReturn(parameterType);
when(parameterType.asGenericType()).thenReturn(parameterType);
TypeDescription rawParameterType = mock(TypeDescription.class);
when(parameterType.asErasure()).thenReturn(rawParameterType);
when(rawParameterType.getName()).thenReturn(QUX);
when(rawParameterType.getStackSize()).thenReturn(StackSize.ZERO);
InstrumentedType instrumentedType = makePlainInstrumentedType();
assertThat(instrumentedType.getDeclaredFields().size(), is(0));
instrumentedType = instrumentedType.withMethod(new MethodDescription.Token(BAR,
Opcodes.ACC_PUBLIC,
returnType,
Collections.singletonList(parameterType)));
assertThat(instrumentedType.getDeclaredMethods().size(), is(1));
MethodDescription.InDefinedShape methodDescription = instrumentedType.getDeclaredMethods().get(0);
assertThat(methodDescription.getReturnType(), is(returnType));
assertThat(methodDescription.getParameters().size(), is(1));
assertThat(methodDescription.getParameters().asTypeList(), is(Collections.singletonList(parameterType)));
assertThat(methodDescription.getExceptionTypes().size(), is(0));
assertThat(methodDescription.getModifiers(), is(Opcodes.ACC_PUBLIC));
assertThat(methodDescription.getName(), is(BAR));
assertThat(methodDescription.getDeclaringType(), sameInstance((TypeDescription) instrumentedType));
}
@Test
public void testWithMethodOfInstrumentedType() throws Exception {
InstrumentedType instrumentedType = makePlainInstrumentedType();
assertThat(instrumentedType.getDeclaredFields().size(), is(0));
instrumentedType = instrumentedType.withMethod(new MethodDescription.Token(BAR,
Opcodes.ACC_PUBLIC,
TargetType.DESCRIPTION.asGenericType(),
Collections.singletonList(TargetType.DESCRIPTION.asGenericType())));
assertThat(instrumentedType.getDeclaredMethods().size(), is(1));
MethodDescription.InDefinedShape methodDescription = instrumentedType.getDeclaredMethods().get(0);
assertThat(methodDescription.getReturnType().asErasure(), sameInstance((TypeDescription) instrumentedType));
assertThat(methodDescription.getParameters().size(), is(1));
assertThat(methodDescription.getParameters().asTypeList().get(0).asErasure(), sameInstance((TypeDescription) instrumentedType));
assertThat(methodDescription.getExceptionTypes().size(), is(0));
assertThat(methodDescription.getModifiers(), is(Opcodes.ACC_PUBLIC));
assertThat(methodDescription.getName(), is(BAR));
assertThat(methodDescription.getDeclaringType(), sameInstance((TypeDescription) instrumentedType));
}
@Test
public void testWithMethodOfInstrumentedTypeAsArray() throws Exception {
InstrumentedType instrumentedType = makePlainInstrumentedType();
assertThat(instrumentedType.getDeclaredFields().size(), is(0));
instrumentedType = instrumentedType.withMethod(new MethodDescription.Token(BAR,
Opcodes.ACC_PUBLIC,
new TypeDescription.Generic.OfGenericArray.Latent(TargetType.DESCRIPTION.asGenericType(), new AnnotationSource.Explicit(annotationDescription)),
Collections.singletonList(new TypeDescription.Generic.OfGenericArray.Latent(TargetType.DESCRIPTION.asGenericType(), new AnnotationSource.Explicit(annotationDescription)))));
assertThat(instrumentedType.getDeclaredMethods().size(), is(1));
MethodDescription.InDefinedShape methodDescription = instrumentedType.getDeclaredMethods().get(0);
assertThat(methodDescription.getReturnType().asErasure().isArray(), is(true));
assertThat(methodDescription.getReturnType().getComponentType().asErasure(), sameInstance((TypeDescription) instrumentedType));
assertThat(methodDescription.getParameters().size(), is(1));
assertThat(methodDescription.getParameters().asTypeList().asErasures().get(0).isArray(), is(true));
assertThat(methodDescription.getParameters().asTypeList().get(0).getComponentType().asErasure(), sameInstance((TypeDescription) instrumentedType));
assertThat(methodDescription.getExceptionTypes().size(), is(0));
assertThat(methodDescription.getReturnType().getDeclaredAnnotations().size(), is(1));
assertThat(methodDescription.getReturnType().getDeclaredAnnotations().getOnly(), is(annotationDescription));
assertThat(methodDescription.getParameters().getOnly().getType().getDeclaredAnnotations().size(), is(1));
assertThat(methodDescription.getParameters().getOnly().getType().getDeclaredAnnotations().getOnly(), is(annotationDescription));
assertThat(methodDescription.getModifiers(), is(Opcodes.ACC_PUBLIC));
assertThat(methodDescription.getName(), is(BAR));
assertThat(methodDescription.getDeclaringType(), sameInstance((TypeDescription) instrumentedType));
}
@Test
@SuppressWarnings("unchecked")
public void testWithInterface() throws Exception {
TypeDescription.Generic interfaceType = mock(TypeDescription.Generic.class);
when(interfaceType.asGenericType()).thenReturn(interfaceType);
when(interfaceType.accept(Mockito.any(TypeDescription.Generic.Visitor.class))).thenReturn(interfaceType);
TypeDescription rawBoundType = mock(TypeDescription.class);
when(interfaceType.asErasure()).thenReturn(rawBoundType);
when(rawBoundType.getName()).thenReturn(FOO);
InstrumentedType instrumentedType = makePlainInstrumentedType();
assertThat(instrumentedType.getInterfaces().size(), is(0));
instrumentedType = instrumentedType.withInterfaces(new TypeList.Generic.Explicit(interfaceType));
assertThat(instrumentedType.getInterfaces().size(), is(1));
assertThat(instrumentedType.getInterfaces(), is(Collections.singletonList(interfaceType)));
}
@Test
public void testWithInterfaceOfInstrumentedType() throws Exception {
InstrumentedType instrumentedType = makePlainInstrumentedType();
assertThat(instrumentedType.getInterfaces().size(), is(0));
instrumentedType = instrumentedType.withInterfaces(new TypeList.Generic.Explicit(TargetType.DESCRIPTION));
assertThat(instrumentedType.getInterfaces().size(), is(1));
assertThat(instrumentedType.getInterfaces(), is(Collections.singletonList(instrumentedType.asGenericType())));
}
@Test
public void testWithAnnotation() throws Exception {
AnnotationDescription annotationDescription = mock(AnnotationDescription.class);
InstrumentedType instrumentedType = makePlainInstrumentedType();
assertThat(instrumentedType.getDeclaredAnnotations().size(), is(0));
instrumentedType = instrumentedType.withAnnotations(Collections.singletonList(annotationDescription));
assertThat(instrumentedType.getDeclaredAnnotations(), is(Collections.singletonList(annotationDescription)));
}
@Test
public void testWithName() throws Exception {
InstrumentedType.WithFlexibleName instrumentedType = makePlainInstrumentedType();
assertThat(instrumentedType.getName(), is(FOO + "." + BAZ));
instrumentedType = instrumentedType.withName(BAR);
assertThat(instrumentedType.getName(), is(BAR));
}
@Test
public void testModifiers() throws Exception {
InstrumentedType instrumentedType = makePlainInstrumentedType();
assertThat(instrumentedType.getModifiers(), is(ModifierContributor.EMPTY_MASK));
instrumentedType = instrumentedType.withModifiers(OTHER_MODIFIERS);
assertThat(instrumentedType.getModifiers(), is(OTHER_MODIFIERS));
}
@Test
public void testWithLoadedTypeInitializerInitial() throws Exception {
LoadedTypeInitializer loadedTypeInitializer = makePlainInstrumentedType().getLoadedTypeInitializer();
assertThat(loadedTypeInitializer.isAlive(), is(false));
}
@Test
public void testWithLoadedTypeInitializerSingle() throws Exception {
InstrumentedType instrumentedType = makePlainInstrumentedType();
assertThat(instrumentedType.getDeclaredFields().size(), is(0));
LoadedTypeInitializer loadedTypeInitializer = mock(LoadedTypeInitializer.class);
instrumentedType = instrumentedType.withInitializer(loadedTypeInitializer);
assertThat(instrumentedType.getLoadedTypeInitializer(),
is((LoadedTypeInitializer) new LoadedTypeInitializer.Compound(LoadedTypeInitializer.NoOp.INSTANCE, loadedTypeInitializer)));
}
@Test
public void testWithLoadedTypeInitializerDouble() throws Exception {
InstrumentedType instrumentedType = makePlainInstrumentedType();
assertThat(instrumentedType.getDeclaredFields().size(), is(0));
LoadedTypeInitializer first = mock(LoadedTypeInitializer.class), second = mock(LoadedTypeInitializer.class);
instrumentedType = instrumentedType.withInitializer(first).withInitializer(second);
assertThat(instrumentedType.getLoadedTypeInitializer(),
is((LoadedTypeInitializer) new LoadedTypeInitializer.Compound(new LoadedTypeInitializer
.Compound(LoadedTypeInitializer.NoOp.INSTANCE, first), second)));
}
@Test
public void testWithTypeInitializerInitial() throws Exception {
TypeInitializer typeInitializer = makePlainInstrumentedType().getTypeInitializer();
assertThat(typeInitializer.isDefined(), is(false));
}
@Test
public void testWithTypeInitializerSingle() throws Exception {
InstrumentedType instrumentedType = makePlainInstrumentedType();
assertThat(instrumentedType.getDeclaredFields().size(), is(0));
ByteCodeAppender byteCodeAppender = mock(ByteCodeAppender.class);
instrumentedType = instrumentedType.withInitializer(byteCodeAppender);
TypeInitializer typeInitializer = instrumentedType.getTypeInitializer();
assertThat(typeInitializer.isDefined(), is(true));
MethodDescription methodDescription = mock(MethodDescription.class);
typeInitializer.apply(methodVisitor, implementationContext, methodDescription);
verify(byteCodeAppender).apply(methodVisitor, implementationContext, methodDescription);
}
@Test
public void testWithTypeInitializerDouble() throws Exception {
InstrumentedType instrumentedType = makePlainInstrumentedType();
assertThat(instrumentedType.getDeclaredFields().size(), is(0));
ByteCodeAppender first = mock(ByteCodeAppender.class), second = mock(ByteCodeAppender.class);
MethodDescription methodDescription = mock(MethodDescription.class);
when(first.apply(methodVisitor, implementationContext, methodDescription)).thenReturn(new ByteCodeAppender.Size(0, 0));
when(second.apply(methodVisitor, implementationContext, methodDescription)).thenReturn(new ByteCodeAppender.Size(0, 0));
instrumentedType = instrumentedType.withInitializer(first).withInitializer(second);
TypeInitializer typeInitializer = instrumentedType.getTypeInitializer();
assertThat(typeInitializer.isDefined(), is(true));
typeInitializer.apply(methodVisitor, implementationContext, methodDescription);
verify(first).apply(methodVisitor, implementationContext, methodDescription);
verify(second).apply(methodVisitor, implementationContext, methodDescription);
}
@Test
public void testGetStackSize() throws Exception {
assertThat(makePlainInstrumentedType().getStackSize(), is(StackSize.SINGLE));
}
@Test
public void testHashCode() throws Exception {
InstrumentedType instrumentedType = makePlainInstrumentedType();
assertThat(instrumentedType.hashCode(), is(instrumentedType.getName().hashCode()));
}
@Test
public void testEquals() throws Exception {
InstrumentedType instrumentedType = makePlainInstrumentedType();
TypeDescription other = mock(TypeDescription.class);
when(other.getName()).thenReturn(instrumentedType.getName());
when(other.getSort()).thenReturn(TypeDefinition.Sort.NON_GENERIC);
when(other.asErasure()).thenReturn(other);
assertThat(instrumentedType, is(other));
verify(other, atLeast(1)).getName();
}
@Test
public void testIsAssignableFrom() {
assertThat(makePlainInstrumentedType().isAssignableFrom(Object.class), is(false));
assertThat(makePlainInstrumentedType().isAssignableFrom(Serializable.class), is(false));
assertThat(makePlainInstrumentedType().isAssignableFrom(Integer.class), is(false));
TypeDescription objectTypeDescription = TypeDescription.OBJECT;
assertThat(makePlainInstrumentedType().isAssignableFrom(objectTypeDescription), is(false));
TypeDescription serializableTypeDescription = new TypeDescription.ForLoadedType(Serializable.class);
assertThat(makePlainInstrumentedType().isAssignableFrom(serializableTypeDescription), is(false));
TypeDescription integerTypeDescription = new TypeDescription.ForLoadedType(Integer.class);
assertThat(makePlainInstrumentedType().isAssignableFrom(integerTypeDescription), is(false));
}
@Test
public void testIsAssignableTo() {
assertThat(makePlainInstrumentedType().isAssignableTo(Object.class), is(true));
assertThat(makePlainInstrumentedType().isAssignableTo(makePlainInstrumentedType()), is(true));
assertThat(makePlainInstrumentedType().isAssignableTo(Integer.class), is(false));
assertThat(makePlainInstrumentedType().isAssignableTo(TypeDescription.OBJECT), is(true));
}
@Test
public void testRepresents() {
assertThat(makePlainInstrumentedType().represents(Object.class), is(false));
assertThat(makePlainInstrumentedType().represents(Serializable.class), is(false));
assertThat(makePlainInstrumentedType().represents(Integer.class), is(false));
}
@Test
public void testSuperClass() {
assertThat(makePlainInstrumentedType().getSuperClass(), is(TypeDescription.Generic.OBJECT));
assertThat(makePlainInstrumentedType().getSuperClass(), not((TypeDescription.Generic) new TypeDescription.Generic.OfNonGenericType.ForLoadedType(Integer.class)));
assertThat(makePlainInstrumentedType().getSuperClass(), not((TypeDescription.Generic) new TypeDescription.Generic.OfNonGenericType.ForLoadedType(Serializable.class)));
}
@Test
public void testInterfaces() {
assertThat(makePlainInstrumentedType().getInterfaces().size(), is(0));
}
@Test
public void testPackage() {
assertThat(makePlainInstrumentedType().getPackage().getName(), is(FOO));
}
@Test
public void testSimpleName() {
assertThat(makePlainInstrumentedType().getSimpleName(), is(BAZ));
}
@Test
public void testEnclosingMethod() throws Exception {
assertThat(makePlainInstrumentedType().getEnclosingMethod(), nullValue());
}
@Test
public void testEnclosingType() throws Exception {
assertThat(makePlainInstrumentedType().getEnclosingType(), nullValue());
}
@Test
public void testDeclaringType() throws Exception {
assertThat(makePlainInstrumentedType().getDeclaringType(), nullValue());
}
@Test
public void testIsAnonymous() throws Exception {
assertThat(makePlainInstrumentedType().isAnonymousClass(), is(false));
}
@Test
public void testCanonicalName() throws Exception {
TypeDescription typeDescription = makePlainInstrumentedType();
assertThat(typeDescription.getCanonicalName(), is(typeDescription.getName()));
}
@Test
public void testIsMemberClass() throws Exception {
assertThat(makePlainInstrumentedType().isMemberClass(), is(false));
}
@Test
public void testDeclaredTypes() throws Exception {
assertThat(makePlainInstrumentedType().getDeclaredTypes().size(), is(0));
}
@Test
public void testFieldTokenIsVisited() throws Exception {
FieldDescription.Token token = mock(FieldDescription.Token.class);
InstrumentedType instrumentedType = makePlainInstrumentedType();
assertThat(instrumentedType.withField(token), is(instrumentedType));
verify(token).accept(TypeDescription.Generic.Visitor.Substitutor.ForDetachment.of(instrumentedType));
verifyNoMoreInteractions(token);
}
@Test
public void testMethodTokenIsVisited() throws Exception {
MethodDescription.Token token = mock(MethodDescription.Token.class);
InstrumentedType instrumentedType = makePlainInstrumentedType();
assertThat(instrumentedType.withMethod(token), is(instrumentedType));
verify(token).accept(TypeDescription.Generic.Visitor.Substitutor.ForDetachment.of(instrumentedType));
verifyNoMoreInteractions(token);
}
@Test
public void testTypeVariableIsVisited() throws Exception {
TypeVariableToken token = mock(TypeVariableToken.class);
InstrumentedType instrumentedType = makePlainInstrumentedType();
assertThat(instrumentedType.withTypeVariable(token), is(instrumentedType));
verify(token).accept(TypeDescription.Generic.Visitor.Substitutor.ForDetachment.of(instrumentedType));
verifyNoMoreInteractions(token);
}
@Test
@SuppressWarnings("unchecked")
public void testInterfaceTypesVisited() throws Exception {
TypeDescription.Generic typeDescription = mock(TypeDescription.Generic.class);
when(typeDescription.asGenericType()).thenReturn(typeDescription);
when(typeDescription.accept(Mockito.any(TypeDescription.Generic.Visitor.class))).thenReturn(typeDescription);
InstrumentedType instrumentedType = makePlainInstrumentedType();
assertThat(instrumentedType.withInterfaces(new TypeList.Generic.Explicit(typeDescription)), is(instrumentedType));
verify(typeDescription).accept(TypeDescription.Generic.Visitor.Substitutor.ForDetachment.of(instrumentedType));
verify(typeDescription, times(2)).asGenericType();
verifyNoMoreInteractions(typeDescription);
}
@Test(expected = IllegalStateException.class)
public void testTypeIllegalName() throws Exception {
makePlainInstrumentedType().withName(ILLEGAL_NAME).validated();
}
@Test(expected = IllegalStateException.class)
public void testTypeIllegalEndName() throws Exception {
makePlainInstrumentedType().withName(FOO + ILLEGAL_NAME).validated();
}
@Test(expected = IllegalStateException.class)
public void testTypeEmptyEndName() throws Exception {
makePlainInstrumentedType().withName(NamedElement.EMPTY_NAME).validated();
}
@Test(expected = IllegalStateException.class)
public void testTypeChainedEmptyEndName() throws Exception {
makePlainInstrumentedType().withName("." + FOO).validated();
}
@Test(expected = IllegalStateException.class)
public void testTypeIllegalKeywordName() throws Exception {
makePlainInstrumentedType().withName(void.class.getName()).validated();
}
@Test(expected = IllegalStateException.class)
public void testTypeIllegalSubType() throws Exception {
InstrumentedType.Factory.Default.MODIFIABLE.subclass(FOO, ModifierContributor.EMPTY_MASK, TypeDefinition.Sort.describe(Serializable.class)).validated();
}
@Test(expected = IllegalStateException.class)
public void testTypeInvisibleSubType() throws Exception {
InstrumentedType.Factory.Default.MODIFIABLE.subclass(FOO, ModifierContributor.EMPTY_MASK, TypeDefinition.Sort.describe(PackagePrivateType.TYPE)).validated();
}
@Test(expected = IllegalStateException.class)
public void testTypeIllegalModifiers() throws Exception {
InstrumentedType.Factory.Default.MODIFIABLE.subclass(FOO, ILLEGAL_MODIFIERS, TypeDefinition.Sort.describe(Object.class)).validated();
}
@Test(expected = IllegalStateException.class)
public void testPackageTypeIllegalModifiers() throws Exception {
InstrumentedType.Factory.Default.MODIFIABLE.subclass(FOO + "." + PackageDescription.PACKAGE_CLASS_NAME, ModifierContributor.EMPTY_MASK, TypeDefinition.Sort.describe(Object.class))
.validated();
}
@Test(expected = IllegalStateException.class)
public void testTypeIllegalInterfaceType() throws Exception {
makePlainInstrumentedType().withInterfaces(new TypeList.Generic.Explicit(TypeDescription.Generic.OBJECT)).validated();
}
@Test(expected = IllegalStateException.class)
public void testInvisibleInterfaceType() throws Exception {
makePlainInstrumentedType().withInterfaces(new TypeList.Generic.Explicit(TypeDefinition.Sort.describe(PackagePrivateType.INTERFACE_TYPE))).validated();
}
@Test(expected = IllegalStateException.class)
public void testTypeDuplicateInterface() throws Exception {
makePlainInstrumentedType().withInterfaces(new TypeList.Generic.Explicit(
new TypeDescription.ForLoadedType(Serializable.class),
new TypeDescription.ForLoadedType(Serializable.class)
)).validated();
}
@Test(expected = IllegalStateException.class)
public void testTypeThrowableWithGenerics() throws Exception {
InstrumentedType.Factory.Default.MODIFIABLE.represent(new TypeDescription.ForLoadedType(Exception.class))
.withTypeVariable(new TypeVariableToken(FOO, Collections.singletonList(TypeDescription.Generic.OBJECT)))
.validated();
}
@Test(expected = IllegalStateException.class)
public void testTypeDuplicateTypeVariableName() throws Exception {
makePlainInstrumentedType()
.withTypeVariable(new TypeVariableToken(FOO, Collections.singletonList(TypeDescription.Generic.OBJECT)))
.withTypeVariable(new TypeVariableToken(FOO, Collections.singletonList(TypeDescription.Generic.OBJECT)))
.validated();
}
@Test(expected = IllegalStateException.class)
public void testTypeTypeVariableIllegalName() throws Exception {
makePlainInstrumentedType()
.withTypeVariable(new TypeVariableToken(ILLEGAL_NAME, Collections.singletonList(TypeDescription.Generic.OBJECT)))
.validated();
}
@Test(expected = IllegalStateException.class)
public void testTypeTypeVariableMissingBound() throws Exception {
makePlainInstrumentedType()
.withTypeVariable(new TypeVariableToken(FOO, Collections.<TypeDescription.Generic>emptyList()))
.validated();
}
@Test(expected = IllegalStateException.class)
public void testTypeTypeVariableDuplicateBound() throws Exception {
makePlainInstrumentedType()
.withTypeVariable(new TypeVariableToken(FOO, Arrays.asList(TypeDescription.Sort.describe(Serializable.class), TypeDefinition.Sort.describe(Serializable.class))))
.validated();
}
@Test(expected = IllegalStateException.class)
public void testTypeTypeVariableIllegalBound() throws Exception {
makePlainInstrumentedType()
.withTypeVariable(new TypeVariableToken(FOO, Collections.singletonList(TypeDescription.Generic.VOID)))
.validated();
}
@Test(expected = IllegalStateException.class)
public void testTypeTypeVariableDoubleClassBound() throws Exception {
makePlainInstrumentedType()
.withTypeVariable(new TypeVariableToken(FOO, Arrays.asList(TypeDescription.Generic.OBJECT, TypeDefinition.Sort.describe(String.class))))
.validated();
}
@Test(expected = IllegalStateException.class)
public void testTypeDuplicateAnnotation() throws Exception {
makePlainInstrumentedType()
.withAnnotations(Arrays.asList(
AnnotationDescription.Builder.ofType(SampleAnnotation.class).build(),
AnnotationDescription.Builder.ofType(SampleAnnotation.class).build()
)).validated();
}
@Test(expected = IllegalStateException.class)
public void testTypeIncompatibleAnnotation() throws Exception {
makePlainInstrumentedType()
.withAnnotations(Collections.singletonList(AnnotationDescription.Builder.ofType(IncompatibleAnnotation.class).build()))
.validated();
}
@Test(expected = IllegalStateException.class)
public void testPackageIncompatibleAnnotation() throws Exception {
makePlainInstrumentedType()
.withName(FOO + "." + PackageDescription.PACKAGE_CLASS_NAME)
.withAnnotations(Collections.singletonList(AnnotationDescription.Builder.ofType(IncompatibleAnnotation.class).build()))
.validated();
}
@Test(expected = IllegalStateException.class)
public void testAnnotationTypeIncompatibleAnnotation() throws Exception {
makePlainInstrumentedType()
.withModifiers(Opcodes.ACC_ANNOTATION | Opcodes.ACC_ABSTRACT)
.withAnnotations(Collections.singletonList(AnnotationDescription.Builder.ofType(IncompatibleAnnotation.class).build()))
.validated();
}
@Test(expected = IllegalStateException.class)
public void testAnnotationTypeIncompatibleSuperClassTypeAnnotation() throws Exception {
InstrumentedType.Factory.Default.MODIFIABLE.subclass(FOO, ModifierReviewable.EMPTY_MASK, TypeDescription.Generic.Builder.rawType(Object.class)
.build(AnnotationDescription.Builder.ofType(IncompatibleAnnotation.class).build()))
.validated();
}
@Test(expected = IllegalStateException.class)
public void testAnnotationTypeIncompatibleInterfaceTypeAnnotation() throws Exception {
makePlainInstrumentedType()
.withInterfaces(new TypeList.Generic.Explicit(TypeDescription.Generic.Builder.rawType(Runnable.class)
.build(AnnotationDescription.Builder.ofType(IncompatibleAnnotation.class).build())))
.validated();
}
@Test(expected = IllegalStateException.class)
public void testAnnotationTypeIncompatibleTypeVariableTypeAnnotation() throws Exception {
makePlainInstrumentedType()
.withTypeVariable(new TypeVariableToken(FOO,
Collections.singletonList(TypeDescription.Generic.OBJECT),
Collections.singletonList(AnnotationDescription.Builder.ofType(IncompatibleAnnotation.class).build())))
.validated();
}
@Test(expected = IllegalStateException.class)
public void testAnnotationTypeIncompatibleTypeVariableBoundTypeAnnotation() throws Exception {
makePlainInstrumentedType()
.withTypeVariable(new TypeVariableToken(FOO,
Collections.singletonList(TypeDescription.Generic.Builder.rawType(Object.class)
.build(AnnotationDescription.Builder.ofType(IncompatibleAnnotation.class).build()))))
.validated();
}
@Test(expected = IllegalStateException.class)
public void testFieldDuplicateName() throws Exception {
makePlainInstrumentedType()
.withField(new FieldDescription.Token(FOO, ModifierContributor.EMPTY_MASK, TypeDescription.Generic.OBJECT))
.withField(new FieldDescription.Token(FOO, ModifierContributor.EMPTY_MASK, TypeDescription.Generic.OBJECT))
.validated();
}
@Test(expected = IllegalStateException.class)
public void testFieldIllegalName() throws Exception {
makePlainInstrumentedType().withField(new FieldDescription.Token(ILLEGAL_NAME, ModifierContributor.EMPTY_MASK, TypeDescription.Generic.OBJECT)).validated();
}
@Test(expected = IllegalStateException.class)
public void testFieldIllegalModifiers() throws Exception {
makePlainInstrumentedType().withField(new FieldDescription.Token(FOO, ILLEGAL_MODIFIERS, TypeDescription.Generic.OBJECT)).validated();
}
@Test(expected = IllegalStateException.class)
public void testFieldIllegalType() throws Exception {
makePlainInstrumentedType().withField(new FieldDescription.Token(ILLEGAL_NAME, ModifierContributor.EMPTY_MASK, TypeDescription.Generic.VOID)).validated();
}
@Test(expected = IllegalStateException.class)
public void testFieldInvisibleType() throws Exception {
makePlainInstrumentedType()
.withField(new FieldDescription.Token(FOO, ModifierContributor.EMPTY_MASK, TypeDefinition.Sort.describe(PackagePrivateType.TYPE)))
.validated();
}
@Test(expected = IllegalStateException.class)
public void tesFieldDuplicateAnnotation() throws Exception {
makePlainInstrumentedType()
.withField(new FieldDescription.Token(FOO, ModifierContributor.EMPTY_MASK, TypeDescription.Generic.OBJECT, Arrays.asList(
AnnotationDescription.Builder.ofType(SampleAnnotation.class).build(),
AnnotationDescription.Builder.ofType(SampleAnnotation.class).build()
))).validated();
}
@Test(expected = IllegalStateException.class)
public void tesFieldIncompatibleAnnotation() throws Exception {
makePlainInstrumentedType()
.withField(new FieldDescription.Token(FOO, ModifierContributor.EMPTY_MASK, TypeDescription.Generic.OBJECT, Collections.singletonList(
AnnotationDescription.Builder.ofType(IncompatibleAnnotation.class).build()
))).validated();
}
@Test(expected = IllegalStateException.class)
public void testFieldIncompatibleTypeAnnotation() throws Exception {
makePlainInstrumentedType()
.withField(new FieldDescription.Token(FOO,
ModifierContributor.EMPTY_MASK,
TypeDescription.Generic.Builder.rawType(Runnable.class)
.build(AnnotationDescription.Builder.ofType(IncompatibleAnnotation.class).build())))
.validated();
}
@Test(expected = IllegalStateException.class)
public void testMethodDuplicateErasure() throws Exception {
makePlainInstrumentedType()
.withMethod(new MethodDescription.Token(FOO, ModifierContributor.EMPTY_MASK, TypeDescription.Generic.OBJECT))
.withMethod(new MethodDescription.Token(FOO, ModifierContributor.EMPTY_MASK, TypeDescription.Generic.OBJECT))
.validated();
}
@Test(expected = IllegalStateException.class)
public void testMethodTypeInitializer() throws Exception {
makePlainInstrumentedType()
.withMethod(new MethodDescription.Token(MethodDescription.TYPE_INITIALIZER_INTERNAL_NAME, ModifierContributor.EMPTY_MASK, TypeDescription.Generic.VOID))
.validated();
}
@Test(expected = IllegalStateException.class)
public void testConstructorNonVoidReturnType() throws Exception {
makePlainInstrumentedType()
.withMethod(new MethodDescription.Token(MethodDescription.CONSTRUCTOR_INTERNAL_NAME, ModifierContributor.EMPTY_MASK, TypeDescription.Generic.OBJECT))
.validated();
}
@Test(expected = IllegalStateException.class)
public void testMethodInvisibleReturnType() throws Exception {
makePlainInstrumentedType()
.withMethod(new MethodDescription.Token(FOO, ModifierContributor.EMPTY_MASK, TypeDefinition.Sort.describe(PackagePrivateType.TYPE)))
.validated();
}
@Test
public void testMethodInvisibleReturnTypeSynthetic() throws Exception {
assertThat(makePlainInstrumentedType()
.withMethod(new MethodDescription.Token(FOO, Opcodes.ACC_SYNTHETIC, TypeDefinition.Sort.describe(PackagePrivateType.TYPE)))
.validated(), instanceOf(TypeDescription.class));
}
@Test(expected = IllegalStateException.class)
public void testMethodIllegalName() throws Exception {
makePlainInstrumentedType().withMethod(new MethodDescription.Token(ILLEGAL_NAME, ModifierContributor.EMPTY_MASK, TypeDescription.Generic.OBJECT)).validated();
}
@Test(expected = IllegalStateException.class)
public void testMethodIllegalModifiers() throws Exception {
makePlainInstrumentedType().withMethod(new MethodDescription.Token(FOO, ILLEGAL_MODIFIERS, TypeDescription.Generic.OBJECT)).validated();
}
@Test(expected = IllegalStateException.class)
public void testMethodDuplicateAnnotation() throws Exception {
makePlainInstrumentedType()
.withMethod(new MethodDescription.Token(FOO,
ModifierContributor.EMPTY_MASK,
Collections.<TypeVariableToken>emptyList(),
TypeDescription.Generic.OBJECT,
Collections.<ParameterDescription.Token>emptyList(),
Collections.<TypeDescription.Generic>emptyList(),
Arrays.asList(
AnnotationDescription.Builder.ofType(SampleAnnotation.class).build(),
AnnotationDescription.Builder.ofType(SampleAnnotation.class).build()
), AnnotationValue.UNDEFINED,
TypeDescription.Generic.UNDEFINED))
.validated();
}
@Test(expected = IllegalStateException.class)
public void testMethodIncompatibleAnnotation() throws Exception {
makePlainInstrumentedType()
.withMethod(new MethodDescription.Token(FOO,
ModifierContributor.EMPTY_MASK,
Collections.<TypeVariableToken>emptyList(),
TypeDescription.Generic.OBJECT,
Collections.<ParameterDescription.Token>emptyList(),
Collections.<TypeDescription.Generic>emptyList(),
Collections.singletonList(AnnotationDescription.Builder.ofType(IncompatibleAnnotation.class).build()),
AnnotationValue.UNDEFINED,
TypeDescription.Generic.UNDEFINED))
.validated();
}
@Test(expected = IllegalStateException.class)
public void testMethodIncompatibleReturnTypeTypeAnnotation() throws Exception {
makePlainInstrumentedType()
.withMethod(new MethodDescription.Token(FOO,
ModifierContributor.EMPTY_MASK,
TypeDescription.Generic.Builder.rawType(Runnable.class)
.build(AnnotationDescription.Builder.ofType(IncompatibleAnnotation.class).build())))
.validated();
}
@Test(expected = IllegalStateException.class)
public void testMethodIllegalTypeVariableTypeAnnotation() throws Exception {
makePlainInstrumentedType()
.withMethod(new MethodDescription.Token(FOO,
ModifierContributor.EMPTY_MASK,
Collections.singletonList(new TypeVariableToken(FOO,
Collections.singletonList(TypeDescription.Generic.OBJECT),
Collections.singletonList(AnnotationDescription.Builder.ofType(IncompatibleAnnotation.class).build()))),
TypeDescription.Generic.OBJECT,
Collections.<ParameterDescription.Token>emptyList(),
Collections.<TypeDescription.Generic>emptyList(),
Collections.<AnnotationDescription>emptyList(),
AnnotationValue.UNDEFINED,
TypeDescription.Generic.UNDEFINED))
.validated();
}
@Test(expected = IllegalStateException.class)
public void testMethodIllegalTypeVariableBoundTypeAnnotation() throws Exception {
makePlainInstrumentedType()
.withMethod(new MethodDescription.Token(FOO,
ModifierContributor.EMPTY_MASK,
Collections.singletonList(new TypeVariableToken(FOO,
Collections.singletonList(TypeDescription.Generic.Builder.rawType(Object.class).build(
AnnotationDescription.Builder.ofType(IncompatibleAnnotation.class).build())))),
TypeDescription.Generic.OBJECT,
Collections.<ParameterDescription.Token>emptyList(),
Collections.<TypeDescription.Generic>emptyList(),
Collections.<AnnotationDescription>emptyList(),
AnnotationValue.UNDEFINED,
TypeDescription.Generic.UNDEFINED))
.validated();
}
@Test(expected = IllegalStateException.class)
public void testMethodIllegalTypeVariableName() throws Exception {
makePlainInstrumentedType()
.withMethod(new MethodDescription.Token(FOO,
ModifierContributor.EMPTY_MASK,
Collections.singletonList(new TypeVariableToken(ILLEGAL_NAME, Collections.singletonList(TypeDescription.Generic.OBJECT))),
TypeDescription.Generic.OBJECT,
Collections.<ParameterDescription.Token>emptyList(),
Collections.<TypeDescription.Generic>emptyList(),
Collections.<AnnotationDescription>emptyList(),
AnnotationValue.UNDEFINED,
TypeDescription.Generic.UNDEFINED))
.validated();
}
@Test(expected = IllegalStateException.class)
public void testMethodDuplicateTypeVariableName() throws Exception {
makePlainInstrumentedType()
.withMethod(new MethodDescription.Token(FOO,
ModifierContributor.EMPTY_MASK,
Arrays.asList(
new TypeVariableToken(FOO, Collections.singletonList(TypeDescription.Generic.OBJECT)),
new TypeVariableToken(FOO, Collections.singletonList(TypeDescription.Generic.OBJECT))
),
TypeDescription.Generic.OBJECT,
Collections.<ParameterDescription.Token>emptyList(),
Collections.<TypeDescription.Generic>emptyList(),
Collections.<AnnotationDescription>emptyList(),
AnnotationValue.UNDEFINED,
TypeDescription.Generic.UNDEFINED))
.validated();
}
@Test(expected = IllegalStateException.class)
public void testMethodTypeVariableMissingBound() throws Exception {
makePlainInstrumentedType()
.withMethod(new MethodDescription.Token(FOO,
ModifierContributor.EMPTY_MASK,
Collections.singletonList(new TypeVariableToken(FOO, Collections.<TypeDescription.Generic>emptyList())),
TypeDescription.Generic.OBJECT,
Collections.<ParameterDescription.Token>emptyList(),
Collections.<TypeDescription.Generic>emptyList(),
Collections.<AnnotationDescription>emptyList(),
AnnotationValue.UNDEFINED,
TypeDescription.Generic.UNDEFINED))
.validated();
}
@Test(expected = IllegalStateException.class)
public void testMethodTypeVariableIllegalBound() throws Exception {
makePlainInstrumentedType()
.withMethod(new MethodDescription.Token(FOO,
ModifierContributor.EMPTY_MASK,
Collections.singletonList(new TypeVariableToken(FOO, Collections.singletonList(TypeDescription.Generic.VOID))),
TypeDescription.Generic.OBJECT,
Collections.<ParameterDescription.Token>emptyList(),
Collections.<TypeDescription.Generic>emptyList(),
Collections.<AnnotationDescription>emptyList(),
AnnotationValue.UNDEFINED,
TypeDescription.Generic.UNDEFINED))
.validated();
}
@Test(expected = IllegalStateException.class)
public void testMethodTypeVariableDuplicateBound() throws Exception {
makePlainInstrumentedType()
.withMethod(new MethodDescription.Token(FOO,
ModifierContributor.EMPTY_MASK,
Collections.singletonList(new TypeVariableToken(FOO, Arrays.asList(TypeDefinition.Sort.describe(Serializable.class),
TypeDefinition.Sort.describe(Serializable.class)))),
TypeDescription.Generic.OBJECT,
Collections.<ParameterDescription.Token>emptyList(),
Collections.<TypeDescription.Generic>emptyList(),
Collections.<AnnotationDescription>emptyList(),
AnnotationValue.UNDEFINED,
TypeDescription.Generic.UNDEFINED))
.validated();
}
@Test(expected = IllegalStateException.class)
public void testMethodTypeVariableDoubleClassBound() throws Exception {
makePlainInstrumentedType()
.withMethod(new MethodDescription.Token(FOO,
ModifierContributor.EMPTY_MASK,
Collections.singletonList(new TypeVariableToken(FOO, Arrays.asList(TypeDescription.Generic.OBJECT, TypeDefinition.Sort.describe(String.class)))),
TypeDescription.Generic.OBJECT,
Collections.<ParameterDescription.Token>emptyList(),
Collections.<TypeDescription.Generic>emptyList(),
Collections.<AnnotationDescription>emptyList(),
AnnotationValue.UNDEFINED,
TypeDescription.Generic.UNDEFINED))
.validated();
}
@Test(expected = IllegalStateException.class)
public void testMethodParameterIllegalName() throws Exception {
makePlainInstrumentedType()
.withMethod(new MethodDescription.Token(FOO,
ModifierContributor.EMPTY_MASK,
Collections.<TypeVariableToken>emptyList(),
TypeDescription.Generic.OBJECT,
Collections.singletonList(new ParameterDescription.Token(TypeDescription.Generic.OBJECT, ILLEGAL_NAME, 0)),
Collections.<TypeDescription.Generic>emptyList(),
Collections.<AnnotationDescription>emptyList(),
AnnotationValue.UNDEFINED,
TypeDescription.Generic.UNDEFINED))
.validated();
}
@Test(expected = IllegalStateException.class)
public void testMethodParameterIllegalType() throws Exception {
makePlainInstrumentedType()
.withMethod(new MethodDescription.Token(FOO,
ModifierContributor.EMPTY_MASK,
Collections.<TypeVariableToken>emptyList(),
TypeDescription.Generic.OBJECT,
Collections.singletonList(new ParameterDescription.Token(TypeDescription.Generic.VOID)),
Collections.<TypeDescription.Generic>emptyList(),
Collections.<AnnotationDescription>emptyList(),
AnnotationValue.UNDEFINED,
TypeDescription.Generic.UNDEFINED))
.validated();
}
@Test(expected = IllegalStateException.class)
public void testMethodParameterInvisibleType() throws Exception {
makePlainInstrumentedType()
.withMethod(new MethodDescription.Token(FOO,
ModifierContributor.EMPTY_MASK,
Collections.<TypeVariableToken>emptyList(),
TypeDescription.Generic.OBJECT,
Collections.singletonList(new ParameterDescription.Token(TypeDefinition.Sort.describe(PackagePrivateType.TYPE))),
Collections.<TypeDescription.Generic>emptyList(),
Collections.<AnnotationDescription>emptyList(),
AnnotationValue.UNDEFINED,
TypeDescription.Generic.UNDEFINED))
.validated();
}
@Test
public void testMethodParameterInvisibleTypeSynthetic() throws Exception {
assertThat(makePlainInstrumentedType()
.withMethod(new MethodDescription.Token(FOO,
Opcodes.ACC_SYNTHETIC,
Collections.<TypeVariableToken>emptyList(),
TypeDescription.Generic.OBJECT,
Collections.singletonList(new ParameterDescription.Token(TypeDefinition.Sort.describe(PackagePrivateType.TYPE))),
Collections.<TypeDescription.Generic>emptyList(),
Collections.<AnnotationDescription>emptyList(),
AnnotationValue.UNDEFINED,
TypeDescription.Generic.UNDEFINED))
.validated(), notNullValue(TypeDescription.class));
}
@Test(expected = IllegalStateException.class)
public void testMethodParameterDuplicateName() throws Exception {
makePlainInstrumentedType()
.withMethod(new MethodDescription.Token(FOO,
ModifierContributor.EMPTY_MASK,
Collections.<TypeVariableToken>emptyList(),
TypeDescription.Generic.OBJECT,
Arrays.asList(
new ParameterDescription.Token(TypeDescription.Generic.OBJECT, FOO, 0),
new ParameterDescription.Token(TypeDescription.Generic.OBJECT, FOO, 0)
), Collections.<TypeDescription.Generic>emptyList(),
Collections.<AnnotationDescription>emptyList(),
AnnotationValue.UNDEFINED,
TypeDescription.Generic.UNDEFINED))
.validated();
}
@Test(expected = IllegalStateException.class)
public void testMethodParameterIllegalModifiers() throws Exception {
makePlainInstrumentedType()
.withMethod(new MethodDescription.Token(FOO,
ModifierContributor.EMPTY_MASK,
Collections.<TypeVariableToken>emptyList(),
TypeDescription.Generic.OBJECT,
Collections.singletonList(new ParameterDescription.Token(TypeDescription.Generic.OBJECT, FOO, -1)),
Collections.<TypeDescription.Generic>emptyList(),
Collections.<AnnotationDescription>emptyList(),
AnnotationValue.UNDEFINED,
TypeDescription.Generic.UNDEFINED))
.validated();
}
@Test(expected = IllegalStateException.class)
public void testMethodParameterDuplicateAnnotation() throws Exception {
makePlainInstrumentedType()
.withMethod(new MethodDescription.Token(FOO,
ModifierContributor.EMPTY_MASK,
Collections.<TypeVariableToken>emptyList(),
TypeDescription.Generic.OBJECT,
Collections.singletonList(new ParameterDescription.Token(TypeDescription.Generic.OBJECT, Arrays.asList(
AnnotationDescription.Builder.ofType(SampleAnnotation.class).build(),
AnnotationDescription.Builder.ofType(SampleAnnotation.class).build()
))), Collections.<TypeDescription.Generic>emptyList(),
Collections.<AnnotationDescription>emptyList(),
AnnotationValue.UNDEFINED,
TypeDescription.Generic.UNDEFINED))
.validated();
}
@Test(expected = IllegalStateException.class)
public void testMethodParameterIncompatibleAnnotation() throws Exception {
makePlainInstrumentedType()
.withMethod(new MethodDescription.Token(FOO,
ModifierContributor.EMPTY_MASK,
Collections.<TypeVariableToken>emptyList(),
TypeDescription.Generic.OBJECT,
Collections.singletonList(new ParameterDescription.Token(TypeDescription.Generic.OBJECT, Collections.singletonList(
AnnotationDescription.Builder.ofType(IncompatibleAnnotation.class).build()
))), Collections.<TypeDescription.Generic>emptyList(),
Collections.<AnnotationDescription>emptyList(),
AnnotationValue.UNDEFINED,
TypeDescription.Generic.UNDEFINED))
.validated();
}
@Test(expected = IllegalStateException.class)
public void testMethodIllegalExceptionType() throws Exception {
makePlainInstrumentedType()
.withMethod(new MethodDescription.Token(FOO,
ModifierContributor.EMPTY_MASK,
Collections.<TypeVariableToken>emptyList(),
TypeDescription.Generic.OBJECT,
Collections.<ParameterDescription.Token>emptyList(),
Collections.singletonList(TypeDescription.Generic.OBJECT),
Collections.<AnnotationDescription>emptyList(),
AnnotationValue.UNDEFINED,
TypeDescription.Generic.UNDEFINED))
.validated();
}
@Test(expected = IllegalStateException.class)
public void testMethodIncompatibleExceptionTypeTypeAnnotation() throws Exception {
makePlainInstrumentedType()
.withMethod(new MethodDescription.Token(FOO,
ModifierContributor.EMPTY_MASK,
Collections.<TypeVariableToken>emptyList(),
TypeDescription.Generic.OBJECT,
Collections.<ParameterDescription.Token>emptyList(),
Collections.singletonList(TypeDescription.Generic.Builder.rawType(Exception.class)
.build(AnnotationDescription.Builder.ofType(IncompatibleAnnotation.class).build())),
Collections.<AnnotationDescription>emptyList(),
AnnotationValue.UNDEFINED,
TypeDescription.Generic.UNDEFINED))
.validated();
}
@Test(expected = IllegalStateException.class)
public void testMethodInvisibleExceptionType() throws Exception {
makePlainInstrumentedType()
.withMethod(new MethodDescription.Token(FOO,
ModifierContributor.EMPTY_MASK,
Collections.<TypeVariableToken>emptyList(),
TypeDescription.Generic.OBJECT,
Collections.<ParameterDescription.Token>emptyList(),
Collections.singletonList(TypeDefinition.Sort.describe(PackagePrivateType.EXCEPTION_TYPE)),
Collections.<AnnotationDescription>emptyList(),
AnnotationValue.UNDEFINED,
TypeDescription.Generic.UNDEFINED))
.validated();
}
@Test
public void testMethodInvisibleExceptionSynthetic() throws Exception {
assertThat(makePlainInstrumentedType()
.withMethod(new MethodDescription.Token(FOO,
Opcodes.ACC_SYNTHETIC,
Collections.<TypeVariableToken>emptyList(),
TypeDescription.Generic.OBJECT,
Collections.<ParameterDescription.Token>emptyList(),
Collections.singletonList(TypeDefinition.Sort.describe(PackagePrivateType.EXCEPTION_TYPE)),
Collections.<AnnotationDescription>emptyList(),
AnnotationValue.UNDEFINED,
TypeDescription.Generic.UNDEFINED))
.validated(), notNullValue(TypeDescription.class));
}
@Test(expected = IllegalStateException.class)
public void testMethodDuplicateExceptionType() throws Exception {
makePlainInstrumentedType()
.withMethod(new MethodDescription.Token(FOO,
ModifierContributor.EMPTY_MASK,
Collections.<TypeVariableToken>emptyList(),
TypeDescription.Generic.OBJECT,
Collections.<ParameterDescription.Token>emptyList(),
Arrays.asList(TypeDefinition.Sort.describe(Exception.class), TypeDefinition.Sort.describe(Exception.class)),
Collections.<AnnotationDescription>emptyList(),
AnnotationValue.UNDEFINED,
TypeDescription.Generic.UNDEFINED))
.validated();
}
@Test(expected = IllegalStateException.class)
public void testMethodIllegalDefaultValue() throws Exception {
makePlainInstrumentedType()
.withMethod(new MethodDescription.Token(FOO,
ModifierContributor.EMPTY_MASK,
Collections.<TypeVariableToken>emptyList(),
TypeDescription.Generic.OBJECT,
Collections.<ParameterDescription.Token>emptyList(),
Collections.<TypeDescription.Generic>emptyList(),
Collections.<AnnotationDescription>emptyList(),
AnnotationValue.ForConstant.of(FOO),
TypeDescription.Generic.UNDEFINED))
.validated();
}
@Test(expected = IllegalStateException.class)
public void testNonNullReceiverStaticMethod() throws Exception {
makePlainInstrumentedType()
.withMethod(new MethodDescription.Token(FOO,
Opcodes.ACC_STATIC,
Collections.<TypeVariableToken>emptyList(),
TypeDescription.Generic.OBJECT,
Collections.<ParameterDescription.Token>emptyList(),
Collections.<TypeDescription.Generic>emptyList(),
Collections.<AnnotationDescription>emptyList(),
AnnotationValue.UNDEFINED,
TypeDescription.Generic.OBJECT))
.validated();
}
@Test(expected = IllegalStateException.class)
public void testInconsistentReceiverNonStaticMethod() throws Exception {
makePlainInstrumentedType()
.withMethod(new MethodDescription.Token(FOO,
ModifierContributor.EMPTY_MASK,
Collections.<TypeVariableToken>emptyList(),
TypeDescription.Generic.OBJECT,
Collections.<ParameterDescription.Token>emptyList(),
Collections.<TypeDescription.Generic>emptyList(),
Collections.<AnnotationDescription>emptyList(),
AnnotationValue.UNDEFINED,
TypeDescription.Generic.OBJECT))
.validated();
}
@Test(expected = IllegalStateException.class)
public void testInconsistentReceiverConstructor() throws Exception {
makePlainInstrumentedType()
.withMethod(new MethodDescription.Token(MethodDescription.CONSTRUCTOR_INTERNAL_NAME,
ModifierContributor.EMPTY_MASK,
Collections.<TypeVariableToken>emptyList(),
TypeDescription.Generic.OBJECT,
Collections.<ParameterDescription.Token>emptyList(),
Collections.<TypeDescription.Generic>emptyList(),
Collections.<AnnotationDescription>emptyList(),
AnnotationValue.UNDEFINED,
TypeDescription.Generic.OBJECT))
.validated();
}
@Test(expected = IllegalStateException.class)
public void testInconsistentReceiverConstructorInnerClass() throws Exception {
InstrumentedType.Factory.Default.MODIFIABLE.represent(new TypeDescription.ForLoadedType(Foo.class))
.withMethod(new MethodDescription.Token(MethodDescription.CONSTRUCTOR_INTERNAL_NAME,
ModifierContributor.EMPTY_MASK,
Collections.<TypeVariableToken>emptyList(),
TypeDescription.Generic.OBJECT,
Collections.<ParameterDescription.Token>emptyList(),
Collections.<TypeDescription.Generic>emptyList(),
Collections.<AnnotationDescription>emptyList(),
AnnotationValue.UNDEFINED,
TypeDefinition.Sort.describe(Foo.class)))
.validated();
}
@Test
public void testTypeVariableOutOfScopeIsErased() throws Exception {
TypeDescription typeDescription = new InstrumentedType.Default("foo",
Opcodes.ACC_PUBLIC,
new TypeDescription.Generic.OfNonGenericType.ForLoadedType(AbstractOuter.ExtendedInner.class),
Collections.<TypeVariableToken>emptyList(),
Collections.<TypeDescription.Generic>emptyList(),
Collections.<FieldDescription.Token>emptyList(),
Collections.singletonList(new MethodDescription.Token("foo",
Opcodes.ACC_BRIDGE,
TypeDescription.Generic.VOID,
Collections.<TypeDescription.Generic>emptyList())),
Collections.<AnnotationDescription>emptyList(),
TypeInitializer.None.INSTANCE,
LoadedTypeInitializer.NoOp.INSTANCE,
TypeDescription.UNDEFINED,
MethodDescription.UNDEFINED,
TypeDescription.UNDEFINED,
Collections.<TypeDescription>emptyList(),
false,
false,
false);
MethodDescription methodDescription = typeDescription.getSuperClass().getSuperClass().getDeclaredMethods().filter(named(FOO)).getOnly();
assertThat(methodDescription.getReturnType(), is(TypeDescription.Generic.OBJECT));
}
public @interface SampleAnnotation {
/* empty */
}
@Target({})
public @interface IncompatibleAnnotation {
/* empty */
}
private class Foo {
/* empty */
}
public static abstract class AbstractOuter<T> {
public abstract class Inner {
public abstract T foo();
}
public abstract class ExtendedInner extends Inner {
/* empty */
}
}
}