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;
}
}