package net.bytebuddy.implementation.bytecode.constant;
import net.bytebuddy.implementation.Implementation;
import net.bytebuddy.implementation.bytecode.StackManipulation;
import net.bytebuddy.test.utility.MockitoRule;
import net.bytebuddy.test.utility.ObjectPropertyAssertion;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TestRule;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.mockito.Mock;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import java.util.Arrays;
import java.util.Collection;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.mockito.Mockito.*;
@RunWith(Parameterized.class)
public class IntegerConstantTest {
private final int value;
private final PushType pushType;
@Rule
public TestRule mockitoRule = new MockitoRule(this);
@Mock
private MethodVisitor methodVisitor;
@Mock
private Implementation.Context implementationContext;
public IntegerConstantTest(int value, PushType pushType) {
this.value = value;
this.pushType = pushType;
}
@Parameterized.Parameters
public static Collection<Object[]> data() {
return Arrays.asList(new Object[][]{
{Integer.MIN_VALUE, PushType.LDC},
{Short.MIN_VALUE - 1, PushType.LDC},
{Short.MIN_VALUE, PushType.SIPUSH},
{Byte.MIN_VALUE - 1, PushType.SIPUSH},
{Byte.MIN_VALUE, PushType.BIPUSH},
{-100, PushType.BIPUSH},
{-2, PushType.BIPUSH},
{6, PushType.BIPUSH},
{7, PushType.BIPUSH},
{100, PushType.BIPUSH},
{Byte.MAX_VALUE, PushType.BIPUSH},
{Byte.MAX_VALUE + 1, PushType.SIPUSH},
{Short.MAX_VALUE, PushType.SIPUSH},
{Short.MAX_VALUE + 1, PushType.LDC},
{Integer.MAX_VALUE, PushType.LDC},
});
}
@Test
public void testBiPush() throws Exception {
StackManipulation integerConstant = IntegerConstant.forValue(value);
assertThat(integerConstant.isValid(), is(true));
StackManipulation.Size size = integerConstant.apply(methodVisitor, implementationContext);
assertThat(size.getSizeImpact(), is(1));
assertThat(size.getMaximalSize(), is(1));
pushType.verifyInstruction(methodVisitor, value);
verifyNoMoreInteractions(methodVisitor);
verifyZeroInteractions(implementationContext);
}
@Test
public void testObjectProperties() throws Exception {
ObjectPropertyAssertion.of(IntegerConstant.SingleBytePush.class).apply();
ObjectPropertyAssertion.of(IntegerConstant.TwoBytePush.class).apply();
ObjectPropertyAssertion.of(IntegerConstant.ConstantPool.class).apply();
}
private enum PushType {
BIPUSH,
SIPUSH,
LDC;
private void verifyInstruction(MethodVisitor methodVisitor, int value) {
switch (this) {
case BIPUSH:
verify(methodVisitor).visitIntInsn(Opcodes.BIPUSH, value);
break;
case SIPUSH:
verify(methodVisitor).visitIntInsn(Opcodes.SIPUSH, value);
break;
case LDC:
verify(methodVisitor).visitLdcInsn(value);
break;
default:
throw new AssertionError();
}
}
}
}