Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add recipes for migrating Arquillian from JUnit 4 to JUnit 5. #654

Merged
merged 10 commits into from
Dec 22, 2024
3 changes: 2 additions & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,9 @@ dependencies {
exclude(group = "org.yaml", module = "snakeyaml")
}
testRuntimeOnly("org.easymock:easymock:latest.release")
testRuntimeOnly("org.testng:testng:latest.release")
testRuntimeOnly("org.jboss.arquillian.junit:arquillian-junit-core:latest.release")
testRuntimeOnly("org.mockito.kotlin:mockito-kotlin:latest.release")
testRuntimeOnly("org.testcontainers:testcontainers:latest.release")
testRuntimeOnly("org.testcontainers:nginx:latest.release")
testRuntimeOnly("org.testng:testng:latest.release")
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
/*
* Copyright 2024 the original author or authors.
* <p>
* 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
* <p>
* https://docs.moderne.io/licensing/moderne-source-available-license
* <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.arquillian;

import org.openrewrite.ExecutionContext;
import org.openrewrite.Preconditions;
import org.openrewrite.Recipe;
import org.openrewrite.TreeVisitor;
import org.openrewrite.java.*;
import org.openrewrite.java.search.UsesType;
import org.openrewrite.java.service.AnnotationService;
import org.openrewrite.java.tree.J;

import java.util.Comparator;

public class ReplaceArquillianInSequenceAnnotation extends Recipe {

@Override
public String getDisplayName() {
return "Arquillian JUnit 4 `@InSequence` to JUnit Jupiter `@Order`";
}

@Override
public String getDescription() {
return "Transforms the Arquillian JUnit 4 `@InSequence` to the JUnit Jupiter `@Order`.";
}

@Override
public TreeVisitor<?, ExecutionContext> getVisitor() {
return Preconditions.check(
new UsesType<>("org.jboss.arquillian.junit.InSequence", false),
new JavaIsoVisitor<ExecutionContext>() {
private final String IN_SEQUENCE = "org.jboss.arquillian.junit.InSequence";
private final String TEST_METHOD_ORDER = "org.junit.jupiter.api.TestMethodOrder";
private final String METHOD_ORDERER = "org.junit.jupiter.api.MethodOrderer";
private final AnnotationMatcher IN_SEQUENCE_MATCHER = new AnnotationMatcher("@" + IN_SEQUENCE);
private final AnnotationMatcher TEST_METHOD_ORDER_MATCHER = new AnnotationMatcher("@" + TEST_METHOD_ORDER);

@Override
public J.ClassDeclaration visitClassDeclaration(J.ClassDeclaration classDecl, ExecutionContext ctx) {
doAfterVisit(new ChangeType(IN_SEQUENCE, "org.junit.jupiter.api.Order", true).getVisitor());
return super.visitClassDeclaration(classDecl, ctx);
}

@Override
public J.MethodDeclaration visitMethodDeclaration(J.MethodDeclaration method, ExecutionContext ctx) {
J.MethodDeclaration m = super.visitMethodDeclaration(method, ctx);
if (service(AnnotationService.class).matches(updateCursor(m), IN_SEQUENCE_MATCHER)) {
J.ClassDeclaration classWithInSequenceMethods = getCursor().firstEnclosing(J.ClassDeclaration.class);
if (classWithInSequenceMethods != null) {
doAfterVisit(new JavaIsoVisitor<ExecutionContext>() {
@Override
public J.ClassDeclaration visitClassDeclaration(J.ClassDeclaration classDecl, ExecutionContext ctx) {
J.ClassDeclaration cd = super.visitClassDeclaration(classDecl, ctx);
if (cd.getName().equals(classWithInSequenceMethods.getName()) &&
!service(AnnotationService.class).matches(updateCursor(cd), TEST_METHOD_ORDER_MATCHER)) {
maybeAddImport(METHOD_ORDERER);
maybeAddImport(TEST_METHOD_ORDER);
return JavaTemplate.builder("@TestMethodOrder(MethodOrderer.class)")
.imports(METHOD_ORDERER, TEST_METHOD_ORDER)
.javaParser(JavaParser.fromJavaVersion().classpathFromResources(ctx, "junit-jupiter-api-5"))
.build()
.apply(getCursor(), classDecl.getCoordinates().addAnnotation(Comparator.comparing(J.Annotation::getSimpleName)));
}
return cd;
}
});
}
}
return m;
}
}
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/*
* Copyright 2024 the original author or authors.
* <p>
* 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
* <p>
* https://docs.moderne.io/licensing/moderne-source-available-license
* <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.
*/
@NullMarked
package org.openrewrite.java.testing.arquillian;

import org.jspecify.annotations.NullMarked;
41 changes: 41 additions & 0 deletions src/main/resources/META-INF/rewrite/arquillian.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#
# Copyright 2024 the original author or authors.
# <p>
# 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
# <p>
# https://docs.moderne.io/licensing/moderne-source-available-license
# <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.
#

---
type: specs.openrewrite.org/v1beta/recipe
name: org.openrewrite.java.testing.arquillian.ArquillianJUnit4ToArquillianJUnit5
displayName: Use Arquillian JUnit 5 Extension
description: Migrates Arquillian JUnit 4 to JUnit 5.
tags:
- testing
- junit
- arquillian
recipeList:
- org.openrewrite.java.testing.junit5.RunnerToExtension:
runners:
- org.jboss.arquillian.junit.Arquillian
extension: org.jboss.arquillian.junit5.ArquillianExtension
- org.openrewrite.java.dependencies.ChangeDependency:
oldGroupId: org.jboss.arquillian.junit
oldArtifactId: arquillian-junit-container
newGroupId: org.jboss.arquillian.junit5
newArtifactId: arquillian-junit5-container
newVersion: x
- org.openrewrite.java.testing.arquillian.ReplaceArquillianInSequenceAnnotation
- org.openrewrite.java.ChangePackage:
oldPackageName: org.jboss.arquillian.junit
newPackageName: org.jboss.arquillian.junit5
recursive: true
2 changes: 1 addition & 1 deletion src/main/resources/META-INF/rewrite/junit5.yml
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ recipeList:
- org.openrewrite.java.ChangeType:
oldFullyQualifiedTypeName: org.jbehave.core.junit.JUnitStories
newFullyQualifiedTypeName: org.jbehave.core.junit.JupiterStories
- org.openrewrite.java.testing.arquillian.ArquillianJUnit4ToArquillianJUnit5
- org.openrewrite.java.testing.dbrider.MigrateDbRiderSpringToDbRiderJUnit5

---
Expand Down Expand Up @@ -322,4 +323,3 @@ recipeList:
groupId: org.junit.platform
artifactId: junit-platform-surefire-provider
version: 1.1.0

Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/*
* Copyright 2024 the original author or authors.
* <p>
* 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
* <p>
* https://docs.moderne.io/licensing/moderne-source-available-license
* <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.arquillian;

import org.junit.jupiter.api.Test;
import org.openrewrite.DocumentExample;
import org.openrewrite.test.RecipeSpec;
import org.openrewrite.test.RewriteTest;

import static org.openrewrite.java.Assertions.mavenProject;
import static org.openrewrite.maven.Assertions.pomXml;

class ArquillianJUnit4ToArquillianJunit5Test implements RewriteTest {

@Override
public void defaults(RecipeSpec spec) {
spec.recipeFromResource(
"/META-INF/rewrite/arquillian.yml",
"org.openrewrite.java.testing.arquillian.ArquillianJUnit4ToArquillianJUnit5");
}

@DocumentExample
@Test
void convert() {
rewriteRun(
mavenProject("project",
//language=xml
pomXml(
"""
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>org.openrewrite</groupId>
<artifactId>arquillian</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.jboss.arquillian.junit</groupId>
<artifactId>arquillian-junit-container</artifactId>
<version>1.7.0.Final</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
""",
"""
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>org.openrewrite</groupId>
<artifactId>arquillian</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.jboss.arquillian.junit5</groupId>
<artifactId>arquillian-junit5-container</artifactId>
<version>1.9.1.Final</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
"""
)
)
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/*
* Copyright 2024 the original author or authors.
* <p>
* 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
* <p>
* https://docs.moderne.io/licensing/moderne-source-available-license
* <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.arquillian;

import org.junit.jupiter.api.Test;
import org.openrewrite.DocumentExample;
import org.openrewrite.java.JavaParser;
import org.openrewrite.test.RecipeSpec;
import org.openrewrite.test.RewriteTest;

import static org.openrewrite.java.Assertions.java;

class ReplaceArquillianInSequenceAnnotationTest implements RewriteTest {

@Override
public void defaults(RecipeSpec spec) {
spec
.parser(JavaParser.fromJavaVersion().classpath("arquillian-junit-core"))
.recipe(new ReplaceArquillianInSequenceAnnotation());
}

@DocumentExample
@Test
void replaceInSequenceAnnotation() {
rewriteRun(
//language=java
java(
"""
import org.jboss.arquillian.junit.InSequence;

class A {
@InSequence(2)
void second() {}

@InSequence(1)
void first() {}
}
""",
"""
import org.junit.jupiter.api.MethodOrderer;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.TestMethodOrder;

@TestMethodOrder(MethodOrderer.class)
class A {
@Order(2)
void second() {}

@Order(1)
void first() {}
}
"""
)
);
}
}
Loading