org.testng.DependencyMap Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of testng Show documentation
Show all versions of testng Show documentation
A testing framework for the JVM
package org.testng;
import org.testng.collections.ListMultiMap;
import org.testng.collections.Lists;
import org.testng.collections.Maps;
import java.util.List;
import java.util.Set;
import java.util.regex.Pattern;
/**
* Helper class to keep track of dependencies.
*
* @author Cedric Beust
*/
public class DependencyMap {
private ListMultiMap m_dependencies = Maps.newListMultiMap();
private ListMultiMap m_groups = Maps.newListMultiMap();
public DependencyMap(ITestNGMethod[] methods) {
for (ITestNGMethod m : methods) {
m_dependencies.put(m.getQualifiedName(), m);
for (String g : m.getGroups()) {
m_groups.put(g, m);
}
}
}
public List getMethodsThatBelongTo(String group, ITestNGMethod fromMethod) {
Set uniqueKeys = m_groups.keySet();
List result = Lists.newArrayList();
for (String k : uniqueKeys) {
if (Pattern.matches(group, k)) {
result.addAll(m_groups.get(k));
}
}
if (result.isEmpty() && !fromMethod.ignoreMissingDependencies()) {
throw new TestNGException(
"DependencyMap::Method \""
+ fromMethod
+ "\" depends on nonexistent group \""
+ group
+ "\"");
} else {
return result;
}
}
public ITestNGMethod getMethodDependingOn(String methodName, ITestNGMethod fromMethod) {
List l = m_dependencies.get(methodName);
if (l.isEmpty()) {
// Try to fetch dependencies by using the test class in the method name.
// This is usually needed in scenarios wherein a child class overrides a base class method.
// So the dependency name needs to be adjusted to use the test class name instead of using the
// declared class.
l = m_dependencies.get(constructMethodNameUsingTestClass(methodName, fromMethod));
}
if (l.isEmpty() && fromMethod.ignoreMissingDependencies()) {
return fromMethod;
}
for (ITestNGMethod m : l) {
// If they are in the same class hierarchy, they must belong to the same instance,
// otherwise, it's a method depending on a method in a different class so we
// don't bother checking the instance.
if (isSameInstance(fromMethod, m)
|| belongToDifferentClassHierarchy(fromMethod, m)
|| hasInstance(fromMethod, m)) {
return m;
}
}
throw new TestNGException(
"Method \"" + fromMethod + "\" depends on nonexistent method \"" + methodName + "\"");
}
private static boolean belongToDifferentClassHierarchy(
ITestNGMethod baseClassMethod, ITestNGMethod derivedClassMethod) {
return !baseClassMethod.getRealClass().isAssignableFrom(derivedClassMethod.getRealClass());
}
private static boolean hasInstance(
ITestNGMethod baseClassMethod, ITestNGMethod derivedClassMethod) {
Object baseInstance = baseClassMethod.getInstance();
Object derivedInstance = derivedClassMethod.getInstance();
return derivedInstance != null || baseInstance != null;
}
private static boolean isSameInstance(
ITestNGMethod baseClassMethod, ITestNGMethod derivedClassMethod) {
Object baseInstance = baseClassMethod.getInstance();
Object derivedInstance = derivedClassMethod.getInstance();
return derivedInstance != null
&& baseInstance != null
&& baseInstance.getClass().isAssignableFrom(derivedInstance.getClass());
}
private static String constructMethodNameUsingTestClass(
String currentMethodName, ITestNGMethod m) {
int lastIndex = currentMethodName.lastIndexOf('.');
if (lastIndex != -1) {
return m.getTestClass().getRealClass().getName() + currentMethodName.substring(lastIndex);
}
return currentMethodName;
}
}