Skip to content

Commit 5869a99

Browse files
HamcrestMatcherToAssertJ: isNull() and isNotNull() take no args (#864)
Correct migration to AssertJ's `isNull()` and `isNotNull()`. Fixes: #862
1 parent 6ea4619 commit 5869a99

File tree

2 files changed

+64
-16
lines changed

2 files changed

+64
-16
lines changed

src/main/java/org/openrewrite/java/testing/hamcrest/HamcrestMatcherToAssertJ.java

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,7 @@
2727
import org.openrewrite.java.tree.*;
2828
import org.openrewrite.marker.Markers;
2929

30-
import java.util.ArrayList;
31-
import java.util.List;
30+
import java.util.*;
3231

3332
import static java.util.stream.Collectors.joining;
3433

@@ -77,6 +76,9 @@ private class MigrateToAssertJVisitor extends JavaIsoVisitor<ExecutionContext> {
7776
private final MethodMatcher matchersMatcher = new MethodMatcher("org.hamcrest.*Matchers " + matcher + "(..)");
7877
private final MethodMatcher subMatcher = new MethodMatcher("org.hamcrest.*Matchers *(org.hamcrest.Matcher)");
7978

79+
// AssertJ assertions that don't take any arguments - matcher arguments should be ignored
80+
private final Set<String> noArgAssertions = new HashSet<>(Arrays.asList("isNotNull", "isNull"));
81+
8082
@Override
8183
public J.MethodInvocation visitMethodInvocation(J.MethodInvocation method, ExecutionContext ctx) {
8284
J.MethodInvocation mi = super.visitMethodInvocation(method, ctx);
@@ -100,11 +102,13 @@ private J.MethodInvocation replace(J.MethodInvocation mi, ExecutionContext ctx)
100102

101103
String actual = typeToIndicator(actualArgument.getType());
102104
J.MethodInvocation matcherArgumentMethod = (J.MethodInvocation) matcherArgument;
105+
boolean isNoArgAssertion = noArgAssertions.contains(assertion);
106+
String argsTemplate = isNoArgAssertion ? "" : getArgumentsTemplate(matcherArgumentMethod);
103107
JavaTemplate template = JavaTemplate.builder(String.format(
104108
"assertThat(%s)" +
105109
(reasonArgument != null ? ".as(#{any(String)})" : "") +
106110
".%s(%s)",
107-
actual, assertion, getArgumentsTemplate(matcherArgumentMethod)))
111+
actual, assertion, argsTemplate))
108112
.javaParser(JavaParser.fromJavaVersion().classpathFromResources(ctx, "assertj-core-3"))
109113
.staticImports(
110114
"org.assertj.core.api.Assertions.assertThat",
@@ -122,16 +126,19 @@ actual, assertion, getArgumentsTemplate(matcherArgumentMethod)))
122126
if (reasonArgument != null) {
123127
templateArguments.add(reasonArgument);
124128
}
125-
boolean isCloseTo = CLOSE_TO_MATCHER.matches(matcherArgumentMethod);
126-
List<Expression> matcherArgs = matcherArgumentMethod.getArguments();
127-
for (int i = 0; i < matcherArgs.size(); i++) {
128-
Expression originalArgument = matcherArgs.get(i);
129-
if (!(originalArgument instanceof J.Empty)) {
130-
// For closeTo, the tolerance (second argument) type must match the actual value type for within()
131-
if (isCloseTo && i == 1) {
132-
templateArguments.add(ensureMatchingNumericType(originalArgument, actualArgument.getType()));
133-
} else {
134-
templateArguments.add(originalArgument);
129+
// Skip adding matcher arguments for assertions that don't take any arguments
130+
if (!isNoArgAssertion) {
131+
boolean isCloseTo = CLOSE_TO_MATCHER.matches(matcherArgumentMethod);
132+
List<Expression> matcherArgs = matcherArgumentMethod.getArguments();
133+
for (int i = 0; i < matcherArgs.size(); i++) {
134+
Expression originalArgument = matcherArgs.get(i);
135+
if (!(originalArgument instanceof J.Empty)) {
136+
// For closeTo, the tolerance (second argument) type must match the actual value type for within()
137+
if (isCloseTo && i == 1) {
138+
templateArguments.add(ensureMatchingNumericType(originalArgument, actualArgument.getType()));
139+
} else {
140+
templateArguments.add(originalArgument);
141+
}
135142
}
136143
}
137144
}
@@ -140,7 +147,7 @@ actual, assertion, getArgumentsTemplate(matcherArgumentMethod)))
140147

141148
private final MethodMatcher CLOSE_TO_MATCHER = new MethodMatcher("org.hamcrest.Matchers closeTo(..)");
142149

143-
private Expression ensureMatchingNumericType(Expression toleranceExpr, JavaType actualType) {
150+
private Expression ensureMatchingNumericType(Expression toleranceExpr, @Nullable JavaType actualType) {
144151
JavaType toleranceType = toleranceExpr.getType();
145152
// Only cast if the actual value is a double/float and tolerance is an integer type
146153
if ((actualType == JavaType.Primitive.Double || TypeUtils.isOfClassType(actualType, "java.lang.Double")) &&
@@ -175,14 +182,14 @@ private String getArgumentsTemplate(J.MethodInvocation matcherArgument) {
175182
.collect(joining(", "));
176183
}
177184

178-
private String typeToIndicator(JavaType type) {
185+
private String typeToIndicator(@Nullable JavaType type) {
179186
if (type instanceof JavaType.Array) {
180187
type = ((JavaType.Array) type).getElemType();
181188
String str = type instanceof JavaType.Primitive || type.toString().startsWith("java.") ?
182189
type.toString().replaceAll("<.*>", "") : "java.lang.Object";
183190
return String.format("#{anyArray(%s)}", str);
184191
}
185-
if (type instanceof JavaType.Primitive || type.toString().startsWith("java.")) {
192+
if (type instanceof JavaType.Primitive || type != null && type.toString().startsWith("java.")) {
186193
return "#{any()}";
187194
}
188195
return "#{any(java.lang.Object)}";

src/test/java/org/openrewrite/java/testing/hamcrest/HamcrestMatcherToAssertJTest.java

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -635,4 +635,45 @@ String reason() {
635635
);
636636
}
637637
}
638+
639+
@Nested
640+
class NoArguments {
641+
@Issue("https://github.com/openrewrite/rewrite-testing-frameworks/issues/862")
642+
@Test
643+
void notNullValueWithClassArgument() {
644+
rewriteRun(
645+
spec -> spec.recipe(new HamcrestMatcherToAssertJ("notNullValue", "isNotNull", null)),
646+
//language=java
647+
java(
648+
"""
649+
import org.junit.jupiter.api.Test;
650+
651+
import static org.hamcrest.MatcherAssert.assertThat;
652+
import static org.hamcrest.Matchers.notNullValue;
653+
654+
class ATest {
655+
@Test
656+
void test() {
657+
String str = "Hello world!";
658+
assertThat(str, notNullValue(String.class));
659+
}
660+
}
661+
""",
662+
"""
663+
import org.junit.jupiter.api.Test;
664+
665+
import static org.assertj.core.api.Assertions.assertThat;
666+
667+
class ATest {
668+
@Test
669+
void test() {
670+
String str = "Hello world!";
671+
assertThat(str).isNotNull();
672+
}
673+
}
674+
"""
675+
)
676+
);
677+
}
678+
}
638679
}

0 commit comments

Comments
 (0)