Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
package org.testng.internal;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Stream;
import org.testng.IMethodSelector;
import org.testng.IMethodSelectorContext;
import org.testng.ITestNGMethod;
import org.testng.collections.ListMultiMap;
import org.testng.collections.Lists;
import org.testng.collections.Maps;
import org.testng.internal.reflect.ReflectionHelper;
import org.testng.xml.XmlClass;
import org.testng.xml.XmlInclude;
import org.testng.xml.XmlScript;
/**
* This class is the default method selector used by TestNG to determine which methods need to be
* included and excluded based on the specification given in testng.xml.
*/
// TODO: Need to investigate as to why is m_includedGroups/m_excludedGroups being created as a map
// even though
// We are only working with the values and the keys are completely ignored.
public class XmlMethodSelector implements IMethodSelector {
private static final String QUOTED_DOLLAR = Matcher.quoteReplacement("\\$");
// List of methods included implicitly
private final ListMultiMap m_includedMethods = Maps.newListMultiMap();
private final Map m_logged = Maps.newHashMap();
// Groups included and excluded for this run
private Map m_includedGroups = Maps.newHashMap();
private Map m_excludedGroups = Maps.newHashMap();
private List m_classes = Collections.emptyList();
private ScriptMethodSelector scriptSelector;
private boolean m_isInitialized = false;
private List m_testMethods = Collections.emptyList();
// Group inclusions override
private boolean m_overrideIncludedMethods = false;
@Override
public boolean includeMethod(
IMethodSelectorContext context, ITestNGMethod tm, boolean isTestMethod) {
if (!m_isInitialized) {
m_isInitialized = true;
init(context);
}
if (scriptSelector != null) {
return scriptSelector.includeMethodFromExpression(tm);
}
return includeMethodFromIncludeExclude(tm, isTestMethod);
}
private boolean includeMethodFromIncludeExclude(ITestNGMethod tm, boolean isTestMethod) {
boolean result = false;
ConstructorOrMethod method = tm.getConstructorOrMethod();
Map includedGroups = m_includedGroups;
Map excludedGroups = m_excludedGroups;
String key;
boolean hasTestClass = tm.getTestClass() != null;
if (hasTestClass) {
key = makeMethodName(tm.getTestClass().getRealClass().getName(), method.getName());
} else {
key = MethodHelper.calculateMethodCanonicalName(tm);
}
List includeList = m_includedMethods.get(key);
// No groups were specified:
if (includedGroups.isEmpty()
&& excludedGroups.isEmpty()
&& !hasIncludedMethods()
&& !hasExcludedMethods()) {
// If we don't include or exclude any methods, method is in
result = true;
} else if (includedGroups.isEmpty() && excludedGroups.isEmpty() && !isTestMethod) {
// If it's a configuration method and no groups were requested, we want it in
result = true;
} else if (!includeList.isEmpty() && !m_overrideIncludedMethods) {
// Is this method included implicitly and are we not overriding inclusions by group
// exclusions?
result = true;
} else { // Include or Exclude groups were specified:
// Only add this method if it belongs to an included group and not
// to an excluded group
boolean noGroupsSpecified = false; /* Explicitly disable logic to consider size for groups */
String[] groups =
Stream.of(
Optional.ofNullable(tm.getBeforeGroups()).orElse(new String[] {}),
Optional.ofNullable(tm.getGroups()).orElse(new String[] {}),
Optional.ofNullable(tm.getAfterGroups()).orElse(new String[] {}))
.flatMap(Arrays::stream)
.distinct()
.toArray(String[]::new);
boolean isIncludedInGroups = isIncluded(m_includedGroups.values(), noGroupsSpecified, groups);
boolean isExcludedInGroups = isExcluded(m_excludedGroups.values(), groups);
// Calculate the run methods by groups first
if (isIncludedInGroups && !isExcludedInGroups) {
result = true;
} else if (isExcludedInGroups) {
result = false;
}
if (isTestMethod) {
// Now filter by method name
Class methodClass = method.getDeclaringClass();
String fullMethodName = makeMethodName(methodClass.getName(), method.getName());
// Check if groups was involved or not. If groups was not involved then we should not be
// involving the size of the list for evaluation of "isIncluded"
noGroupsSpecified = (m_includedGroups.isEmpty() && m_excludedGroups.isEmpty());
// Iterate through all the classes so we can gather all the included and
// excluded methods
for (XmlClass xmlClass : m_classes) {
// Only consider included/excluded methods that belong to the same class
// we are looking at
Class cls = xmlClass.getSupportClass();
if (!assignable(methodClass, cls)) {
continue;
}
List includedMethods =
createQualifiedMethodNames(xmlClass, toStringList(xmlClass.getIncludedMethods()));
boolean isIncludedInMethods =
isIncluded(includedMethods, noGroupsSpecified, fullMethodName);
List excludedMethods =
createQualifiedMethodNames(xmlClass, xmlClass.getExcludedMethods());
boolean isExcludedInMethods = isExcluded(excludedMethods, fullMethodName);
if (result) {
// If we're about to include this method by group, make sure
// it's included by method and not excluded by method
if (!xmlClass.getIncludedMethods().isEmpty()) {
result = isIncludedInMethods;
}
if (!xmlClass.getExcludedMethods().isEmpty()) {
result = result && !isExcludedInMethods;
}
}
// otherwise it's already excluded and nothing will bring it back,
// since exclusions preempt inclusions
}
}
}
Package pkg = method.getDeclaringClass().getPackage();
String methodName = pkg != null ? pkg.getName() + "." + method.getName() : method.getName();
logInclusion(result ? "Including" : "Excluding", "method", methodName + "()");
return result;
}
private static boolean assignable(Class sourceClass, Class targetClass) {
return sourceClass.isAssignableFrom(targetClass) || targetClass.isAssignableFrom(sourceClass);
}
private void logInclusion(String including, String type, String name) {
if (!m_logged.containsKey(name)) {
log(including + " " + type + " " + name);
m_logged.put(name, name);
}
}
private boolean hasIncludedMethods() {
for (XmlClass xmlClass : m_classes) {
if (!xmlClass.getIncludedMethods().isEmpty()) {
return true;
}
}
return false;
}
private boolean hasExcludedMethods() {
for (XmlClass xmlClass : m_classes) {
if (!xmlClass.getExcludedMethods().isEmpty()) {
return true;
}
}
return false;
}
private static List toStringList(List methods) {
List result = Lists.newArrayList();
for (XmlInclude m : methods) {
result.add(m.getName());
}
return result;
}
private static List createQualifiedMethodNames(XmlClass xmlClass, List methods) {
List vResult = Lists.newArrayList();
Class cls = xmlClass.getSupportClass();
while (cls != null) {
for (String im : methods) {
Pattern pattern = Pattern.compile(methodName(im));
Method[] allMethods = ReflectionHelper.getLocalMethods(cls);
for (Method m : allMethods) {
if (pattern.matcher(m.getName()).matches()) {
vResult.add(makeMethodName(m.getDeclaringClass().getName(), m.getName()));
}
}
}
cls = cls.getSuperclass();
}
return vResult;
}
private static String methodName(String methodName) {
if (methodName.contains("\\$")) {
return methodName;
}
return methodName.replaceAll("\\Q$\\E", QUOTED_DOLLAR);
}
private static String makeMethodName(String className, String methodName) {
return className + "." + methodName;
}
private static void checkMethod(Class c, String methodName) {
Pattern p = Pattern.compile(methodName);
for (Method m : c.getMethods()) {
if (p.matcher(m.getName()).matches()) {
return;
}
}
Utils.log(
"Warning",
2,
"The regular expression \""
+ methodName
+ "\" didn't match any"
+ " method in class "
+ c.getName());
}
public void setXmlClasses(List classes) {
m_classes = classes;
for (XmlClass c : classes) {
for (XmlInclude m : c.getIncludedMethods()) {
checkMethod(c.getSupportClass(), m.getName());
String methodName = makeMethodName(c.getName(), m.getName());
m_includedMethods.put(methodName, m);
}
}
}
/** @return Returns the excludedGroups. */
public Map getExcludedGroups() {
return m_excludedGroups;
}
/** @return Returns the includedGroups. */
public Map getIncludedGroups() {
return m_includedGroups;
}
/** @param excludedGroups The excludedGroups to set. */
public void setExcludedGroups(Map excludedGroups) {
m_excludedGroups = excludedGroups;
}
/** @param includedGroups The includedGroups to set. */
public void setIncludedGroups(Map includedGroups) {
m_includedGroups = includedGroups;
}
private static boolean isIncluded(
Collection includedGroups, boolean noGroupsSpecified, String... groups) {
if (noGroupsSpecified) {
return isMemberOf(includedGroups, groups);
}
return includedGroups.isEmpty() || isMemberOf(includedGroups, groups);
}
private static boolean isExcluded(Collection excludedGroups, String... groups) {
return isMemberOf(excludedGroups, groups);
}
/**
* @param groups Array of groups on the method
* @param list Map of regexps of groups to be run
*/
private static boolean isMemberOf(Collection list, String... groups) {
for (String group : groups) {
for (String o : list) {
String regexpStr = methodName(o);
if (Pattern.matches(regexpStr, group)) {
return true;
}
}
}
return false;
}
private static void log(String s) {
Utils.log("XmlMethodSelector", 4, s);
}
public void setScript(XmlScript script) {
scriptSelector = (script == null) ? null : ScriptSelectorFactory.getScriptSelector(script);
}
@Override
public void setTestMethods(List testMethods) {
// Caution: this variable is initialized with an empty list first and then modified
// externally by the caller (TestRunner#fixMethodWithClass). Ugly.
m_testMethods = testMethods;
}
public boolean getOverrideIncludedMethods() {
return m_overrideIncludedMethods;
}
public void setOverrideIncludedMethods(boolean overrideIncludedMethods) {
m_overrideIncludedMethods = overrideIncludedMethods;
}
private void init(IMethodSelectorContext context) {
String[] groups = m_includedGroups.keySet().toArray(new String[0]);
Set groupClosure = new HashSet<>();
Set methodClosure = new HashSet<>();
List includedMethods = Lists.newArrayList();
for (ITestNGMethod m : m_testMethods) {
if (includeMethod(context, m, true)) {
includedMethods.add(m);
}
}
MethodGroupsHelper.findGroupTransitiveClosure(
includedMethods, m_testMethods, groups, groupClosure, methodClosure);
// If we are asked to include or exclude specific groups, calculate
// the transitive closure of all the included groups. If no include groups
// were specified, don't do anything.
// Any group that is part of the transitive closure but not part of
// m_includedGroups is being added implicitly by TestNG so that if someone
// includes a group z that depends on a, b and c, they don't need to
// include a, b and c explicitly.
if (!m_includedGroups.isEmpty()) {
// Make the transitive closure our new included groups
for (String g : groupClosure) {
log("Including group " + (m_includedGroups.containsKey(g) ? ": " : "(implicitly): ") + g);
m_includedGroups.put(g, g);
}
// Make the transitive closure our new included methods
for (ITestNGMethod m : methodClosure) {
String methodName = m.getQualifiedName();
XmlInclude xi = new XmlInclude(methodName);
// TODO: set the XmlClass on this xi or we won't get inheritance of parameters
m_includedMethods.put(methodName, xi);
logInclusion("Including", "method ", methodName);
}
}
}
}