-
Notifications
You must be signed in to change notification settings - Fork 75
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* WIP: Add recipe for migration from Hamcrest Work in progress implementation of a recipe which migrates Hamcrest test matchers to JUnit5 test assertions. Signed-off-by: matus.matok <[email protected]> * Add missing license headers * Resolve some of the test issues * Fix test import * Add proto implementation for assertEquals Added a prototype-y implementation of translation from hamcrest's equalTo to JUnit5's assertEquals. Should be easy to add more of the simple hamcrest matchers to this implementation. \TODO the import is not being added Signed-off-by: matus.matok <[email protected]> * Use static import and #{any(java.lang.Object)} to fix test * Adapt to main Another iteration of the prototype. Adapted it to be based on the up-to-date main. Added a proposal of how similar simple matchers could be translated to junit assertion methods. Signed-off-by: matus.matok <[email protected]> * Add more simple matcher-to-method translations Added translations for matchers closeTo, containsString, empty, emptyArray, emptyIterable, emptyCollectionOf, emptyIterableOf, endsWith. Tests need to be added for each matcher. Signed-off-by: matus.matok <[email protected]> * Add more simple matcher-to-method translations Added all the simple matcher-to-method translations. Tests need to be added for each matcher. Signed-off-by: matus.matok <[email protected]> * Add tests Added a bunch of tests, to verify the correctness of each matcher-to-assertion case. Signed-off-by: matus.matok <[email protected]> * Finalise the pull request Added all the necessary unit tests and polished out the implementation. Signed-off-by: matus.matok <[email protected]> * Add required license header * Move classes to align with the Hamcrest to AssertJ implementation * Consistently use `class Test` to avoid conflicts with `@Test` * Refactored and split HamcrestMatcherToJUnit5 recipe Refactored HamcrestMatcherToJUnit5 recipe, so now the whole translation is stored in one place, not scatter amongst three methods. Given the existence of RemoveIsMatcher Recipe, this recipe relies that it will never encounter is() matcher. In similar fashion as RemoveIsMatcher, RemoveNotMatcher was added, which does exactly the same as RemoveIsMatcher, but it also stores the logical context for the nested matcher (so that it knows it was negated) in execution context. Matchers instanceOf and isA were difficult to handle within the HamcrestMatcherToJUnit5 recipe, therefore these cases were moved to a newly added HamcrestInstanceOfToJUnit5 recipe. Signed-off-by: matus.matok <[email protected]> * Add license headers Forgot, added now Signed-off-by: matus.matok <[email protected]> * Apply suggestions from code review Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> * Apply suggestions from code review Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> * Fix compilation * Update description to use JUnit * Apply suggestions from code review Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> * Format tests * Drop RemoveNotMatcher recipe; retain visitor only To avoid misuse * Drop AssertThatBooleanToJUnit5; replace with declarative recipes * Apply suggestions from code review Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> * Limit execution through preconditions * Add preconditions to HamcrestMatcherToJUnit5 * Minor polish * Extract and reuse `ConsistentHamcrestMatcherImports` * Polish recipe display name and description --------- Signed-off-by: matus.matok <[email protected]> Co-authored-by: Tim te Beek <[email protected]> Co-authored-by: Tim te Beek <[email protected]> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
- Loading branch information
1 parent
1d1b915
commit f0d765a
Showing
8 changed files
with
1,757 additions
and
10 deletions.
There are no files selected for viewing
116 changes: 116 additions & 0 deletions
116
src/main/java/org/openrewrite/java/testing/hamcrest/HamcrestInstanceOfToJUnit5.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
/* | ||
* Copyright 2023 the original author or authors. | ||
* <p> | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* <p> | ||
* https://www.apache.org/licenses/LICENSE-2.0 | ||
* <p> | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
package org.openrewrite.java.testing.hamcrest; | ||
|
||
import org.openrewrite.ExecutionContext; | ||
import org.openrewrite.Preconditions; | ||
import org.openrewrite.Recipe; | ||
import org.openrewrite.TreeVisitor; | ||
import org.openrewrite.java.JavaIsoVisitor; | ||
import org.openrewrite.java.JavaParser; | ||
import org.openrewrite.java.JavaTemplate; | ||
import org.openrewrite.java.MethodMatcher; | ||
import org.openrewrite.java.search.UsesMethod; | ||
import org.openrewrite.java.tree.Expression; | ||
import org.openrewrite.java.tree.J; | ||
|
||
import java.util.ArrayList; | ||
import java.util.List; | ||
|
||
public class HamcrestInstanceOfToJUnit5 extends Recipe { | ||
@Override | ||
public String getDisplayName() { | ||
return "Migrate from Hamcrest `instanceOf` matcher to JUnit 5"; | ||
} | ||
|
||
@Override | ||
public String getDescription() { | ||
return "Migrate from Hamcrest `instanceOf` and `isA` matcher to JUnit5 `assertInstanceOf` assertion."; | ||
} | ||
|
||
private static final MethodMatcher INSTANCE_OF_MATCHER = new MethodMatcher("org.hamcrest.Matchers instanceOf(..)"); | ||
private static final MethodMatcher IS_A_MATCHER = new MethodMatcher("org.hamcrest.Matchers isA(..)"); | ||
private static final MethodMatcher ASSERT_THAT_MATCHER = new MethodMatcher("org.hamcrest.MatcherAssert assertThat(.., org.hamcrest.Matcher)"); | ||
|
||
@Override | ||
public TreeVisitor<?, ExecutionContext> getVisitor() { | ||
TreeVisitor<?, ExecutionContext> preconditions = Preconditions.and( | ||
new UsesMethod<>(ASSERT_THAT_MATCHER), | ||
Preconditions.or( | ||
new UsesMethod<>(INSTANCE_OF_MATCHER), | ||
new UsesMethod<>(IS_A_MATCHER))); | ||
return Preconditions.check(preconditions, new JavaIsoVisitor<ExecutionContext>() { | ||
@Override | ||
public J.MethodInvocation visitMethodInvocation(J.MethodInvocation mi, ExecutionContext ctx) { | ||
if (ASSERT_THAT_MATCHER.matches(mi)) { | ||
Expression reason; | ||
Expression examinedObject; | ||
Expression hamcrestMatcher; | ||
|
||
if (mi.getArguments().size() == 2) { | ||
reason = null; | ||
examinedObject = mi.getArguments().get(0); | ||
hamcrestMatcher = mi.getArguments().get(1); | ||
} else if (mi.getArguments().size() == 3) { | ||
reason = mi.getArguments().get(0); | ||
examinedObject = mi.getArguments().get(1); | ||
hamcrestMatcher = mi.getArguments().get(2); | ||
} else { | ||
return mi; | ||
} | ||
|
||
J.MethodInvocation matcherInvocation = (J.MethodInvocation) hamcrestMatcher; | ||
while ("not".equals(matcherInvocation.getSimpleName())) { | ||
maybeRemoveImport("org.hamcrest.Matchers.not"); | ||
maybeRemoveImport("org.hamcrest.CoreMatchers.not"); | ||
matcherInvocation = (J.MethodInvocation) new RemoveNotMatcherVisitor().visit(matcherInvocation, ctx); | ||
} | ||
|
||
if (INSTANCE_OF_MATCHER.matches(matcherInvocation) || IS_A_MATCHER.matches(matcherInvocation)) { | ||
boolean logicalContext = RemoveNotMatcherVisitor.getLogicalContext(matcherInvocation, ctx); | ||
|
||
String templateString = (logicalContext ? | ||
"assertInstanceOf(#{any(java.lang.Class)}, #{any(java.lang.Object)}" : | ||
"assertFalse(#{any(java.lang.Class)}.isAssignableFrom(#{any(java.lang.Object)}.getClass())") + | ||
(reason == null ? ")" : ", #{any(java.lang.String)})"); | ||
|
||
JavaTemplate template = JavaTemplate.builder(templateString) | ||
.javaParser(JavaParser.fromJavaVersion().classpathFromResources(ctx, "junit-jupiter-api-5.9")) | ||
.staticImports("org.junit.jupiter.api.Assertions." + (logicalContext ? "assertInstanceOf" : "assertFalse")) | ||
.build(); | ||
|
||
maybeRemoveImport("org.hamcrest.MatcherAssert.assertThat"); | ||
maybeRemoveImport("org.hamcrest.Matchers.instanceOf"); | ||
maybeRemoveImport("org.hamcrest.CoreMatchers.instanceOf"); | ||
maybeRemoveImport("org.hamcrest.Matchers.isA"); | ||
maybeRemoveImport("org.hamcrest.CoreMatchers.isA"); | ||
maybeAddImport("org.junit.jupiter.api.Assertions", logicalContext ? "assertInstanceOf" : "assertFalse"); | ||
|
||
List<Expression> arguments = new ArrayList<>(); | ||
arguments.add(matcherInvocation.getArguments().get(0)); | ||
arguments.add(examinedObject); | ||
if (reason != null) { | ||
arguments.add(reason); | ||
} | ||
|
||
return template.apply(getCursor(), mi.getCoordinates().replace(), arguments.toArray()); | ||
} | ||
} | ||
return super.visitMethodInvocation(mi, ctx); | ||
} | ||
}); | ||
} | ||
} |
191 changes: 191 additions & 0 deletions
191
src/main/java/org/openrewrite/java/testing/hamcrest/HamcrestMatcherToJUnit5.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,191 @@ | ||
/* | ||
* Copyright 2023 the original author or authors. | ||
* <p> | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* <p> | ||
* https://www.apache.org/licenses/LICENSE-2.0 | ||
* <p> | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
package org.openrewrite.java.testing.hamcrest; | ||
|
||
import org.openrewrite.ExecutionContext; | ||
import org.openrewrite.Preconditions; | ||
import org.openrewrite.Recipe; | ||
import org.openrewrite.TreeVisitor; | ||
import org.openrewrite.java.JavaIsoVisitor; | ||
import org.openrewrite.java.JavaParser; | ||
import org.openrewrite.java.JavaTemplate; | ||
import org.openrewrite.java.MethodMatcher; | ||
import org.openrewrite.java.search.UsesMethod; | ||
import org.openrewrite.java.tree.Expression; | ||
import org.openrewrite.java.tree.J; | ||
|
||
import java.util.ArrayList; | ||
import java.util.HashMap; | ||
import java.util.List; | ||
import java.util.Map; | ||
import java.util.function.BiFunction; | ||
|
||
public class HamcrestMatcherToJUnit5 extends Recipe { | ||
|
||
private static final MethodMatcher MATCHER_ASSERT_MATCHER = new MethodMatcher("org.hamcrest.MatcherAssert assertThat(.., org.hamcrest.Matcher)"); | ||
|
||
@Override | ||
public String getDisplayName() { | ||
return "Migrate from Hamcrest `Matcher` to JUnit 5"; | ||
} | ||
|
||
@Override | ||
public String getDescription() { | ||
return "Migrate from Hamcrest `Matcher` to JUnit 5 assertions."; | ||
} | ||
|
||
@Override | ||
public TreeVisitor<?, ExecutionContext> getVisitor() { | ||
return Preconditions.check( | ||
new UsesMethod<>(MATCHER_ASSERT_MATCHER), | ||
new MigrationFromHamcrestVisitor()); | ||
} | ||
|
||
enum Replacement { | ||
EQUALTO("equalTo", "assertEquals", "assertNotEquals", "#{any(java.lang.Object)}, #{any(java.lang.Object)}", "examinedObjThenMatcherArgs"), | ||
EMPTYARRAY("emptyArray", "assertEquals", "assertNotEquals", "0, #{anyArray(java.lang.Object)}.length", "examinedObjOnly"), | ||
HASENTRY("hasEntry", "assertEquals", "assertNotEquals", "#{any(java.lang.Object)}, #{any(java.util.Map)}.get(#{any(java.lang.Object)})", "matcher1ExaminedObjMatcher0"), | ||
HASSIZE("hasSize", "assertEquals", "assertNotEquals", "#{any(java.util.Collection)}.size(), #{any(double)}", "examinedObjThenMatcherArgs"), | ||
HASTOSTRING("hasToString", "assertEquals", "assertNotEquals", "#{any(java.lang.Object)}.toString(), #{any(java.lang.String)}", "examinedObjThenMatcherArgs"), | ||
CLOSETO("closeTo", "assertTrue", "assertFalse", "Math.abs(#{any(double)} - #{any(double)}) < #{any(double)}", "examinedObjThenMatcherArgs"), | ||
CONTAINSSTRING("containsString", "assertTrue", "assertFalse", "#{any(java.lang.String)}.contains(#{any(java.lang.String)}", "examinedObjThenMatcherArgs"), | ||
EMPTY("empty", "assertTrue", "assertFalse", "#{any(java.util.Collection)}.isEmpty()", "examinedObjOnly"), | ||
ENDSWITH("endsWith", "assertTrue", "assertFalse", "#{any(java.lang.String)}.endsWith(#{any(java.lang.String)})", "examinedObjThenMatcherArgs"), | ||
EQUALTOIGNORINGCASE("equalToIgnoringCase", "assertTrue", "assertFalse", "#{any(java.lang.String)}.equalsIgnoreCase(#{any(java.lang.String)})", "examinedObjThenMatcherArgs"), | ||
GREATERTHAN("greaterThan", "assertTrue", "assertFalse", "#{any(double)} > #{any(double)}", "examinedObjThenMatcherArgs"), | ||
GREATERTHANOREQUALTO("greaterThanOrEqualTo", "assertTrue", "assertFalse", "#{any(double)} >= #{any(double)}", "examinedObjThenMatcherArgs"), | ||
HASKEY("hasKey", "assertTrue", "assertFalse", "#{any(java.util.Map)}.containsKey(#{any(java.lang.Object)})", "examinedObjThenMatcherArgs"), | ||
HASVALUE("hasValue", "assertTrue", "assertFalse", "#{any(java.util.Map)}.containsValue(#{any(java.lang.Object)})", "examinedObjThenMatcherArgs"), | ||
LESSTHAN("lessThan", "assertTrue", "assertFalse", "#{any(double)} < #{any(double)}", "examinedObjThenMatcherArgs"), | ||
LESSTHANOREQUALTO("lessThanOrEqualTo", "assertTrue", "assertFalse", "#{any(double)} <= #{any(double)}", "examinedObjThenMatcherArgs"), | ||
STARTSWITH("startsWith", "assertTrue", "assertFalse", "#{any(java.lang.String)}.startsWith(#{any(java.lang.String)})", "examinedObjThenMatcherArgs"), | ||
TYPECOMPATIBLEWITH("typeCompatibleWith", "assertTrue", "assertFalse", "#{any(java.lang.Class)}.isAssignableFrom(#{any(java.lang.Class)})", "matcherArgsThenExaminedObj"), | ||
NOTNULLVALUE("notNullValue", "assertNotNull", "assertNull", "#{any(java.lang.Object)}", "examinedObjOnly"), | ||
NULLVALUE("nullValue", "assertNull", "assertNotNull", "#{any(java.lang.Object)}", "examinedObjOnly"), | ||
SAMEINSTANCE("sameInstance", "assertSame", "assertNotSame", "#{any(java.lang.Object)}, #{any(java.lang.Object)}", "examinedObjThenMatcherArgs"), | ||
THEINSTANCE("theInstance", "assertSame", "assertNotSame", "#{any(java.lang.Object)}, #{any(java.lang.Object)}", "examinedObjThenMatcherArgs"), | ||
EMPTYITERABLE("emptyIterable", "assertFalse", "assertTrue", "#{any(java.lang.Iterable)}.iterator().hasNext()", "examinedObjOnly"); | ||
|
||
final String hamcrest, junitPositive, junitNegative, template; | ||
final String argumentsMethod; | ||
|
||
private static final Map<String, BiFunction<Expression, J.MethodInvocation, List<Expression>>> methods = new HashMap<>(); | ||
|
||
static { | ||
methods.put("examinedObjThenMatcherArgs", (ex, matcher) -> { | ||
List<Expression> arguments = matcher.getArguments(); | ||
arguments.add(0, ex); | ||
return arguments; | ||
}); | ||
methods.put("matcherArgsThenExaminedObj", (ex, matcher) -> { | ||
List<Expression> arguments = matcher.getArguments(); | ||
arguments.add(ex); | ||
return arguments; | ||
}); | ||
methods.put("examinedObjOnly", (ex, matcher) -> { | ||
List<Expression> arguments = new ArrayList<>(); | ||
arguments.add(ex); | ||
return arguments; | ||
}); | ||
methods.put("matcher1ExaminedObjMatcher0", (ex, matcher) -> { | ||
List<Expression> arguments = new ArrayList<>(); | ||
arguments.add(matcher.getArguments().get(1)); | ||
arguments.add(ex); | ||
arguments.add(matcher.getArguments().get(0)); | ||
return arguments; | ||
}); | ||
} | ||
|
||
Replacement(String hamcrest, String junitPositive, String junitNegative, String template, String argumentsMethod) { | ||
this.hamcrest = hamcrest; | ||
this.junitPositive = junitPositive; | ||
this.junitNegative = junitNegative; | ||
this.template = template; | ||
this.argumentsMethod = argumentsMethod; | ||
} | ||
} | ||
|
||
private static class MigrationFromHamcrestVisitor extends JavaIsoVisitor<ExecutionContext> { | ||
|
||
@Override | ||
public J.MethodInvocation visitMethodInvocation(J.MethodInvocation method, ExecutionContext ctx) { | ||
J.MethodInvocation mi = super.visitMethodInvocation(method, ctx); | ||
|
||
if (MATCHER_ASSERT_MATCHER.matches(mi)) { | ||
Expression reason; | ||
Expression examinedObject; | ||
Expression hamcrestMatcher; | ||
|
||
if (mi.getArguments().size() == 2) { | ||
reason = null; | ||
examinedObject = mi.getArguments().get(0); | ||
hamcrestMatcher = mi.getArguments().get(1); | ||
} else if (mi.getArguments().size() == 3) { | ||
reason = mi.getArguments().get(0); | ||
examinedObject = mi.getArguments().get(1); | ||
hamcrestMatcher = mi.getArguments().get(2); | ||
} else { | ||
return mi; | ||
} | ||
|
||
if (hamcrestMatcher instanceof J.MethodInvocation) { | ||
J.MethodInvocation matcherInvocation = (J.MethodInvocation) hamcrestMatcher; | ||
maybeRemoveImport("org.hamcrest.MatcherAssert.assertThat"); | ||
|
||
while ("not".equals(matcherInvocation.getSimpleName())) { | ||
maybeRemoveImport("org.hamcrest.Matchers.not"); | ||
maybeRemoveImport("org.hamcrest.CoreMatchers.not"); | ||
matcherInvocation = (J.MethodInvocation) new RemoveNotMatcherVisitor().visit(matcherInvocation, ctx); | ||
} | ||
|
||
//we do not handle nested matchers | ||
if (!(matcherInvocation.getArguments().get(0) instanceof J.Empty)) { | ||
if ((matcherInvocation.getArguments().get(0).getType()).toString().startsWith("org.hamcrest")) { | ||
return mi; | ||
} | ||
} | ||
|
||
boolean logicalContext = RemoveNotMatcherVisitor.getLogicalContext(matcherInvocation, ctx); | ||
|
||
Replacement replacement; | ||
try { | ||
replacement = Replacement.valueOf(matcherInvocation.getSimpleName().toUpperCase()); | ||
} catch (IllegalArgumentException e) { | ||
return mi; | ||
} | ||
String assertion = logicalContext ? replacement.junitPositive : replacement.junitNegative; | ||
String templateString = assertion + "(" + replacement.template + (reason == null ? ")" : ", #{any(java.lang.String)})"); | ||
JavaTemplate template = JavaTemplate.builder(templateString) | ||
.javaParser(JavaParser.fromJavaVersion().classpathFromResources(ctx, "junit-jupiter-api-5.9")) | ||
.staticImports("org.junit.jupiter.api.Assertions." + assertion) | ||
.build(); | ||
|
||
maybeRemoveImport("org.hamcrest.Matchers." + replacement.hamcrest); | ||
maybeRemoveImport("org.hamcrest.CoreMatchers." + replacement.hamcrest); | ||
maybeAddImport("org.junit.jupiter.api.Assertions", assertion); | ||
|
||
List<Expression> arguments = Replacement.methods.get(replacement.argumentsMethod).apply(examinedObject, matcherInvocation); | ||
if (reason != null) { | ||
arguments.add(reason); | ||
} | ||
|
||
return template.apply(getCursor(), method.getCoordinates().replace(), arguments.toArray()); | ||
} | ||
} | ||
return mi; | ||
} | ||
} | ||
} |
77 changes: 77 additions & 0 deletions
77
src/main/java/org/openrewrite/java/testing/hamcrest/RemoveNotMatcherVisitor.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
/* | ||
* Copyright 2024 the original author or authors. | ||
* <p> | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* <p> | ||
* https://www.apache.org/licenses/LICENSE-2.0 | ||
* <p> | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
package org.openrewrite.java.testing.hamcrest; | ||
|
||
import org.openrewrite.ExecutionContext; | ||
import org.openrewrite.java.JavaIsoVisitor; | ||
import org.openrewrite.java.JavaParser; | ||
import org.openrewrite.java.JavaTemplate; | ||
import org.openrewrite.java.MethodMatcher; | ||
import org.openrewrite.java.tree.J; | ||
|
||
import java.security.InvalidParameterException; | ||
import java.util.Objects; | ||
|
||
class RemoveNotMatcherVisitor extends JavaIsoVisitor<ExecutionContext> { | ||
static final MethodMatcher NOT_MATCHER = new MethodMatcher("org.hamcrest.Matchers not(..)"); | ||
|
||
public static boolean getLogicalContext(J.MethodInvocation mi, ExecutionContext ctx) throws InvalidParameterException { | ||
Object msg = ctx.getMessage(mi.toString()); | ||
if (msg == null) { | ||
return true; | ||
} else if (msg instanceof Boolean) { | ||
return (Boolean) msg; | ||
} else { | ||
throw new InvalidParameterException(); | ||
} | ||
} | ||
|
||
@Override | ||
@SuppressWarnings("ConstantConditions") | ||
public J.MethodInvocation visitMethodInvocation(J.MethodInvocation mi, ExecutionContext ctx) { | ||
if (NOT_MATCHER.matches(mi)) { | ||
boolean logicalContext; | ||
if (ctx.pollMessage(mi.toString()) != null) { | ||
logicalContext = ctx.getMessage(mi.toString()); | ||
} else { | ||
logicalContext = true; | ||
} | ||
|
||
maybeRemoveImport("org.hamcrest.Matchers.not"); | ||
|
||
J.MethodInvocation result; | ||
if (Objects.requireNonNull(mi.getArguments().get(0).getType()).toString().startsWith("org.hamcrest")) { | ||
result = mi.getArguments().get(0).withPrefix(mi.getPrefix()); | ||
} else { | ||
JavaTemplate template = JavaTemplate.builder("equalTo(#{any(java.lang.Object)})") | ||
.javaParser(JavaParser.fromJavaVersion().classpathFromResources(ctx, "hamcrest-2.2")) | ||
.staticImports("org.hamcrest.Matchers.equalTo") | ||
.build(); | ||
maybeAddImport("org.hamcrest.Matchers", "equalTo"); | ||
result = template.apply(getCursor(), mi.getCoordinates().replace(), mi.getArguments().get(0)); | ||
} | ||
|
||
ctx.putMessage(result.toString(), !logicalContext); | ||
|
||
return result; | ||
} else { | ||
if (ctx.pollMessage(mi.toString()) == null) { | ||
ctx.putMessage(mi.toString(), true); | ||
} | ||
} | ||
return super.visitMethodInvocation(mi, ctx); | ||
} | ||
} |
Oops, something went wrong.