package test.reflect;
import org.testng.Assert;
import org.testng.ITestContext;
import org.testng.ITestResult;
import org.testng.TestRunner;
import org.testng.annotations.DataProvider;
import org.testng.annotations.NoInjection;
import org.testng.annotations.Test;
import org.testng.internal.reflect.InjectableParameter;
import org.testng.internal.reflect.Parameter;
import org.testng.internal.reflect.ReflectionRecipes;
import org.testng.xml.XmlTest;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.sql.Connection;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
/**
* @author <a href="mailto:nitin.matrix@gmail.com">Nitin Verma</a>
*/
public class ReflectionRecipesTest {
private static final Object[] A0 = new Object[]{343, true};
private static final Parameter[] S0 = getMethodParameters(T.class, "s0");
private static final Parameter[] S1 = getMethodParameters(T.class, "s1");
private static final Parameter[] S2 = getMethodParameters(T.class, "s2");
private static final Parameter[] S3 = getMethodParameters(T.class, "s3");
private static Parameter[] getMethodParameters(final Class<?> clazz, final String methodName) {
Method method = null;
Parameter[] parameters = null;
for (final Method m : clazz.getMethods()) {
if (m.getName().equals(methodName)) {
method = m;
}
}
if (method != null) {
parameters = ReflectionRecipes.getMethodParameters(method);
}
return parameters;
}
@DataProvider
public Object[][] methodInputParameters() {
return new Object[][]{S0, S1, S2, S3};
}
@DataProvider
public Object[][] methodInputParamArgsPair() {
return new Object[][]{
new Object[]{S0, A0},
new Object[]{S1, A0},
new Object[]{S2, A0},
new Object[]{S3, A0},
};
}
@DataProvider
public Object[][] exactMatchDP() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
final Method[] methods = ExactMatchTest.class.getDeclaredMethods();
final List<Object[]> objects = new ArrayList<>();
System.out.println("exactMatchDP:");
for (int i = 0; i < methods.length; i++) {
final Method method = methods[i];
final ExactMatchTest.Expectation annotation =
method.getAnnotation(ExactMatchTest.Expectation.class);
if (annotation != null) {
final String provider = annotation.expectationProvider();
final int flag = annotation.flag();
Assert.assertNotNull(provider);
final Method providerMethod = ExactMatchTest.class.getMethod(provider, int.class);
final Object out = providerMethod.invoke(ExactMatchTest.class, flag);
Assert.assertTrue(out instanceof Object[][]);
System.out.println(method.getName() + ", " + out);
objects.add(new Object[]{out, method});
}
}
return objects.toArray(new Object[objects.size()][]);
}
@DataProvider
public Object[][] matchArrayEndingDP() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
final Method[] methods = MatchArrayEndingTest.class.getDeclaredMethods();
final List<Object[]> objects = new ArrayList<>();
System.out.println("matchArrayEndingDP:");
for (int i = 0; i < methods.length; i++) {
final Method method = methods[i];
final MatchArrayEndingTest.Expectation annotation =
method.getAnnotation(MatchArrayEndingTest.Expectation.class);
if (annotation != null) {
final String provider = annotation.expectationProvider();
final int flag = annotation.flag();
Assert.assertNotNull(provider);
final Method providerMethod = MatchArrayEndingTest.class.getMethod(provider, int.class);
final Object out = providerMethod.invoke(MatchArrayEndingTest.class, flag);
Assert.assertTrue(out instanceof Object[][]);
System.out.println(method.getName() + ", " + out);
objects.add(new Object[]{out, method});
}
}
return objects.toArray(new Object[objects.size()][]);
}
@DataProvider
public Object[][] testContexts() {
return new Object[][]{
{TestRunner.class},
{ITestContext.class},
{TestContextJustForTesting.class}
};
}
@DataProvider
public Object[][] notTestContexts() {
return new Object[][]{
{Object.class},
{Class.class},
{Connection.class}
};
}
@Test(dataProvider = "matchArrayEndingDP")
public void matchArrayEndingTest(final Object[][] expected, @NoInjection final Method method) {
if (expected != null) {
final Parameter[] methodParameters = ReflectionRecipes.getMethodParameters(method);
Assert.assertNotNull(methodParameters);
final Parameter[] filteredParameters =
ReflectionRecipes.filter(methodParameters, InjectableParameter.Assistant.ALL_INJECTS);
Assert.assertNotNull(filteredParameters);
for (final Object[] expect : expected) {
Assert.assertNotNull(expect);
Assert.assertEquals(expect.length, 2);
Assert.assertNotNull(expect[0]);
Assert.assertTrue(expect[0] instanceof Object[]);
Assert.assertNotNull(expect[1]);
Assert.assertTrue(expect[1] instanceof Boolean);
Assert.assertEquals(
ReflectionRecipes.matchArrayEnding(filteredParameters, (Object[]) expect[0]),
expect[1]
);
}
}
}
@Test(dataProvider = "exactMatchDP")
public void exactMatchTest(final Object[][] expected, @NoInjection final Method method) {
if (expected != null) {
final Parameter[] methodParameters = ReflectionRecipes.getMethodParameters(method);
Assert.assertNotNull(methodParameters);
final Parameter[] filteredParameters =
ReflectionRecipes.filter(methodParameters, InjectableParameter.Assistant.ALL_INJECTS);
Assert.assertNotNull(filteredParameters);
for (final Object[] expect : expected) {
Assert.assertNotNull(expect);
Assert.assertEquals(expect.length, 2);
Assert.assertNotNull(expect[0]);
Assert.assertTrue(expect[0] instanceof Object[]);
Assert.assertNotNull(expect[1]);
Assert.assertTrue(expect[1] instanceof Boolean);
Assert.assertEquals(
ReflectionRecipes.exactMatch(filteredParameters, (Object[]) expect[0]),
expect[1]
);
}
}
}
@Test(dataProvider = "methodInputParameters")
public void testFilters(final Parameter[] parameters) {
System.out.println("In: " + Arrays.asList(parameters));
final Parameter[] parameters1 = ReflectionRecipes.filter(parameters, InjectableParameter.Assistant.ALL_INJECTS);
System.out.println("Out: " + Arrays.asList(parameters1));
Assert.assertEquals(parameters1.length, 2);
Assert.assertEquals(parameters1[0].getType(), int.class);
Assert.assertEquals(parameters1[1].getType(), Boolean.class);
}
@Test(dataProvider = "methodInputParamArgsPair")
public void testInject(final Parameter[] parameters, final Object[] args) {
System.out.println("In: " + Arrays.asList(parameters));
System.out.println("args: " + Arrays.asList(args));
final Object[] injectedArgs = ReflectionRecipes.inject(
parameters, InjectableParameter.Assistant.ALL_INJECTS, args,
null, null, null
);
System.out.println("injectedArgs: " + Arrays.asList(injectedArgs));
Assert.assertEquals(injectedArgs.length, parameters.length);
}
@Test(dataProvider = "testContexts")
public void testIsOrImplementsInterface(final Class<?> clazz) {
Assert.assertTrue(ReflectionRecipes.isOrImplementsInterface(ITestContext.class, clazz));
}
@Test(dataProvider = "notTestContexts")
public void testNegativeCaseIsOrImplementsInterface(final Class<?> clazz) {
Assert.assertFalse(ReflectionRecipes.isOrImplementsInterface(ITestContext.class, clazz));
}
private static interface T {
public void s0(TestContextJustForTesting testContext, int i, Boolean b);
public void s1(int i, ITestContext iTestContext, Boolean b);
public void s2(int i, Boolean b, ITestContext iTestContext);
public void s3(ITestContext iTestContext1, int i, Boolean b, ITestContext iTestContext2);
}
public static abstract class ExactMatchTest {
public static Object[][] exactMatchData(final int flag) {
switch (flag) {
case 0:
return new Object[][]{
new Object[]{new Object[]{}, true},
new Object[]{new Object[]{1}, false},
new Object[]{new Object[]{""}, false},
new Object[]{new Object[]{1, ""}, false},
};
case 1:
return new Object[][]{
new Object[]{new Object[]{1}, true},
new Object[]{new Object[]{}, false},
new Object[]{new Object[]{""}, false},
new Object[]{new Object[]{1, ""}, false},
new Object[]{new Object[]{"", 1}, false},
};
default:
return null;
}
}
@Expectation(expectationProvider = "exactMatchData", flag = 0)
public abstract void s0();
@Expectation(expectationProvider = "exactMatchData", flag = 0)
public abstract void s0(final ITestContext a0);
@Expectation(expectationProvider = "exactMatchData", flag = 0)
public abstract void s0(final ITestContext a0, final ITestResult a1);
@Expectation(expectationProvider = "exactMatchData", flag = 0)
public abstract void s0(final ITestContext a0, final ITestResult a1, final XmlTest a2);
@Expectation(expectationProvider = "exactMatchData", flag = 0)
public abstract void s0(final ITestContext a0, final ITestResult a1, final XmlTest a2, final Method a3);
@Expectation(expectationProvider = "exactMatchData", flag = 1)
public abstract void s1(final int a0);
@Expectation(expectationProvider = "exactMatchData", flag = 1)
public abstract void s1(final ITestContext a0, final int a1);
@Expectation(expectationProvider = "exactMatchData", flag = 1)
public abstract void s1(final ITestContext a0, final Integer a1, final ITestResult a2);
@Expectation(expectationProvider = "exactMatchData", flag = 1)
public abstract void s1(final int a0, final ITestContext a1, final ITestResult a2, final XmlTest a3);
@Expectation(expectationProvider = "exactMatchData", flag = 1)
public abstract void s1(final ITestContext a0, final ITestResult a1, final int a2,
final XmlTest a3, final Method a4);
@Retention(RUNTIME)
@Target({METHOD})
public static @interface Expectation {
public String expectationProvider();
public int flag();
}
}
public static abstract class MatchArrayEndingTest {
public static Object[][] matchArrayEndingData(final int flag) {
switch (flag) {
case 0:
return new Object[][]{
new Object[]{new Object[]{10f, 2.1f}, true},
new Object[]{new Object[]{10}, true},
new Object[]{new Object[]{10d, ""}, false},
new Object[]{new Object[]{1, ""}, false},
};
case 1:
return new Object[][]{
new Object[]{new Object[]{1, 10f, 2.1f}, true},
new Object[]{new Object[]{}, false},
new Object[]{new Object[]{""}, false},
new Object[]{new Object[]{10f, "", 2.1f}, false},
new Object[]{new Object[]{"", 10f, 2.1f}, false},
};
default:
return null;
}
}
@Expectation(expectationProvider = "matchArrayEndingData", flag = 0)
public abstract void s0(final float... f);
@Expectation(expectationProvider = "matchArrayEndingData", flag = 0)
public abstract void s0(final float[] f, final ITestContext a0);
@Expectation(expectationProvider = "matchArrayEndingData", flag = 0)
public abstract void s0(final ITestContext a0, final float[] f, final ITestResult a1);
@Expectation(expectationProvider = "matchArrayEndingData", flag = 0)
public abstract void s0(final ITestContext a0, final ITestResult a1, final XmlTest a2, final float... f);
@Expectation(expectationProvider = "matchArrayEndingData", flag = 0)
public abstract void s0(final ITestContext a0, final ITestResult a1,
final XmlTest a2, final float[] f,
final Method a3);
@Expectation(expectationProvider = "matchArrayEndingData", flag = 1)
public abstract void s1(final int a0, final float... f);
@Expectation(expectationProvider = "matchArrayEndingData", flag = 1)
public abstract void s1(final ITestContext a0, final int a1, final float... f);
@Expectation(expectationProvider = "matchArrayEndingData", flag = 1)
public abstract void s1(final ITestContext a0, final Integer a1,
final ITestResult a2, final float... f);
@Expectation(expectationProvider = "matchArrayEndingData", flag = 1)
public abstract void s1(final int a0, final ITestContext a1, final ITestResult a2,
final float[] f, final XmlTest a3);
@Expectation(expectationProvider = "matchArrayEndingData", flag = 1)
public abstract void s1(final ITestContext a0, final ITestResult a1, final int a2,
final XmlTest a3, final float[] f, final Method a4);
@Retention(RUNTIME)
@Target({METHOD})
public static @interface Expectation {
public String expectationProvider();
public int flag();
}
}
}