Skip to content

Commit 3982f0e

Browse files
committed
Update ParameterizedRunnerToParameterized to handle nested parameterized tests. Fixes #163
1 parent 71b2347 commit 3982f0e

File tree

2 files changed

+166
-14
lines changed

2 files changed

+166
-14
lines changed

src/main/java/org/openrewrite/java/testing/junit5/ParameterizedRunnerToParameterized.java

Lines changed: 31 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -67,25 +67,26 @@ protected TreeVisitor<?, ExecutionContext> getVisitor() {
6767
}
6868

6969
private static class ParameterizedRunnerVisitor extends JavaIsoVisitor<ExecutionContext> {
70+
@SuppressWarnings("unchecked")
7071
@Override
7172
public J.ClassDeclaration visitClassDeclaration(J.ClassDeclaration classDecl, ExecutionContext executionContext) {
7273
J.ClassDeclaration cd = super.visitClassDeclaration(classDecl, executionContext);
73-
74-
String parametersMethodName = getCursor().pollMessage(PARAMETERS_METHOD_NAME);
75-
List<Expression> parametersAnnotationArguments = getCursor().pollMessage(PARAMETERS_ANNOTATION_ARGUMENTS);
76-
List<Statement> constructorParams = getCursor().pollMessage(CONSTRUCTOR_ARGUMENTS);
77-
Map<Integer, Statement> fieldInjectionParams = getCursor().pollMessage(FIELD_INJECTION_ARGUMENTS);
74+
Map<String, Object> params = getCursor().pollMessage(classDecl.getId().toString());
75+
String parametersMethodName = params != null ? (String)params.get(PARAMETERS_METHOD_NAME) : null;
76+
List<Expression> parametersAnnotationArguments = params != null ? (List<Expression>)params.get(PARAMETERS_ANNOTATION_ARGUMENTS) : null;
77+
List<Statement> constructorParams = params != null ? (List<Statement>)params.get(CONSTRUCTOR_ARGUMENTS) : null;
78+
Map<Integer, Statement> fieldInjectionParams = params != null ? (Map<Integer, Statement>)params.get(FIELD_INJECTION_ARGUMENTS) : null;
7879
String initMethodName = "init" + cd.getSimpleName();
7980

8081
// Constructor Injected Test
8182
if (parametersMethodName != null && constructorParams != null) {
82-
doAfterVisit(new ParameterizedRunnerToParameterizedTestsVisitor(parametersMethodName, initMethodName, parametersAnnotationArguments, constructorParams, true));
83+
doAfterVisit(new ParameterizedRunnerToParameterizedTestsVisitor(classDecl, parametersMethodName, initMethodName, parametersAnnotationArguments, constructorParams, true));
8384
}
8485

8586
// Field Injected Test
8687
else if (parametersMethodName != null && fieldInjectionParams != null) {
8788
List<Statement> fieldParams = new ArrayList<>(fieldInjectionParams.values());
88-
doAfterVisit(new ParameterizedRunnerToParameterizedTestsVisitor(parametersMethodName, initMethodName, parametersAnnotationArguments, fieldParams, false));
89+
doAfterVisit(new ParameterizedRunnerToParameterizedTestsVisitor(classDecl, parametersMethodName, initMethodName, parametersAnnotationArguments, fieldParams, false));
8990
}
9091
return cd;
9192
}
@@ -94,15 +95,16 @@ else if (parametersMethodName != null && fieldInjectionParams != null) {
9495
public J.MethodDeclaration visitMethodDeclaration(J.MethodDeclaration method, ExecutionContext executionContext) {
9596
J.MethodDeclaration m = super.visitMethodDeclaration(method, executionContext);
9697
Cursor classDeclCursor = getCursor().dropParentUntil(J.ClassDeclaration.class::isInstance);
98+
Map<String, Object> params = classDeclCursor.computeMessageIfAbsent(((J.ClassDeclaration)classDeclCursor.getValue()).getId().toString(), v->new HashMap<>());
9799
for (J.Annotation annotation : m.getLeadingAnnotations()) {
98100
if (PARAMETERS.matches(annotation)) {
99-
classDeclCursor.putMessage(PARAMETERS_ANNOTATION_ARGUMENTS, annotation.getArguments());
100-
classDeclCursor.putMessage(PARAMETERS_METHOD_NAME, method.getSimpleName());
101+
params.put(PARAMETERS_ANNOTATION_ARGUMENTS, annotation.getArguments());
102+
params.put(PARAMETERS_METHOD_NAME, method.getSimpleName());
101103
}
102104
}
103105

104106
if (m.isConstructor()) {
105-
classDeclCursor.putMessage(CONSTRUCTOR_ARGUMENTS, m.getParameters());
107+
params.put(CONSTRUCTOR_ARGUMENTS, m.getParameters());
106108
}
107109
return m;
108110
}
@@ -111,6 +113,7 @@ public J.MethodDeclaration visitMethodDeclaration(J.MethodDeclaration method, Ex
111113
public J.VariableDeclarations visitVariableDeclarations(J.VariableDeclarations multiVariable, ExecutionContext executionContext) {
112114
J.VariableDeclarations variableDeclarations = super.visitVariableDeclarations(multiVariable, executionContext);
113115
Cursor classDeclCursor = getCursor().dropParentUntil(J.ClassDeclaration.class::isInstance);
116+
Map<String, Object> params = classDeclCursor.computeMessageIfAbsent(((J.ClassDeclaration)classDeclCursor.getValue()).getId().toString(), v -> new HashMap<>());
114117
J.Annotation parameterAnnotation = variableDeclarations.getLeadingAnnotations().stream().filter(PARAMETER::matches).findFirst().orElse(null);
115118
if (parameterAnnotation != null) {
116119
Integer position = 0;
@@ -127,13 +130,16 @@ public J.VariableDeclarations visitVariableDeclarations(J.VariableDeclarations m
127130
if (variableForInitMethod.getTypeExpression() != null) {
128131
variableForInitMethod = variableForInitMethod.withTypeExpression(variableForInitMethod.getTypeExpression().withPrefix(Space.EMPTY).withComments(new ArrayList<>()));
129132
}
130-
classDeclCursor.computeMessageIfAbsent(FIELD_INJECTION_ARGUMENTS, v -> new TreeMap<Integer, Statement>()).put(position, variableForInitMethod);
133+
//noinspection unchecked
134+
((TreeMap<Integer, Statement>) params.computeIfAbsent(FIELD_INJECTION_ARGUMENTS, v -> new TreeMap<Integer, Statement>())).put(position, variableForInitMethod);
135+
131136
}
132137
return variableDeclarations;
133138
}
134139
}
135140

136141
private static class ParameterizedRunnerToParameterizedTestsVisitor extends JavaIsoVisitor<ExecutionContext> {
142+
private final J.ClassDeclaration scope;
137143
private final String initMethodName;
138144
private final List<Statement> parameterizedTestMethodParameters;
139145
private final String initStatementParamString;
@@ -145,11 +151,13 @@ private static class ParameterizedRunnerToParameterizedTestsVisitor extends Java
145151
@Nullable
146152
private final JavaTemplate initMethodDeclarationTemplate;
147153

148-
public ParameterizedRunnerToParameterizedTestsVisitor(String parametersMethodName,
154+
public ParameterizedRunnerToParameterizedTestsVisitor(J.ClassDeclaration scope,
155+
String parametersMethodName,
149156
String initMethodName,
150157
@Nullable List<Expression> parameterizedTestAnnotationParameters,
151158
List<Statement> parameterizedTestMethodParameters,
152159
boolean isConstructorInjection) {
160+
this.scope = scope;
153161
this.initMethodName = initMethodName;
154162

155163
this.parameterizedTestMethodParameters = parameterizedTestMethodParameters.stream()
@@ -231,6 +239,10 @@ public J.CompilationUnit visitCompilationUnit(J.CompilationUnit cu, ExecutionCon
231239
@Override
232240
public J.ClassDeclaration visitClassDeclaration(J.ClassDeclaration classDecl, ExecutionContext executionContext) {
233241
J.ClassDeclaration cd = super.visitClassDeclaration(classDecl, executionContext);
242+
if (!scope.isScope(classDecl)) {
243+
return cd;
244+
}
245+
234246

235247
if (initMethodDeclarationTemplate != null) {
236248
cd = maybeAutoFormat(cd, cd.withBody(cd.getBody().withTemplate(initMethodDeclarationTemplate,
@@ -257,6 +269,10 @@ public J.ClassDeclaration visitClassDeclaration(J.ClassDeclaration classDecl, Ex
257269
@Override
258270
public J.VariableDeclarations visitVariableDeclarations(J.VariableDeclarations multiVariable, ExecutionContext executionContext) {
259271
J.VariableDeclarations vdecls = super.visitVariableDeclarations(multiVariable, executionContext);
272+
if (!getCursor().dropParentUntil(J.ClassDeclaration.class::isInstance).isScopeInPath(scope)) {
273+
return vdecls;
274+
}
275+
260276
final AtomicReference<Space> annoPrefix = new AtomicReference<>();
261277
vdecls = vdecls.withLeadingAnnotations(ListUtils.map(vdecls.getLeadingAnnotations(), anno -> {
262278
if (PARAMETER.matches(anno)) {
@@ -274,7 +290,9 @@ public J.VariableDeclarations visitVariableDeclarations(J.VariableDeclarations m
274290
@Override
275291
public J.MethodDeclaration visitMethodDeclaration(J.MethodDeclaration method, ExecutionContext executionContext) {
276292
J.MethodDeclaration m = super.visitMethodDeclaration(method, executionContext);
277-
293+
if (!getCursor().dropParentUntil(J.ClassDeclaration.class::isInstance).isScopeInPath(scope)) {
294+
return m;
295+
}
278296
// Replace @Test with @ParameterizedTest
279297
m = m.withLeadingAnnotations(ListUtils.map(m.getLeadingAnnotations(), annotation -> {
280298
if (JUPITER_TEST.matches(annotation) || JUNIT_TEST.matches(annotation)) {
@@ -318,7 +336,6 @@ public J.MethodDeclaration visitMethodDeclaration(J.MethodDeclaration method, Ex
318336
getCursor().dropParentUntil(J.ClassDeclaration.class::isInstance).putMessage("INIT_VARS", fieldNames);
319337
}
320338
}
321-
322339
return m;
323340
}
324341
}

src/test/kotlin/org/openrewrite/java/testing/junit5/ParameterizedRunnerToParameterizedTest.kt

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
package org.openrewrite.java.testing.junit5
1717

1818
import org.junit.jupiter.api.Test
19+
import org.openrewrite.Issue
1920
import org.openrewrite.Recipe
2021
import org.openrewrite.java.JavaParser
2122
import org.openrewrite.java.JavaRecipeTest
@@ -325,4 +326,138 @@ class ParameterizedRunnerToParameterizedTest : JavaRecipeTest {
325326
""",
326327
skipEnhancedTypeValidation = true
327328
)
329+
330+
@Issue("https://github.com/openrewrite/rewrite-testing-frameworks/issues/163")
331+
@Test
332+
fun nestedRunners() = assertChanged(
333+
before = """
334+
import java.util.Collection;
335+
import org.junit.Assert;
336+
import org.junit.BeforeClass;
337+
import org.junit.Test;
338+
import org.junit.runner.RunWith;
339+
import org.junit.runners.Parameterized;
340+
341+
public class NestedTests {
342+
@BeforeClass
343+
public static void setup() {
344+
}
345+
346+
public static abstract class T1 extends NestedTests {
347+
final String path;
348+
public T1(String path) {
349+
this.path = path;
350+
}
351+
@Test
352+
public void test() {
353+
Assert.assertNotNull(path);
354+
}
355+
}
356+
357+
static List<Object[]> valuesDataProvider() {
358+
List<Object[]> params = new ArrayList<>();
359+
params.add(new Object[] { "1", "2" });
360+
return params;
361+
}
362+
363+
@RunWith(Parameterized.class)
364+
public static class I1 extends T1 {
365+
@Parameterized.Parameters(name = "{index}: {0}[{1}] = {2}")
366+
public static Collection<Object[]> data1() {
367+
return valuesDataProvider();
368+
}
369+
public I1(String path) {
370+
super(path);
371+
}
372+
@Test
373+
public void testI() {
374+
Assert.assertNotNull(path);
375+
}
376+
}
377+
378+
@RunWith(Parameterized.class)
379+
public static class I2 extends NestedTests {
380+
@Parameterized.Parameters(name = "{index}: {0}[{1}] = {2}")
381+
public static Collection<Object[]> data2() {
382+
return valuesDataProvider();
383+
}
384+
final String path;
385+
public I2(String path) {
386+
this.path = path;
387+
}
388+
@Test
389+
public void testI2() {
390+
Assert.assertNotNull(path);
391+
}
392+
}
393+
}
394+
""",
395+
after = """
396+
import java.util.Collection;
397+
import org.junit.Assert;
398+
import org.junit.BeforeClass;
399+
import org.junit.Test;
400+
import org.junit.jupiter.params.ParameterizedTest;
401+
import org.junit.jupiter.params.provider.MethodSource;
402+
403+
public class NestedTests {
404+
@BeforeClass
405+
public static void setup() {
406+
}
407+
408+
public static abstract class T1 extends NestedTests {
409+
final String path;
410+
public T1(String path) {
411+
this.path = path;
412+
}
413+
@Test
414+
public void test() {
415+
Assert.assertNotNull(path);
416+
}
417+
}
418+
419+
static List<Object[]> valuesDataProvider() {
420+
List<Object[]> params = new ArrayList<>();
421+
params.add(new Object[] { "1", "2" });
422+
return params;
423+
}
424+
425+
public static class I1 extends T1 {
426+
public static Collection<Object[]> data1() {
427+
return valuesDataProvider();
428+
}
429+
430+
public void initI1(String path) {
431+
super(path);
432+
}
433+
434+
@MethodSource("data1")
435+
@ParameterizedTest(name = "{index}: {0}[{1}] = {2}")
436+
public void testI(String path) {
437+
initI1(path);
438+
Assert.assertNotNull(path);
439+
}
440+
}
441+
442+
public static class I2 extends NestedTests {
443+
public static Collection<Object[]> data2() {
444+
return valuesDataProvider();
445+
}
446+
String path;
447+
448+
public void initI2(String path) {
449+
this.path = path;
450+
}
451+
452+
@MethodSource("data2")
453+
@ParameterizedTest(name = "{index}: {0}[{1}] = {2}")
454+
public void testI2(String path) {
455+
initI2(path);
456+
Assert.assertNotNull(path);
457+
}
458+
}
459+
}
460+
""",
461+
skipEnhancedTypeValidation = true
462+
)
328463
}

0 commit comments

Comments
 (0)