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.MockitoRule; import net.bytebuddy.test.utility.ObjectPropertyAssertion; import org.junit.After; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TestRule; import org.mockito.Mock; import org.objectweb.asm.TypeReference; import java.util.Random; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.MatcherAssert.assertThat; import static org.mockito.Mockito.*; public class AnnotationAppenderForTypeAnnotationsTest { private static final String FOO = "foo"; private static final int BAR = 42; @Rule public TestRule mockitoRule = new MockitoRule(this); @Mock private AnnotationAppender annotationAppender, result; @Mock private AnnotationValueFilter annotationValueFilter; @Mock private AnnotationDescription annotationDescription; @Mock private TypeDescription.Generic typeDescription, second, third; @Mock private TypeDescription erasure; private TypeDescription.Generic.Visitor<AnnotationAppender> visitor; @Before @SuppressWarnings("unchecked") public void setUp() throws Exception { when(annotationAppender.append(eq(annotationDescription), eq(annotationValueFilter), eq(BAR), any(String.class))).thenReturn(result); when(typeDescription.getDeclaredAnnotations()).thenReturn(new AnnotationList.Explicit(annotationDescription)); when(second.accept(any(TypeDescription.Generic.Visitor.class))).thenReturn(result); when(third.accept(any(TypeDescription.Generic.Visitor.class))).thenReturn(result); when(second.asGenericType()).thenReturn(second); when(third.asGenericType()).thenReturn(third); when(typeDescription.asErasure()).thenReturn(erasure); visitor = new AnnotationAppender.ForTypeAnnotations(annotationAppender, annotationValueFilter, BAR, FOO); } @After @SuppressWarnings("unchecked") public void tearDown() throws Exception { verifyZeroInteractions(annotationDescription); verifyZeroInteractions(annotationValueFilter); } @Test public void testGenericArray() throws Exception { when(typeDescription.getComponentType()).thenReturn(second); assertThat(visitor.onGenericArray(typeDescription), is(result)); verify(annotationAppender).append(annotationDescription, annotationValueFilter, BAR, FOO); verifyNoMoreInteractions(annotationAppender); verify(second).accept(new AnnotationAppender.ForTypeAnnotations(result, annotationValueFilter, BAR, FOO + "[")); } @Test public void testWildcardUpperBound() throws Exception { when(typeDescription.getLowerBounds()).thenReturn(new TypeList.Generic.Empty()); when(typeDescription.getUpperBounds()).thenReturn(new TypeList.Generic.Explicit(second)); assertThat(visitor.onWildcard(typeDescription), is(result)); verify(annotationAppender).append(annotationDescription, annotationValueFilter, BAR, FOO); verifyNoMoreInteractions(annotationAppender); verify(second).accept(new AnnotationAppender.ForTypeAnnotations(result, annotationValueFilter, BAR, FOO + "*")); } @Test public void testWildcardLowerBound() throws Exception { when(typeDescription.getLowerBounds()).thenReturn(new TypeList.Generic.Explicit(second)); when(typeDescription.getUpperBounds()).thenReturn(new TypeList.Generic.Explicit(TypeDescription.Generic.OBJECT)); assertThat(visitor.onWildcard(typeDescription), is(result)); verify(annotationAppender).append(annotationDescription, annotationValueFilter, BAR, FOO); verifyNoMoreInteractions(annotationAppender); verify(second).accept(new AnnotationAppender.ForTypeAnnotations(result, annotationValueFilter, BAR, FOO + "*")); } @Test public void testTypeVariable() throws Exception { assertThat(visitor.onTypeVariable(typeDescription), is(result)); verify(annotationAppender).append(annotationDescription, annotationValueFilter, BAR, FOO); verifyNoMoreInteractions(annotationAppender); } @Test public void testNonGenericArray() throws Exception { when(typeDescription.isArray()).thenReturn(true); when(typeDescription.getComponentType()).thenReturn(second); assertThat(visitor.onNonGenericType(typeDescription), is(result)); verify(annotationAppender).append(annotationDescription, annotationValueFilter, BAR, FOO); verifyNoMoreInteractions(annotationAppender); verify(second).accept(new AnnotationAppender.ForTypeAnnotations(result, annotationValueFilter, BAR, FOO + "[")); } @Test public void testNonGeneric() throws Exception { assertThat(visitor.onNonGenericType(typeDescription), is(result)); verify(annotationAppender).append(annotationDescription, annotationValueFilter, BAR, FOO); verifyNoMoreInteractions(annotationAppender); } @Test public void testParameterized() throws Exception { when(erasure.getSegmentCount()).thenReturn(1); when(typeDescription.getTypeArguments()).thenReturn(new TypeList.Generic.Explicit(second)); when(typeDescription.getOwnerType()).thenReturn(third); assertThat(visitor.onParameterizedType(typeDescription), is(result)); verify(annotationAppender).append(annotationDescription, annotationValueFilter, BAR, FOO + "."); verifyNoMoreInteractions(annotationAppender); verify(second).accept(new AnnotationAppender.ForTypeAnnotations(result, annotationValueFilter, BAR, FOO + ".0;")); verify(third).accept(new AnnotationAppender.ForTypeAnnotations(result, annotationValueFilter, BAR, FOO + "")); } @Test public void testParameterizedNoOwner() throws Exception { when(typeDescription.getTypeArguments()).thenReturn(new TypeList.Generic.Explicit(second)); assertThat(visitor.onParameterizedType(typeDescription), is(result)); verify(annotationAppender).append(annotationDescription, annotationValueFilter, BAR, FOO); verifyNoMoreInteractions(annotationAppender); verify(second).accept(new AnnotationAppender.ForTypeAnnotations(result, annotationValueFilter, BAR, FOO + "0;")); } @Test public void testObjectProperties() throws Exception { ObjectPropertyAssertion.of(AnnotationAppender.ForTypeAnnotations.class).refine(new ObjectPropertyAssertion.Refinement<TypeReference>() { @Override public void apply(TypeReference mock) { when(mock.getValue()).thenReturn(new Random().nextInt()); } }).apply(); } }