Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,6 @@ public class AssertionsArgumentOrder extends Recipe {
matchers.add(JUPITER_ASSERT_ITERABLE_EQUALS_MATCHER);
matchers.add(JUPITER_ASSERT_NULL_MATCHER);
matchers.addAll(Arrays.asList(TESTNG_MATCHERS));
//noinspection unchecked
PRECONDITION = Preconditions.or(matchers.stream().map(UsesMethod::new).toArray(TreeVisitor[]::new));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,6 @@ public TreeVisitor<?, ExecutionContext> getVisitor() {
maybeRemoveImport(type);
}
}
//noinspection ConstantConditions
return null;
}
return super.visitMethodDeclaration(method, ctx);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,6 @@ public J.MethodDeclaration visitMethodDeclaration(J.MethodDeclaration method,
ExecutionContext ctx) {
J.MethodDeclaration m = super.visitMethodDeclaration(method, ctx);

// Quickly reject invalid methods
String simpleName = method.getSimpleName();
int nameLength = simpleName.length();
if (nameLength < 5 ||
Expand All @@ -104,23 +103,20 @@ public J.MethodDeclaration visitMethodDeclaration(J.MethodDeclaration method,
return m;
}

// Reject invalid start character
boolean snakecase = simpleName.charAt(4) == '_' &&
5 < nameLength &&
Character.isAlphabetic(simpleName.charAt(5));
if (!snakecase && !Character.isAlphabetic(simpleName.charAt(4))) {
return m;
}

// Avoid reserved keywords
String newMethodName = snakecase ?
NameCaseConvention.format(NameCaseConvention.LOWER_UNDERSCORE, simpleName.substring(5)) :
NameCaseConvention.format(NameCaseConvention.LOWER_CAMEL, simpleName.substring(4));
if (RESERVED_KEYWORDS.contains(newMethodName)) {
return m;
}

// Prevent conflicts with existing methods
JavaType.Method type = m.getMethodType();
if (type == null || methodExists(type, newMethodName)) {
return m;
Expand All @@ -141,12 +137,10 @@ public J.MethodDeclaration visitMethodDeclaration(J.MethodDeclaration method,
for (JavaType.Method declaredMethod : declaringType.getMethods()) {
if (declaredMethod.getName().equals(simpleName) &&
declaredMethod.hasFlags(Flag.Static)) {
// Check for conflict with source method's new name
if (TypeUtils.findDeclaredMethod(declaringType, newMethodName,
declaredMethod.getParameterTypes()).isPresent()) {
return m;
}
// Rename the source method too
doAfterVisit(new ChangeMethodName(
MethodMatcher.methodPattern(declaredMethod),
newMethodName, false, false).getVisitor());
Expand All @@ -156,7 +150,6 @@ public J.MethodDeclaration visitMethodDeclaration(J.MethodDeclaration method,
}
}

// Skip when there's a conflicting static import
if (getCursor().getNearestMessage(STATIC_IMPORTS, new HashSet<>()).contains(newMethodName)) {
return m;
}
Expand All @@ -176,7 +169,6 @@ public J.MethodInvocation visitMethodInvocation(J.MethodInvocation method, Atomi
return m;
}

// Rename method and return
doAfterVisit(new ChangeMethodName(MethodMatcher.methodPattern(m), newMethodName, false, false).getVisitor());
return m;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,14 +60,11 @@ public J.MethodDeclaration visitMethodDeclaration(J.MethodDeclaration methodDecl
maybeRemoveImport("mockit.Mocked");
maybeAddImport("org.mockito.Mockito");

// Create lists to store the mocked parameters and the new type parameters
List<J.VariableDeclarations> mockedParameter = new ArrayList<>();

// Remove any mocked parameters from the method declaration
md = md.withParameters(ListUtils.map(parameters, parameter -> {
if (parameter instanceof J.VariableDeclarations) {
J.VariableDeclarations variableDeclarations = (J.VariableDeclarations) parameter;
// Check if the parameter has the annotation "mockit.Mocked or mockit.Injectable"
if (!FindAnnotations.find(variableDeclarations, "mockit.Injectable").isEmpty() ||
!FindAnnotations.find(variableDeclarations, "mockit.Mocked").isEmpty() ) {
mockedParameter.add(variableDeclarations);
Expand All @@ -77,7 +74,6 @@ public J.MethodDeclaration visitMethodDeclaration(J.MethodDeclaration methodDecl
return parameter;
}));

// Add mocked parameters as statements to the method declaration
if (!mockedParameter.isEmpty()) {
JavaTemplate addStatementsTemplate = JavaTemplate.builder("#{} #{} = Mockito.mock(#{}.class);\n")
.javaParser(getJavaParser(ctx))
Expand All @@ -87,7 +83,6 @@ public J.MethodDeclaration visitMethodDeclaration(J.MethodDeclaration methodDecl
// Retain argument order by iterating in reverse
for (int i = mockedParameter.size() - 1; i >= 0; i--) {
J.VariableDeclarations variableDeclarations = mockedParameter.get(i);
// Apply the template and update the method declaration
md = addStatementsTemplate.apply(updateCursor(md),
md.getBody().getCoordinates().firstStatement(),
variableDeclarations.getTypeExpression().toString(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,16 +27,6 @@

import static java.util.stream.Collectors.toList;

/**
* In Kotlin files, when both {@code import org.junit.jupiter.api.*} and static imports from
* {@code org.junit.jupiter.api.Assertions} are present, the Kotlin compiler cannot resolve
* which assertion method to use due to ambiguity between the Java static methods and the
* Kotlin extension functions.
* <p>
* This recipe removes the static Assertions imports in Kotlin files when the wildcard import
* {@code org.junit.jupiter.api.*} is present, allowing the Kotlin extension functions to be
* used instead. The Kotlin extensions have better nullability handling for Kotlin code.
*/
public class CleanupKotlinJUnit5AssertionImports extends Recipe {

@Getter
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,6 @@ public J.MethodDeclaration visitMethodDeclaration(J.MethodDeclaration method, Ex
J.MethodDeclaration m = super.visitMethodDeclaration(method, ctx);
boolean kotlin = getCursor().firstEnclosing(K.CompilationUnit.class) != null;

// Check if method has exactly one parameter
if (m.getParameters().size() != 1 || m.getParameters().get(0) instanceof J.Empty) {
return m;
}
Expand All @@ -78,11 +77,9 @@ public J.MethodDeclaration visitMethodDeclaration(J.MethodDeclaration method, Ex
return m;
}

// Find @CsvSource annotation
for (J.Annotation annotation : m.getLeadingAnnotations()) {
Optional<Annotated> annotated = new Annotated.Matcher(CSV_SOURCE_MATCHER).get(annotation, getCursor());
if (annotated.isPresent() && annotation.getArguments() != null && annotation.getArguments().size() == 1) {
// Get the parameter type
String paramType = getParameterType((J.VariableDeclarations) m.getParameters().get(0));
if (paramType == null) {
return m;
Expand Down Expand Up @@ -134,13 +131,11 @@ public J.MethodDeclaration visitMethodDeclaration(J.MethodDeclaration method, Ex
}
}

// Build a new ValueSource annotation
String valueSourceAnnotationTemplate = buildValueSourceAnnotation(paramType, values, fromTextBlock, kotlin);
if (valueSourceAnnotationTemplate == null) {
return m;
}

// Replace the annotation
maybeRemoveImport("org.junit.jupiter.params.provider.CsvSource");
maybeAddImport("org.junit.jupiter.params.provider.ValueSource");
J.MethodDeclaration replaced = applyValueSourceTemplate(valueSourceAnnotationTemplate, annotation, kotlin, ctx);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
package org.openrewrite.java.testing.junit5;

import lombok.Getter;
import org.jspecify.annotations.NonNull;
import org.jspecify.annotations.Nullable;
import org.openrewrite.ExecutionContext;
import org.openrewrite.Preconditions;
Expand Down Expand Up @@ -52,11 +51,10 @@
"library.";

@Override
public @NonNull TreeVisitor<?, ExecutionContext> getVisitor() {
public TreeVisitor<?, ExecutionContext> getVisitor() {
return Preconditions.check(new UsesType<>(ENVIRONMENT_VARIABLES, false), new JavaVisitor<ExecutionContext>() {
@Override
public @NonNull J visitCompilationUnit(
J.@NonNull CompilationUnit cu, @NonNull ExecutionContext ctx) {
public J visitCompilationUnit(J.CompilationUnit cu, ExecutionContext ctx) {
maybeRemoveImport(RULE);
maybeRemoveImport(CLASS_RULE);
maybeRemoveImport(ENVIRONMENT_VARIABLES);
Expand All @@ -69,23 +67,20 @@
}

@Override
public @NonNull J visitClassDeclaration(
J.@NonNull ClassDeclaration classDecl, @NonNull ExecutionContext ctx) {
public J visitClassDeclaration(J.ClassDeclaration classDecl, ExecutionContext ctx) {
J.ClassDeclaration cd = (J.ClassDeclaration) super.visitClassDeclaration(classDecl, ctx);
Boolean hasEnvVarRule = getCursor().getMessage(HAS_ENV_VAR_RULE);

if (!Boolean.TRUE.equals(hasEnvVarRule)) {
return cd;
}
// Add @ExtendWith(SystemStubsExtension.class) annotation to class.
return systemStubExtensionTemplate(ctx).apply(
updateCursor(cd),
cd.getCoordinates().addAnnotation(comparing(J.Annotation::getSimpleName)));
}

@Override
public @NonNull J visitVariableDeclarations(
J.@NonNull VariableDeclarations variableDecls, @NonNull ExecutionContext ctx) {
public J visitVariableDeclarations(J.VariableDeclarations variableDecls, ExecutionContext ctx) {
// missing type attribution, possibly parsing error.
if (variableDecls.getType() == null || !TypeUtils.isAssignableTo(ENVIRONMENT_VARIABLES, variableDecls.getType())) {
return variableDecls;
Expand All @@ -100,7 +95,6 @@
.visit(variableDecls, ctx, getCursor().getParentOrThrow());

if (variableDecls != vd) {
// put message to first enclosing ClassDeclaration, to inform that we have an env var rule.
getCursor()
.dropParentUntil(J.ClassDeclaration.class::isInstance)
.putMessage(HAS_ENV_VAR_RULE, true);
Expand All @@ -110,16 +104,13 @@
}

@Override
public @Nullable J visitMethodInvocation(
J.@NonNull MethodInvocation method, @NonNull ExecutionContext ctx) {

public @Nullable J visitMethodInvocation(J.MethodInvocation method, ExecutionContext ctx) {
J.MethodInvocation m = (J.MethodInvocation) super.visitMethodInvocation(method, ctx);
// Replace EnvironmentVariables.clear() with EnvironmentVariables.remove()
if (ENV_VAR_CLEAR.matches(method) && m.getSelect() != null /* NullAway */) {
int argCount = argCount(m);
J j =
getEnvVarClearTemplate(ctx, argCount)
.apply(updateCursor(m), m.getCoordinates().replace(), getArgs(m, argCount));

Check warning on line 113 in src/main/java/org/openrewrite/java/testing/junit5/EnvironmentVariables.java

View workflow job for this annotation

GitHub Actions / build / build

non-varargs call of varargs method with inexact argument type for last parameter;

Check warning on line 113 in src/main/java/org/openrewrite/java/testing/junit5/EnvironmentVariables.java

View workflow job for this annotation

GitHub Actions / build / test (Java 25)

non-varargs call of varargs method with inexact argument type for last parameter;

if (getCursor().getParentTreeCursor().getValue() instanceof J.Block &&
!(j instanceof Statement)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,18 +40,7 @@
import static java.util.Collections.emptyList;
import static org.openrewrite.Tree.randomId;

/**
* Replace usages of JUnit 4's @Rule ExpectedException with JUnit 5 Assertions.
* <p>
* Supported ExpectedException methods:
* expect(java.lang.Class)
* expect(org.hamcrest.Matcher)
* expectMessage(java.lang.String)
* expectMessage(org.hamcrest.Matcher)
* expectCause(org.hamcrest.Matcher)
* <p>
* Does not currently support migration of ExpectedException.isAnyExceptionExpected().
*/
// ExpectedException.isAnyExceptionExpected() is not migrated.
public class ExpectedExceptionToAssertThrows extends Recipe {

@Getter
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,7 @@
import static java.lang.String.format;
import static java.util.Comparator.comparing;

/**
* A recipe that handles the usage of the junit-4 ExternalResourceRule's by adding
* the @ExtendWith(ExternalResourceSupport.class) annotation to the test class.
* In declarative recipe list, this should be the last recipe, to handle any junit4 ExternalResourceRules, which
* are not explicitly handled.
*/
// Run this last in a declarative recipe list, so it only handles the ExternalResource rules no other recipe migrated.
public class HandleExternalResourceRules extends Recipe {

private static final AnnotationMatcher ANY_RULE_ANNOTATION_MATCHER = new AnnotationMatcher("@org.junit.*Rule", true);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,8 @@
import static java.util.Collections.emptyList;
import static java.util.stream.Collectors.joining;

/**
* Converts Pragmatists JUnitParamsRunner tests to their JUnit 5 ParameterizedTest and associated MethodSource equivalent
* <a href="https://github.com/Pragmatists/JUnitParams">...</a>
* Supports the following conversions
* `@Parameters` annotation without arguments and default `parametersFor...` init-method exists
* `@Parameters(method = "...")` annotation with defined method references
* `@Parameters(named = "...")` and associated `@NamedParameter` init-method
* Unsupported tests are identified with a comment on the associated `@Parameters(...)` annotation.
*/
// Converts `@Parameters` without arguments (with a `parametersFor...` method), `@Parameters(method = "...")` and `@Parameters(named = "...")` with a `@NamedParameter` method.
// Other `@Parameters(...)` annotations get a comment marking the test as unsupported.
public class JUnitParamsRunnerToParameterized extends Recipe {

private static final AnnotationMatcher RUN_WITH_JUNIT_PARAMS_ANNOTATION_MATCHER = new AnnotationMatcher("@org.junit.runner.RunWith(junitparams.JUnitParamsRunner.class)");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,6 @@ public J.ClassDeclaration visitClassDeclaration(J.ClassDeclaration classDecl, Ex
// If the class no longer extends TestCase there should no longer be calls to TestCase.super()
// Plenty of edge cases around classes which extend classes which extend TestCase this doesn't account for
if (TEST_CASE_SUPER_MATCHER.matches(method)) {
//noinspection DataFlowIssue
return null;
}
return super.visitMethodInvocation(method, ctx);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,20 +41,7 @@
import static java.util.Comparator.comparing;
import static java.util.stream.Collectors.toList;

/**
* Replaces JUnit 4 MockitoJUnit rules with JUnit MockitoExtension.
* <p>
* Supported MockitoJUnit methods:
* #rule()
* #testRule()
* <p>
* Does not currently support @Incubating MockitoJUnit.collector().
*
* @implNote collector() is designed to aggregate multiple verifications into a single output.
* Refactoring the method may be fairly complex and would likely benefit from being a separate recipe.
* <p>
* Must be run in the JUnit 5 suite.
*/
// MockitoJUnit.collector() is not migrated: it aggregates verifications into a single report, which would need a recipe of its own.
public class MockitoJUnitToMockitoExtension extends Recipe {

@Getter
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@ public class RemoveObsoleteRunnersVisitor extends JavaIsoVisitor<ExecutionContex
@Override
public J.ClassDeclaration visitClassDeclaration(J.ClassDeclaration classDecl, ExecutionContext ctx) {
for (String runner : obsoleteRunners) {
//noinspection ConstantConditions
doAfterVisit(new RemoveAnnotation("@org.junit.runner.RunWith(" + runner + ".class)").getVisitor());
maybeRemoveImport(runner);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,6 @@ public J.ClassDeclaration visitClassDeclaration(J.ClassDeclaration classDecl, Ex
J.ClassDeclaration cd = super.visitClassDeclaration(classDecl, ctx);

for (String runner : runners) {
//noinspection ConstantConditions
for (J.Annotation runWith : FindAnnotations.find(classDecl.withBody(null), "@org.junit.runner.RunWith(" + runner + ".class)")) {
cd = buildExtendsWithTemplate(ctx).apply(
updateCursor(cd),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,6 @@ public J visitVariableDeclarations(J.VariableDeclarations multiVariable, Executi
doAfterVisit(new AddNewFolderOrFileMethod(mi, FileOrFolder.FOLDER, getCursor().firstEnclosing(J.ClassDeclaration.class)));
break;
case "create":
//noinspection ConstantConditions
return null;
case "getRoot":
return mi.getSelect().withPrefix(mi.getPrefix());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,6 @@ private static J.VariableDeclarations removeFinalModifier(J.VariableDeclarations
public J.@Nullable NewClass visitNewClass(J.NewClass newClass, ExecutionContext ctx) {
J.NewClass nc = super.visitNewClass(newClass, ctx);
if (TypeUtils.isOfClassType(nc.getType(), "org.junit.rules.TestName")) {
//noinspection ConstantConditions
return null;
}
return nc;
Expand Down Expand Up @@ -181,7 +180,6 @@ public J.MethodDeclaration visitMethodDeclaration(J.MethodDeclaration method, Ex
.build()
.apply(updateCursor(md), md.getCoordinates().replaceParameters());

//noinspection ConstantConditions
md = maybeAutoFormat(
md,
JavaTemplate.builder(testMethodStatement)
Expand Down
Loading
Loading