All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.openrewrite.java.testing.hamcrest.HamcrestMatcherToJUnit5 Maven / Gradle / Ivy

/*
 * Copyright 2024 the original author or authors.
 * 

* Licensed under the Moderne Source Available License (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at *

* https://docs.moderne.io/licensing/moderne-source-available-license *

* 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 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>> methods = new HashMap<>(); static { methods.put("examinedObjThenMatcherArgs", (ex, matcher) -> { List arguments = matcher.getArguments(); arguments.add(0, ex); return arguments; }); methods.put("matcherArgsThenExaminedObj", (ex, matcher) -> { List arguments = matcher.getArguments(); arguments.add(ex); return arguments; }); methods.put("examinedObjOnly", (ex, matcher) -> { List arguments = new ArrayList<>(); arguments.add(ex); return arguments; }); methods.put("matcher1ExaminedObjMatcher0", (ex, matcher) -> { List 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 { @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 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; } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy