package net.bytebuddy.implementation.bytecode.collection; import net.bytebuddy.description.type.TypeDescription; import net.bytebuddy.implementation.Implementation; import net.bytebuddy.implementation.bytecode.StackManipulation; import net.bytebuddy.implementation.bytecode.StackSize; import net.bytebuddy.test.utility.MockitoRule; import org.junit.After; import org.junit.Before; import org.junit.Rule; import org.junit.rules.TestRule; import org.mockito.Mock; import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.Opcodes; import org.objectweb.asm.Type; import java.util.Collections; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.MatcherAssert.assertThat; import static org.mockito.Mockito.*; public abstract class AbstractArrayFactoryTest { @Rule public TestRule mockitoRule = new MockitoRule(this); @Mock private TypeDescription.Generic componentType; @Mock private TypeDescription rawComponentType; @Mock private MethodVisitor methodVisitor; @Mock private StackManipulation stackManipulation; @Mock private Implementation.Context implementationContext; @Before public void setUp() throws Exception { when(stackManipulation.isValid()).thenReturn(true); when(componentType.asErasure()).thenReturn(rawComponentType); } @After public void tearDown() throws Exception { verifyZeroInteractions(implementationContext); } protected void testCreationUsing(Class<?> componentType, int storageOpcode) throws Exception { defineComponentType(componentType); CollectionFactory arrayFactory = ArrayFactory.forType(this.componentType); StackManipulation arrayStackManipulation = arrayFactory.withValues(Collections.singletonList(stackManipulation)); assertThat(arrayStackManipulation.isValid(), is(true)); verify(stackManipulation, atLeast(1)).isValid(); StackManipulation.Size size = arrayStackManipulation.apply(methodVisitor, implementationContext); assertThat(size.getSizeImpact(), is(1)); assertThat(size.getMaximalSize(), is(3 + StackSize.of(componentType).toIncreasingSize().getSizeImpact())); verify(methodVisitor).visitInsn(Opcodes.ICONST_1); verifyArrayCreation(methodVisitor); verify(methodVisitor).visitInsn(Opcodes.DUP); verify(methodVisitor).visitInsn(Opcodes.ICONST_0); verify(stackManipulation).apply(methodVisitor, implementationContext); verify(methodVisitor).visitInsn(storageOpcode); verifyNoMoreInteractions(methodVisitor); verifyNoMoreInteractions(stackManipulation); } protected abstract void verifyArrayCreation(MethodVisitor methodVisitor); private void defineComponentType(Class<?> type) { when(componentType.isPrimitive()).thenReturn(type.isPrimitive()); when(componentType.represents(type)).thenReturn(true); when(rawComponentType.getInternalName()).thenReturn(Type.getInternalName(type)); when(componentType.getStackSize()).thenReturn(StackSize.of(type)); when(stackManipulation.apply(any(MethodVisitor.class), any(Implementation.Context.class))).thenReturn(StackSize.of(type).toIncreasingSize()); } }