package net.bytebuddy.implementation.bind; import net.bytebuddy.description.method.ParameterDescription; import net.bytebuddy.description.type.TypeDescription; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import org.mockito.Mock; import java.util.Arrays; import java.util.Collection; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.MatcherAssert.assertThat; import static org.mockito.AdditionalMatchers.not; import static org.mockito.Mockito.*; @RunWith(Parameterized.class) public class ArgumentTypeResolverPrimitiveTest extends AbstractArgumentTypeResolverTest { private final Class<?> firstType; private final Class<?> secondType; @Mock private TypeDescription.Generic firstPrimitive, secondPrimitive; @Mock private TypeDescription firstRawPrimitive, secondRawPrimitive; public ArgumentTypeResolverPrimitiveTest(Class<?> firstType, Class<?> secondType) { this.firstType = firstType; this.secondType = secondType; } @Parameterized.Parameters public static Collection<Object[]> data() { return Arrays.asList(new Object[][]{ {boolean.class, byte.class}, {boolean.class, short.class}, {boolean.class, char.class}, {boolean.class, int.class}, {boolean.class, long.class}, {boolean.class, float.class}, {boolean.class, double.class}, {byte.class, short.class}, {byte.class, char.class}, {byte.class, int.class}, {byte.class, long.class}, {byte.class, float.class}, {byte.class, double.class}, {short.class, char.class}, {short.class, int.class}, {short.class, long.class}, {short.class, float.class}, {short.class, double.class}, {char.class, long.class}, {char.class, float.class}, {char.class, double.class}, {int.class, char.class}, {int.class, long.class}, {int.class, float.class}, {int.class, double.class}, {long.class, float.class}, {long.class, double.class}, {float.class, double.class}, }); } @Override @Before public void setUp() throws Exception { super.setUp(); when(firstPrimitive.asErasure()).thenReturn(firstRawPrimitive); when(secondPrimitive.asErasure()).thenReturn(secondRawPrimitive); when(sourceType.isPrimitive()).thenReturn(true); when(firstRawPrimitive.isPrimitive()).thenReturn(true); when(firstRawPrimitive.represents(firstType)).thenReturn(true); when(secondRawPrimitive.isPrimitive()).thenReturn(true); when(secondRawPrimitive.represents(secondType)).thenReturn(true); } @Test public void testLeftDominance() throws Exception { testDominance(firstPrimitive, secondPrimitive, MethodDelegationBinder.AmbiguityResolver.Resolution.LEFT); } @Test public void testRightDominance() throws Exception { testDominance(secondPrimitive, firstPrimitive, MethodDelegationBinder.AmbiguityResolver.Resolution.RIGHT); } @Test public void testLeftNonDominance() throws Exception { testDominance(secondPrimitive, firstPrimitive, MethodDelegationBinder.AmbiguityResolver.Resolution.RIGHT); } @Test public void testRightNonDominance() throws Exception { testDominance(firstPrimitive, secondPrimitive, MethodDelegationBinder.AmbiguityResolver.Resolution.LEFT); } @Test public void testNonDominance() throws Exception { testDominance(firstPrimitive, firstPrimitive, MethodDelegationBinder.AmbiguityResolver.Resolution.AMBIGUOUS); } private void testDominance(TypeDescription.Generic leftPrimitive, TypeDescription.Generic rightPrimitive, MethodDelegationBinder.AmbiguityResolver.Resolution expected) throws Exception { when(sourceParameterList.size()).thenReturn(2); when(sourceType.isPrimitive()).thenReturn(true); ParameterDescription leftParameter = mock(ParameterDescription.class); when(leftParameter.getType()).thenReturn(leftPrimitive); when(leftParameterList.get(0)).thenReturn(leftParameter); when(left.getTargetParameterIndex(any(ArgumentTypeResolver.ParameterIndexToken.class))) .thenAnswer(new TokenAnswer(new int[][]{{0, 0}})); ParameterDescription rightParameter = mock(ParameterDescription.class); when(rightParameter.getType()).thenReturn(rightPrimitive); when(rightParameterList.get(0)).thenReturn(rightParameter); when(right.getTargetParameterIndex(any(ArgumentTypeResolver.ParameterIndexToken.class))) .thenAnswer(new TokenAnswer(new int[][]{{0, 0}})); MethodDelegationBinder.AmbiguityResolver.Resolution resolution = ArgumentTypeResolver.INSTANCE.resolve(source, left, right); assertThat(resolution, is(expected)); verify(source, atLeast(1)).getParameters(); verify(leftMethod, atLeast(1)).getParameters(); verify(rightMethod, atLeast(1)).getParameters(); verify(left, atLeast(1)).getTargetParameterIndex(argThat(describesArgument(0))); verify(left, atLeast(1)).getTargetParameterIndex(argThat(describesArgument(1))); verify(left, never()).getTargetParameterIndex(not(argThat(describesArgument(0, 1)))); verify(right, atLeast(1)).getTargetParameterIndex(argThat(describesArgument(0))); verify(right, atLeast(1)).getTargetParameterIndex(argThat(describesArgument(1))); verify(right, never()).getTargetParameterIndex(not(argThat(describesArgument(0, 1)))); } }