package net.bytebuddy.implementation.attribute;
import net.bytebuddy.description.annotation.AnnotationDescription;
import net.bytebuddy.description.annotation.AnnotationList;
import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.description.type.TypeList;
import net.bytebuddy.test.utility.ObjectPropertyAssertion;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.objectweb.asm.Type;
import org.objectweb.asm.TypeReference;
import java.util.Arrays;
import java.util.Random;
import static org.mockito.Mockito.*;
public class TypeAttributeAppenderForInstrumentedTypeDifferentiatingTest extends AbstractTypeAttributeAppenderTest {
@Mock
private TypeDescription.Generic pseudoType;
@Override
@Before
public void setUp() throws Exception {
super.setUp();
when(pseudoType.asGenericType()).thenReturn(pseudoType);
}
@Test
public void testAnnotationNoRetention() throws Exception {
when(instrumentedType.getTypeVariables()).thenReturn(new TypeList.Generic.Empty());
when(instrumentedType.getInterfaces()).thenReturn(new TypeList.Generic.Empty());
when(instrumentedType.getDeclaredAnnotations()).thenReturn(new AnnotationList.ForLoadedAnnotations(new Baz.Instance(), new Qux.Instance()));
new TypeAttributeAppender.ForInstrumentedType.Differentiating(1, 0, 0).apply(classVisitor, instrumentedType, annotationValueFilter);
verifyZeroInteractions(classVisitor);
verify(instrumentedType).getDeclaredAnnotations();
verify(instrumentedType).getInterfaces();
verify(instrumentedType).getTypeVariables();
verifyNoMoreInteractions(instrumentedType);
}
@Test
public void testAnnotationByteCodeRetention() throws Exception {
when(instrumentedType.getTypeVariables()).thenReturn(new TypeList.Generic.Empty());
when(instrumentedType.getInterfaces()).thenReturn(new TypeList.Generic.Empty());
when(instrumentedType.getDeclaredAnnotations()).thenReturn(new AnnotationList.ForLoadedAnnotations(new QuxBaz.Instance(), new Baz.Instance()));
new TypeAttributeAppender.ForInstrumentedType.Differentiating(1, 0, 0).apply(classVisitor, instrumentedType, annotationValueFilter);
verify(classVisitor).visitAnnotation(Type.getDescriptor(Baz.class), true);
verifyZeroInteractions(classVisitor);
verify(instrumentedType).getDeclaredAnnotations();
verify(instrumentedType).getInterfaces();
verify(instrumentedType).getTypeVariables();
verifyNoMoreInteractions(instrumentedType);
}
@Test
public void testAnnotationClassFileRetention() throws Exception {
when(instrumentedType.getTypeVariables()).thenReturn(new TypeList.Generic.Empty());
when(instrumentedType.getInterfaces()).thenReturn(new TypeList.Generic.Empty());
when(instrumentedType.getDeclaredAnnotations()).thenReturn(new AnnotationList.ForLoadedAnnotations(new Baz.Instance(), new QuxBaz.Instance()));
new TypeAttributeAppender.ForInstrumentedType.Differentiating(1, 0, 0).apply(classVisitor, instrumentedType, annotationValueFilter);
verify(classVisitor).visitAnnotation(Type.getDescriptor(QuxBaz.class), false);
verifyZeroInteractions(classVisitor);
verify(instrumentedType).getDeclaredAnnotations();
verify(instrumentedType).getInterfaces();
verify(instrumentedType).getTypeVariables();
verifyNoMoreInteractions(instrumentedType);
}
@Test
public void testInterfaceTypeAnnotationNoRetention() throws Exception {
when(instrumentedType.getTypeVariables()).thenReturn(new TypeList.Generic.Empty());
when(instrumentedType.getInterfaces()).thenReturn(new TypeList.Generic.Explicit(pseudoType, simpleAnnotatedType));
when(simpleAnnotatedType.getDeclaredAnnotations()).thenReturn(new AnnotationList.ForLoadedAnnotations(new Qux.Instance()));
when(instrumentedType.getDeclaredAnnotations()).thenReturn(new AnnotationList.Empty());
new TypeAttributeAppender.ForInstrumentedType.Differentiating(0, 0, 1).apply(classVisitor, instrumentedType, annotationValueFilter);
verifyZeroInteractions(classVisitor);
verify(instrumentedType).getDeclaredAnnotations();
verify(instrumentedType).getInterfaces();
verify(instrumentedType).getTypeVariables();
verifyNoMoreInteractions(instrumentedType);
}
@Test
public void testInterfaceTypeAnnotationRuntimeRetention() throws Exception {
when(instrumentedType.getTypeVariables()).thenReturn(new TypeList.Generic.Empty());
when(instrumentedType.getInterfaces()).thenReturn(new TypeList.Generic.Explicit(pseudoType, simpleAnnotatedType));
when(simpleAnnotatedType.getDeclaredAnnotations()).thenReturn(new AnnotationList.ForLoadedAnnotations(new Baz.Instance()));
when(instrumentedType.getDeclaredAnnotations()).thenReturn(new AnnotationList.Empty());
new TypeAttributeAppender.ForInstrumentedType.Differentiating(0, 0, 1).apply(classVisitor, instrumentedType, annotationValueFilter);
verify(classVisitor).visitTypeAnnotation(TypeReference.newSuperTypeReference(1).getValue(), null, Type.getDescriptor(Baz.class), true);
verifyNoMoreInteractions(classVisitor);
verify(instrumentedType).getDeclaredAnnotations();
verify(instrumentedType).getInterfaces();
verify(instrumentedType).getTypeVariables();
verifyNoMoreInteractions(instrumentedType);
}
@Test
public void testInterfaceTypeAnnotations() throws Exception {
when(instrumentedType.getTypeVariables()).thenReturn(new TypeList.Generic.Empty());
when(instrumentedType.getInterfaces()).thenReturn(new TypeList.Generic.Explicit(pseudoType, simpleAnnotatedType));
when(simpleAnnotatedType.getDeclaredAnnotations()).thenReturn(new AnnotationList.ForLoadedAnnotations(new QuxBaz.Instance()));
when(instrumentedType.getDeclaredAnnotations()).thenReturn(new AnnotationList.Empty());
new TypeAttributeAppender.ForInstrumentedType.Differentiating(0, 0, 1).apply(classVisitor, instrumentedType, annotationValueFilter);
verify(classVisitor).visitTypeAnnotation(TypeReference.newSuperTypeReference(1).getValue(), null, Type.getDescriptor(QuxBaz.class), false);
verifyNoMoreInteractions(classVisitor);
verify(instrumentedType).getDeclaredAnnotations();
verify(instrumentedType).getInterfaces();
verify(instrumentedType).getTypeVariables();
verifyNoMoreInteractions(instrumentedType);
}
@Test
public void testTypeVariableTypeAnnotationNoRetention() throws Exception {
when(instrumentedType.getTypeVariables()).thenReturn(new TypeList.Generic.Explicit(pseudoType, annotatedTypeVariable));
when(annotatedTypeVariable.getDeclaredAnnotations()).thenReturn(new AnnotationList.ForLoadedAnnotations(new Qux.Instance()));
when(annotatedTypeVariableBound.getDeclaredAnnotations()).thenReturn(new AnnotationList.ForLoadedAnnotations(new Qux.Instance()));
when(instrumentedType.getInterfaces()).thenReturn(new TypeList.Generic.Empty());
when(instrumentedType.getDeclaredAnnotations()).thenReturn(new AnnotationList.Empty());
new TypeAttributeAppender.ForInstrumentedType.Differentiating(0, 1, 0).apply(classVisitor, instrumentedType, annotationValueFilter);
verifyZeroInteractions(classVisitor);
verify(instrumentedType).getDeclaredAnnotations();
verify(instrumentedType).getInterfaces();
verify(instrumentedType).getTypeVariables();
verifyNoMoreInteractions(instrumentedType);
}
@Test
public void testTypeVariableTypeAnnotationRuntimeRetention() throws Exception {
when(instrumentedType.getTypeVariables()).thenReturn(new TypeList.Generic.Explicit(pseudoType, annotatedTypeVariable));
when(annotatedTypeVariable.getDeclaredAnnotations()).thenReturn(new AnnotationList.ForLoadedAnnotations(new Baz.Instance()));
when(annotatedTypeVariableBound.getDeclaredAnnotations()).thenReturn(new AnnotationList.ForLoadedAnnotations(new Baz.Instance()));
when(instrumentedType.getInterfaces()).thenReturn(new TypeList.Generic.Empty());
when(instrumentedType.getDeclaredAnnotations()).thenReturn(new AnnotationList.Empty());
new TypeAttributeAppender.ForInstrumentedType.Differentiating(0, 1, 0).apply(classVisitor, instrumentedType, annotationValueFilter);
verify(classVisitor).visitTypeAnnotation(TypeReference.newTypeParameterReference(TypeReference.CLASS_TYPE_PARAMETER, 1).getValue(),
null,
Type.getDescriptor(Baz.class),
true);
verify(classVisitor).visitTypeAnnotation(TypeReference.newTypeParameterBoundReference(TypeReference.CLASS_TYPE_PARAMETER_BOUND, 1, 0).getValue(),
null,
Type.getDescriptor(Baz.class),
true);
verifyNoMoreInteractions(classVisitor);
verify(instrumentedType).getDeclaredAnnotations();
verify(instrumentedType).getInterfaces();
verify(instrumentedType).getTypeVariables();
verifyNoMoreInteractions(instrumentedType);
}
@Test
public void testTypeVariableTypeAnnotations() throws Exception {
when(instrumentedType.getTypeVariables()).thenReturn(new TypeList.Generic.Explicit(pseudoType, annotatedTypeVariable));
when(annotatedTypeVariable.getDeclaredAnnotations()).thenReturn(new AnnotationList.ForLoadedAnnotations(new QuxBaz.Instance()));
when(annotatedTypeVariableBound.getDeclaredAnnotations()).thenReturn(new AnnotationList.ForLoadedAnnotations(new QuxBaz.Instance()));
when(instrumentedType.getInterfaces()).thenReturn(new TypeList.Generic.Empty());
when(instrumentedType.getDeclaredAnnotations()).thenReturn(new AnnotationList.Empty());
new TypeAttributeAppender.ForInstrumentedType.Differentiating(0, 1, 0).apply(classVisitor, instrumentedType, annotationValueFilter);
verify(classVisitor).visitTypeAnnotation(TypeReference.newTypeParameterReference(TypeReference.CLASS_TYPE_PARAMETER, 1).getValue(),
null,
Type.getDescriptor(QuxBaz.class),
false);
verify(classVisitor).visitTypeAnnotation(TypeReference.newTypeParameterBoundReference(TypeReference.CLASS_TYPE_PARAMETER_BOUND, 1, 0).getValue(),
null,
Type.getDescriptor(QuxBaz.class),
false);
verifyNoMoreInteractions(classVisitor);
verify(instrumentedType).getDeclaredAnnotations();
verify(instrumentedType).getInterfaces();
verify(instrumentedType).getTypeVariables();
verifyNoMoreInteractions(instrumentedType);
}
@Test
public void testObjectProperties() throws Exception {
ObjectPropertyAssertion.of(TypeAttributeAppender.ForInstrumentedType.Differentiating.class).refine(new ObjectPropertyAssertion.Refinement<TypeDescription>() {
@Override
public void apply(TypeDescription mock) {
AnnotationDescription[] annotationDescription = new AnnotationDescription[new Random().nextInt(10000)];
when(mock.getDeclaredAnnotations()).thenReturn(new AnnotationList.Explicit(Arrays.asList(annotationDescription)));
when(mock.getTypeVariables()).thenReturn(new TypeList.Generic.Empty());
when(mock.getInterfaces()).thenReturn(new TypeList.Generic.Empty());
}
}).apply();
}
}