Skip to content

Commit 44a2270

Browse files
amishra-ugithub-actions[bot]timtebeekJenson3210
authored
Fix JunitParams to Parameterized by recursively updating referenced method to static (#717)
* Fix JunitParams to Parameterized by recursively updating referenced method to static * Apply suggestions from code review Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> * add override * Apply suggestions from code review Co-authored-by: Jente Sondervorst <[email protected]> * Slight polish --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Tim te Beek <[email protected]> Co-authored-by: Jente Sondervorst <[email protected]> Co-authored-by: Tim te Beek <[email protected]>
1 parent 869f4a9 commit 44a2270

File tree

2 files changed

+201
-85
lines changed

2 files changed

+201
-85
lines changed

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

+63-12
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
*/
1616
package org.openrewrite.java.testing.junit5;
1717

18+
import lombok.RequiredArgsConstructor;
1819
import org.jspecify.annotations.Nullable;
1920
import org.openrewrite.*;
2021
import org.openrewrite.internal.ListUtils;
@@ -23,15 +24,14 @@
2324
import org.openrewrite.java.trait.Annotated;
2425
import org.openrewrite.java.trait.Literal;
2526
import org.openrewrite.java.trait.Traits;
26-
import org.openrewrite.java.tree.Expression;
27-
import org.openrewrite.java.tree.J;
28-
import org.openrewrite.java.tree.Space;
29-
import org.openrewrite.java.tree.TextComment;
27+
import org.openrewrite.java.tree.*;
3028
import org.openrewrite.marker.Markers;
3129

3230
import java.util.*;
3331
import java.util.stream.Collectors;
3432

33+
import static java.util.Collections.emptyList;
34+
3535
/**
3636
* Converts Pragmatists JUnitParamsRunner tests to their JUnit 5 ParameterizedTest and associated MethodSource equivalent
3737
* <a href="https://github.com/Pragmatists/JUnitParams">...</a>
@@ -121,7 +121,7 @@ public J.Annotation visitAnnotation(J.Annotation annotation, ExecutionContext ct
121121
}
122122
} else if (isSupportedCsvParam(annotated)) {
123123
anno = getCsVParamTemplate(ctx).apply(updateCursor(anno), anno.getCoordinates().replace(), anno.getArguments().get(0));
124-
classDeclCursor.putMessage(CSV_PARAMS, Boolean.TRUE);
124+
classDeclCursor.putMessage(CSV_PARAMS, Boolean.TRUE);
125125
} else if (anno.getArguments() != null && !anno.getArguments().isEmpty()) {
126126
// This conversion is not supported add a comment to the annotation and the method name to the not supported list
127127
String comment = " JunitParamsRunnerToParameterized conversion not supported";
@@ -241,6 +241,10 @@ public J.ClassDeclaration visitClassDeclaration(J.ClassDeclaration classDecl, Ex
241241
J.ClassDeclaration cd = super.visitClassDeclaration(classDecl, ctx);
242242
// Remove @RunWith(JUnitParamsRunner.class) annotation
243243
doAfterVisit(new RemoveAnnotationVisitor(RUN_WITH_JUNIT_PARAMS_ANNOTATION_MATCHER));
244+
List<String> methodNames = getCursor().getMessage(MakeMethodStatic.REFERENCED_METHODS, emptyList());
245+
if (cd.getType() != null && !methodNames.isEmpty()) {
246+
doAfterVisit(new MakeMethodStatic(cd.getType(), methodNames));
247+
}
244248

245249
// Update Imports
246250
maybeRemoveImport("org.junit.Test");
@@ -264,23 +268,22 @@ public J.MethodDeclaration visitMethodDeclaration(J.MethodDeclaration method, Ex
264268
J.MethodDeclaration m = super.visitMethodDeclaration(method, ctx);
265269
final String paramTestName = initMethodReferences.get(m.getSimpleName());
266270

267-
m = m.withLeadingAnnotations(ListUtils.map(m.getLeadingAnnotations(), anno -> {
271+
List<J.Annotation> annotations = ListUtils.map(m.getLeadingAnnotations(), anno -> {
268272
if (TEST_CASE_NAME_MATCHER.matches(anno) || NAMED_PARAMETERS_MATCHER.matches(anno)) {
269273
return null;
270274
}
271275
anno = maybeReplaceTestAnnotation(new Cursor(getCursor(), anno), paramTestName);
272276
anno = maybeReplaceParametersAnnotation(new Cursor(getCursor(), anno), method.getSimpleName());
273277
return anno;
274-
}));
278+
});
279+
m = m.withLeadingAnnotations(annotations);
275280

276281
// If the method is an init-method then add a static modifier if necessary
277282
if (initMethods.contains(m.getSimpleName()) || initMethodReferences.containsValue(m.getSimpleName())) {
278-
if (m.getModifiers().stream().noneMatch(it -> J.Modifier.Type.Static == it.getType())) {
279-
J.Modifier staticModifier = new J.Modifier(Tree.randomId(), Space.format(" "), Markers.EMPTY, null, J.Modifier.Type.Static, new ArrayList<>());
280-
m = maybeAutoFormat(m, m.withModifiers(ListUtils.concat(m.getModifiers(), staticModifier)), ctx, getCursor().getParentTreeCursor());
281-
}
283+
Cursor enclosingCursor = getCursor().dropParentUntil(J.ClassDeclaration.class::isInstance);
284+
enclosingCursor.computeMessageIfAbsent(MakeMethodStatic.REFERENCED_METHODS, k -> new ArrayList<>()).add(m.getSimpleName());
282285
}
283-
return m;
286+
return maybeAutoFormat(method, m, m.getName(), ctx, getCursor().getParentTreeCursor());
284287
}
285288

286289
private J.Annotation maybeReplaceTestAnnotation(Cursor anno, @Nullable String parameterizedTestArgument) {
@@ -340,4 +343,52 @@ private J.Annotation maybeReplaceParametersAnnotation(Cursor anno, String method
340343
}
341344

342345
}
346+
347+
@RequiredArgsConstructor
348+
private static class MakeMethodStatic extends JavaIsoVisitor<ExecutionContext> {
349+
350+
private static final String REFERENCED_METHODS = "referencedMethods";
351+
352+
private final JavaType.FullyQualified classType;
353+
private final List<String> methodNames;
354+
355+
@Override
356+
public J.ClassDeclaration visitClassDeclaration(J.ClassDeclaration classDeclaration, ExecutionContext ctx) {
357+
if (classDeclaration.getType() != classType) {
358+
return classDeclaration;
359+
}
360+
J.ClassDeclaration cd = super.visitClassDeclaration(classDeclaration, ctx);
361+
List<String> methodNames = getCursor().getMessage(REFERENCED_METHODS, emptyList());
362+
if (!methodNames.isEmpty()) {
363+
doAfterVisit(new MakeMethodStatic(classType, methodNames));
364+
}
365+
return cd;
366+
}
367+
368+
@Override
369+
public J.MethodDeclaration visitMethodDeclaration(J.MethodDeclaration method, ExecutionContext ctx) {
370+
if (!methodNames.contains(method.getSimpleName()) ||
371+
method.hasModifier(J.Modifier.Type.Static) ||
372+
method.getMethodType() == null ||
373+
method.getMethodType().getDeclaringType() != classType) {
374+
return method;
375+
}
376+
J.MethodDeclaration m = super.visitMethodDeclaration(method, ctx);
377+
J.Modifier staticModifier = new J.Modifier(Tree.randomId(), Space.SINGLE_SPACE, Markers.EMPTY, null, J.Modifier.Type.Static, new ArrayList<>());
378+
return m.withModifiers(ListUtils.concat(m.getModifiers(), staticModifier));
379+
}
380+
381+
@Override
382+
public J.MethodInvocation visitMethodInvocation(J.MethodInvocation method, ExecutionContext ctx) {
383+
J.MethodDeclaration enclosingMethod = getCursor().firstEnclosing(J.MethodDeclaration.class);
384+
if (enclosingMethod != null &&
385+
method.getMethodType() != null &&
386+
methodNames.contains(enclosingMethod.getSimpleName()) &&
387+
method.getMethodType().getDeclaringType() == classType) {
388+
Cursor classCursor = getCursor().dropParentUntil(j -> j instanceof J.ClassDeclaration);
389+
classCursor.computeMessageIfAbsent(REFERENCED_METHODS, k -> new ArrayList<>()).add(method.getSimpleName());
390+
}
391+
return super.visitMethodInvocation(method, ctx);
392+
}
393+
}
343394
}

src/test/java/org/openrewrite/java/testing/junit5/JUnitParamsRunnerToParameterizedTest.java

+138-73
Original file line numberDiff line numberDiff line change
@@ -197,34 +197,99 @@ private static Object named3() {
197197
);
198198
}
199199

200+
@Test
201+
void methodSourceWithInstanceAccess() {
202+
//language=java
203+
rewriteRun(
204+
java(
205+
"""
206+
import org.junit.Test;
207+
import org.junit.runner.RunWith;
208+
import java.time.LocalDateTime;
209+
import junitparams.JUnitParamsRunner;
210+
import junitparams.Parameters;
211+
import junitparams.NamedParameters;
212+
import junitparams.naming.TestCaseName;
213+
214+
@RunWith(JUnitParamsRunner.class)
215+
public class PersonTests {
216+
217+
@Test
218+
@Parameters(method = "youngAdultPersonParams")
219+
public void personIsAdult(int age, boolean valid) {
220+
}
221+
222+
private Object[] youngAdultPersonParams() {
223+
return new Object[]{new Object[]{getAge(2000), false}, new Object[]{getAge(2005), false}};
224+
}
225+
226+
private int getAge(int birthYear) {
227+
return getCurrentYear() - birthYear;
228+
}
229+
230+
private int getCurrentYear() {
231+
return LocalDateTime.now().getYear();
232+
}
233+
}
234+
""",
235+
"""
236+
import org.junit.jupiter.params.ParameterizedTest;
237+
import org.junit.jupiter.params.provider.MethodSource;
238+
239+
import java.time.LocalDateTime;
240+
241+
public class PersonTests {
242+
243+
@ParameterizedTest
244+
@MethodSource("youngAdultPersonParams")
245+
public void personIsAdult(int age, boolean valid) {
246+
}
247+
248+
private static Object[] youngAdultPersonParams() {
249+
return new Object[]{new Object[]{getAge(2000), false}, new Object[]{getAge(2005), false}};
250+
}
251+
252+
private static int getAge(int birthYear) {
253+
return getCurrentYear() - birthYear;
254+
}
255+
256+
private static int getCurrentYear() {
257+
return LocalDateTime.now().getYear();
258+
}
259+
}
260+
"""
261+
)
262+
);
263+
}
264+
200265
@Test
201266
void csvSource() {
202267
//language=java
203268
rewriteRun(
204269
java(
205270
"""
206-
import org.junit.Test;
207-
import org.junit.runner.RunWith;
208-
import junitparams.JUnitParamsRunner;
209-
import junitparams.Parameters;
210-
211-
@RunWith(JUnitParamsRunner.class)
212-
class CsvSourceTests {
213-
@Test
214-
@Parameters({"Lav,20", "Katy,25"})
215-
public void csvSource(String name, int age) { }
216-
}
217-
""",
271+
import org.junit.Test;
272+
import org.junit.runner.RunWith;
273+
import junitparams.JUnitParamsRunner;
274+
import junitparams.Parameters;
275+
276+
@RunWith(JUnitParamsRunner.class)
277+
class CsvSourceTests {
278+
@Test
279+
@Parameters({"Lav,20", "Katy,25"})
280+
public void csvSource(String name, int age) { }
281+
}
282+
""",
218283
"""
219-
import org.junit.jupiter.params.ParameterizedTest;
220-
import org.junit.jupiter.params.provider.CsvSource;
221-
222-
class CsvSourceTests {
223-
@ParameterizedTest
224-
@CsvSource({"Lav,20", "Katy,25"})
225-
public void csvSource(String name, int age) { }
226-
}
227-
"""
284+
import org.junit.jupiter.params.ParameterizedTest;
285+
import org.junit.jupiter.params.provider.CsvSource;
286+
287+
class CsvSourceTests {
288+
@ParameterizedTest
289+
@CsvSource({"Lav,20", "Katy,25"})
290+
public void csvSource(String name, int age) { }
291+
}
292+
"""
228293
)
229294
);
230295
}
@@ -235,28 +300,28 @@ void csvSourceWithExplicitValue() {
235300
rewriteRun(
236301
java(
237302
"""
238-
import org.junit.Test;
239-
import org.junit.runner.RunWith;
240-
import junitparams.JUnitParamsRunner;
241-
import junitparams.Parameters;
242-
243-
@RunWith(JUnitParamsRunner.class)
244-
class CsvSourceTests {
245-
@Test
246-
@Parameters(value = {"Lav,20", "Katy,25"})
247-
public void csvSource(String name, int age) { }
248-
}
249-
""",
303+
import org.junit.Test;
304+
import org.junit.runner.RunWith;
305+
import junitparams.JUnitParamsRunner;
306+
import junitparams.Parameters;
307+
308+
@RunWith(JUnitParamsRunner.class)
309+
class CsvSourceTests {
310+
@Test
311+
@Parameters(value = {"Lav,20", "Katy,25"})
312+
public void csvSource(String name, int age) { }
313+
}
314+
""",
250315
"""
251-
import org.junit.jupiter.params.ParameterizedTest;
252-
import org.junit.jupiter.params.provider.CsvSource;
253-
254-
class CsvSourceTests {
255-
@ParameterizedTest
256-
@CsvSource(value = {"Lav,20", "Katy,25"})
257-
public void csvSource(String name, int age) { }
258-
}
259-
"""
316+
import org.junit.jupiter.params.ParameterizedTest;
317+
import org.junit.jupiter.params.provider.CsvSource;
318+
319+
class CsvSourceTests {
320+
@ParameterizedTest
321+
@CsvSource(value = {"Lav,20", "Katy,25"})
322+
public void csvSource(String name, int age) { }
323+
}
324+
"""
260325
)
261326
);
262327
}
@@ -267,38 +332,38 @@ void csvSourceWithCustomConverterNotConverted() {
267332
rewriteRun(
268333
java(
269334
"""
270-
import org.junit.Test;
271-
import org.junit.runner.RunWith;
272-
import java.util.Date;
273-
import junitparams.converters.Param;
274-
import junitparams.JUnitParamsRunner;
275-
import junitparams.Parameters;
276-
import junitparams.converters.NullableConverter;
277-
278-
@RunWith(JUnitParamsRunner.class)
279-
class CsvSourceTests {
280-
@Test
281-
@Parameters({"01.12.2012"})
282-
public void csvSource(@Param(converter = NullableConverter.class) Date date) { }
283-
}
284-
""",
335+
import org.junit.Test;
336+
import org.junit.runner.RunWith;
337+
import java.util.Date;
338+
import junitparams.converters.Param;
339+
import junitparams.JUnitParamsRunner;
340+
import junitparams.Parameters;
341+
import junitparams.converters.NullableConverter;
342+
343+
@RunWith(JUnitParamsRunner.class)
344+
class CsvSourceTests {
345+
@Test
346+
@Parameters({"01.12.2012"})
347+
public void csvSource(@Param(converter = NullableConverter.class) Date date) { }
348+
}
349+
""",
285350
"""
286-
import org.junit.Test;
287-
import org.junit.runner.RunWith;
288-
import java.util.Date;
289-
import junitparams.converters.Param;
290-
import junitparams.JUnitParamsRunner;
291-
import junitparams.Parameters;
292-
import junitparams.converters.NullableConverter;
293-
294-
@RunWith(JUnitParamsRunner.class)
295-
class CsvSourceTests {
296-
@Test
297-
// JunitParamsRunnerToParameterized conversion not supported
298-
@Parameters({"01.12.2012"})
299-
public void csvSource(@Param(converter = NullableConverter.class) Date date) { }
300-
}
301-
"""
351+
import org.junit.Test;
352+
import org.junit.runner.RunWith;
353+
import java.util.Date;
354+
import junitparams.converters.Param;
355+
import junitparams.JUnitParamsRunner;
356+
import junitparams.Parameters;
357+
import junitparams.converters.NullableConverter;
358+
359+
@RunWith(JUnitParamsRunner.class)
360+
class CsvSourceTests {
361+
@Test
362+
// JunitParamsRunnerToParameterized conversion not supported
363+
@Parameters({"01.12.2012"})
364+
public void csvSource(@Param(converter = NullableConverter.class) Date date) { }
365+
}
366+
"""
302367
)
303368
);
304369
}

0 commit comments

Comments
 (0)