Skip to content

Commit

Permalink
Honour regex in dependsOnMethods
Browse files Browse the repository at this point in the history
  • Loading branch information
krmahadevan committed Nov 23, 2022
1 parent e4adf0f commit c13daf0
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 31 deletions.
3 changes: 2 additions & 1 deletion CHANGES.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
Current
Fixed: GITHUB-141: regular expression in "dependsOnMethods" does not work (Krishnan Mahadevan)
Fixed: GITHUB-2770: FileAlreadyExistsException when report is generated (melloware)
Fixed: GITHUB-2825: Programically Loading TestNG Suite from JAR File Fails to Delete Temporary Copy of Suite File (Steven Jubb)
Fixed: GITHUB-2825: Programmatically Loading TestNG Suite from JAR File Fails to Delete Temporary Copy of Suite File (Steven Jubb)
Fixed: GITHUB-2818: Add configuration key for callback discrepancy behavior (Krishnan Mahadevan)
Fixed: GITHUB-2819: Ability to retry a data provider in case of failures (Krishnan Mahadevan)
Fixed: GITHUB-2308: StringIndexOutOfBoundsException in findClassesInPackage - Surefire/Maven - JDK 11 fails (Krishnan Mahadevan)
Expand Down
67 changes: 37 additions & 30 deletions testng-core/src/main/java/org/testng/DependencyMap.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package org.testng;

import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import org.testng.collections.ListMultiMap;
Expand All @@ -24,36 +22,39 @@ public DependencyMap(ITestNGMethod[] methods) {
}

public List<ITestNGMethod> getMethodsThatBelongTo(String group, ITestNGMethod fromMethod) {
Set<String> uniqueKeys = m_groups.keySet();
Pattern pattern = Pattern.compile(group);

List<ITestNGMethod> result =
m_groups.keySet().stream()
.parallel()
.filter(k -> pattern.matcher(k).matches())
.flatMap(k -> m_groups.get(k).stream())
m_groups
.entrySet()
.parallelStream()
.filter(entry -> pattern.matcher(entry.getKey()).matches())
.flatMap(entry -> entry.getValue().stream())
.collect(Collectors.toList());

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

public ITestNGMethod getMethodDependingOn(String methodName, ITestNGMethod fromMethod) {
List<ITestNGMethod> l = m_dependencies.get(methodName);
if (l.isEmpty()) {
Pattern pattern = Pattern.compile(methodName);
l =
m_dependencies
.entrySet()
.parallelStream()
.filter(entry -> methodNameMatch(pattern, entry.getKey()))
.flatMap(entry -> entry.getValue().stream())
.collect(Collectors.toList());
}
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.
Expand All @@ -64,26 +65,32 @@ public ITestNGMethod getMethodDependingOn(String methodName, ITestNGMethod fromM
if (l.isEmpty() && fromMethod.ignoreMissingDependencies()) {
return fromMethod;
}
Optional<ITestNGMethod> found =
l.stream()
.parallel()
.filter(
m ->
isSameInstance(fromMethod, m)
|| belongToDifferentClassHierarchy(fromMethod, m)
|| hasInstance(fromMethod, m))
.findFirst();
if (found.isPresent()) {
return found.get();
}
return l.parallelStream()
.filter(
m ->
isSameInstance(fromMethod, m)
|| belongToDifferentClassHierarchy(fromMethod, m)
|| hasInstance(fromMethod, m))
.findFirst()
.orElseThrow(
() ->
new TestNGException(
"Method \""
+ fromMethod
+ "\" depends on nonexistent method \""
+ methodName
+ "\""));
}

throw new TestNGException(
"Method \"" + fromMethod + "\" depends on nonexistent method \"" + methodName + "\"");
private static boolean methodNameMatch(Pattern pattern, String method) {
String justMethodName = method.substring(method.lastIndexOf(".") + 1);
return pattern.matcher(justMethodName).matches();
}

private static boolean belongToDifferentClassHierarchy(
ITestNGMethod baseClassMethod, ITestNGMethod derivedClassMethod) {
return !baseClassMethod.getRealClass().isAssignableFrom(derivedClassMethod.getRealClass());
Class<?> left = baseClassMethod.getRealClass();
return !left.isAssignableFrom(derivedClassMethod.getRealClass());
}

private static boolean hasInstance(
Expand Down
10 changes: 10 additions & 0 deletions testng-core/src/test/java/test/dependent/DependentTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,21 @@
import test.dependent.github1380.GitHub1380Sample2;
import test.dependent.github1380.GitHub1380Sample3;
import test.dependent.github1380.GitHub1380Sample4;
import test.dependent.issue141.TestClassSample;
import test.dependent.issue2658.FailingClassSample;
import test.dependent.issue2658.PassingClassSample;

public class DependentTest extends SimpleBaseTest {

@Test(description = "GITHUB-141")
public void ensureDependsOnMethodsHonoursRegexPatterns() {
TestNG testng = create(TestClassSample.class);
MethodNameCollector listener = new MethodNameCollector();
testng.addListener(listener);
testng.run();
assertThat(listener.getPassedNames()).containsExactly("test_C6390323", "randomTest");
}

@Test
public void simpleSkip() {
TestNG testng = create(SampleDependent1.class);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package test.dependent.issue141;

import org.testng.annotations.Test;

public class TestClassSample {

@Test(dependsOnMethods = "test_C[0-9]{7}")
public void randomTest() {}

@Test
public void test_C6390323() {}
}

0 comments on commit c13daf0

Please sign in to comment.