package org.testng.internal;
import static org.testng.internal.TestNGMethodFinder.MethodType.*;
import java.lang.reflect.Method;
import java.util.Comparator;
import java.util.List;
import java.util.Set;
import org.testng.ITestMethodFinder;
import org.testng.ITestNGMethod;
import org.testng.annotations.IConfigurationAnnotation;
import org.testng.annotations.ITestAnnotation;
import org.testng.collections.Lists;
import org.testng.internal.annotations.AnnotationHelper;
import org.testng.internal.annotations.IAnnotationFinder;
import org.testng.xml.XmlTest;
public class TestNGMethodFinder implements ITestMethodFinder {
enum MethodType {
BEFORE_SUITE,
AFTER_SUITE,
BEFORE_TEST,
AFTER_TEST,
BEFORE_CLASS,
AFTER_CLASS,
BEFORE_TEST_METHOD,
AFTER_TEST_METHOD,
BEFORE_GROUPS,
AFTER_GROUPS
}
private static final Comparator<ITestNGMethod> NO_COMPARISON = (o1, o2) -> 0;
private RunInfo runInfo;
private IAnnotationFinder annotationFinder;
private final Comparator<ITestNGMethod> comparator;
public TestNGMethodFinder(RunInfo runInfo, IAnnotationFinder annotationFinder) {
this(runInfo, annotationFinder, NO_COMPARISON);
}
public TestNGMethodFinder(
RunInfo runInfo, IAnnotationFinder annotationFinder, Comparator<ITestNGMethod> comparator) {
this.runInfo = runInfo;
this.annotationFinder = annotationFinder;
this.comparator = comparator;
}
@Override
public ITestNGMethod[] getTestMethods(Class<?> clazz, XmlTest xmlTest) {
return AnnotationHelper.findMethodsWithAnnotation(
clazz, ITestAnnotation.class, annotationFinder, xmlTest);
}
@Override
public ITestNGMethod[] getBeforeClassMethods(Class cls) {
return findConfiguration(cls, BEFORE_CLASS);
}
@Override
public ITestNGMethod[] getAfterClassMethods(Class cls) {
return findConfiguration(cls, AFTER_CLASS);
}
@Override
public ITestNGMethod[] getBeforeTestMethods(Class cls) {
return findConfiguration(cls, BEFORE_TEST_METHOD);
}
@Override
public ITestNGMethod[] getAfterTestMethods(Class cls) {
return findConfiguration(cls, AFTER_TEST_METHOD);
}
@Override
public ITestNGMethod[] getBeforeSuiteMethods(Class cls) {
return findConfiguration(cls, BEFORE_SUITE);
}
@Override
public ITestNGMethod[] getAfterSuiteMethods(Class cls) {
return findConfiguration(cls, AFTER_SUITE);
}
@Override
public ITestNGMethod[] getBeforeTestConfigurationMethods(Class clazz) {
return findConfiguration(clazz, BEFORE_TEST);
}
@Override
public ITestNGMethod[] getAfterTestConfigurationMethods(Class clazz) {
return findConfiguration(clazz, AFTER_TEST);
}
@Override
public ITestNGMethod[] getBeforeGroupsConfigurationMethods(Class clazz) {
return findConfiguration(clazz, BEFORE_GROUPS);
}
@Override
public ITestNGMethod[] getAfterGroupsConfigurationMethods(Class clazz) {
return findConfiguration(clazz, AFTER_GROUPS);
}
private ITestNGMethod[] findConfiguration(final Class clazz, final MethodType configurationType) {
List<ITestNGMethod> vResult = Lists.newArrayList();
Set<Method> methods = ClassHelper.getAvailableMethods(clazz);
for (Method m : methods) {
IConfigurationAnnotation configuration =
AnnotationHelper.findConfiguration(annotationFinder, m);
if (null == configuration) {
continue;
}
boolean create;
boolean isBeforeSuite = false;
boolean isAfterSuite = false;
boolean isBeforeTest = false;
boolean isAfterTest = false;
boolean isBeforeClass = false;
boolean isAfterClass = false;
boolean isBeforeTestMethod = false;
boolean isAfterTestMethod = false;
String[] beforeGroups = null;
String[] afterGroups = null;
switch (configurationType) {
case BEFORE_SUITE:
create = configuration.getBeforeSuite();
isBeforeSuite = true;
break;
case AFTER_SUITE:
create = configuration.getAfterSuite();
isAfterSuite = true;
break;
case BEFORE_TEST:
create = configuration.getBeforeTest();
isBeforeTest = true;
break;
case AFTER_TEST:
create = configuration.getAfterTest();
isAfterTest = true;
break;
case BEFORE_CLASS:
create = configuration.getBeforeTestClass();
isBeforeClass = true;
break;
case AFTER_CLASS:
create = configuration.getAfterTestClass();
isAfterClass = true;
break;
case BEFORE_TEST_METHOD:
create = configuration.getBeforeTestMethod();
isBeforeTestMethod = true;
break;
case AFTER_TEST_METHOD:
create = configuration.getAfterTestMethod();
isAfterTestMethod = true;
break;
case BEFORE_GROUPS:
beforeGroups = configuration.getBeforeGroups();
create = shouldCreateBeforeAfterGroup(beforeGroups, annotationFinder, clazz, configuration.getInheritGroups());
isBeforeTestMethod = true;
break;
case AFTER_GROUPS:
afterGroups = configuration.getAfterGroups();
create = shouldCreateBeforeAfterGroup(afterGroups, annotationFinder, clazz, configuration.getInheritGroups());
isAfterTestMethod = true;
break;
default:
throw new AssertionError("Unexpected value: " + configurationType);
}
if (create) {
addConfigurationMethod(
clazz,
vResult,
m,
isBeforeSuite,
isAfterSuite,
isBeforeTest,
isAfterTest,
isBeforeClass,
isAfterClass,
isBeforeTestMethod,
isAfterTestMethod,
beforeGroups,
afterGroups,
null);
}
}
List<ITestNGMethod> excludedMethods = Lists.newArrayList();
boolean unique = configurationType == BEFORE_SUITE || configurationType == AFTER_SUITE;
return MethodHelper.collectAndOrderMethods(
Lists.newArrayList(vResult),
false ,
runInfo,
annotationFinder,
unique,
excludedMethods,
comparator);
}
private static boolean shouldCreateBeforeAfterGroup(String[] groups, IAnnotationFinder finder,
Class<?> clazz, boolean isInheritGroups) {
if (!isInheritGroups) {
return groups.length > 0;
}
ITestAnnotation test = AnnotationHelper.findTest(finder, clazz);
if (test == null) {
return groups.length > 0;
}
return groups.length > 0 || test.getGroups().length > 0;
}
private void addConfigurationMethod(
Class<?> clazz,
List<ITestNGMethod> results,
Method method,
boolean isBeforeSuite,
boolean isAfterSuite,
boolean isBeforeTest,
boolean isAfterTest,
boolean isBeforeClass,
boolean isAfterClass,
boolean isBeforeTestMethod,
boolean isAfterTestMethod,
String[] beforeGroups,
String[] afterGroups,
Object instance) {
if (method.getDeclaringClass().isAssignableFrom(clazz)) {
ITestNGMethod confMethod =
new ConfigurationMethod(
new ConstructorOrMethod(method),
annotationFinder,
isBeforeSuite,
isAfterSuite,
isBeforeTest,
isAfterTest,
isBeforeClass,
isAfterClass,
isBeforeTestMethod,
isAfterTestMethod,
beforeGroups,
afterGroups,
instance);
results.add(confMethod);
}
}
}