2727import org .openrewrite .java .tree .*;
2828import org .openrewrite .marker .Markers ;
2929
30- import java .util .ArrayList ;
31- import java .util .List ;
30+ import java .util .*;
3231
3332import 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)}" ;
0 commit comments