Skip to content

Commit df54124

Browse files
committed
Fix various issues in ChangeTestAnnotation and add some experimental scaffolding for trying out JUnit recipes within this project
1 parent fc5a0ae commit df54124

File tree

8 files changed

+268
-59
lines changed

8 files changed

+268
-59
lines changed

build.gradle.kts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,11 @@ repositories {
4444
mavenCentral()
4545
}
4646

47+
sourceSets {
48+
create("before")
49+
create("after")
50+
}
51+
4752
configurations.all {
4853
resolutionStrategy {
4954
cacheChangingModulesFor(0, TimeUnit.SECONDS)
@@ -58,10 +63,14 @@ dependencies {
5863
testImplementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
5964

6065
testImplementation("junit:junit:latest.release")
66+
"beforeImplementation"("junit:junit:latest.release")
6167

6268
testImplementation("org.junit.jupiter:junit-jupiter-api:latest.release")
6369
testImplementation("org.junit.jupiter:junit-jupiter-params:latest.release")
6470
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:latest.release")
71+
"afterImplementation"("org.junit.jupiter:junit-jupiter-api:latest.release")
72+
"afterImplementation"("org.junit.jupiter:junit-jupiter-params:latest.release")
73+
"afterRuntimeOnly"("org.junit.jupiter:junit-jupiter-engine:latest.release")
6574

6675
testRuntimeOnly("ch.qos.logback:logback-classic:1.0.13")
6776

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/*
2+
* Copyright 2020 the original author or authors.
3+
* <p>
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
* <p>
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
* <p>
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.openrewrite.java.testing.junit5;
17+
18+
import org.junit.AfterClass;
19+
import org.junit.BeforeClass;
20+
import org.junit.Rule;
21+
import org.junit.Test;
22+
import org.junit.rules.TemporaryFolder;
23+
import org.junit.rules.Timeout;
24+
25+
public class ExampleJunitTestClass {
26+
27+
@Rule
28+
public Timeout globalTimeout = new Timeout(500);
29+
30+
@Rule
31+
public TemporaryFolder folder = new TemporaryFolder();
32+
33+
@BeforeClass
34+
public static void beforeClass() { }
35+
36+
@AfterClass
37+
public static void afterClass() {}
38+
39+
@Test(expected = RuntimeException.class)
40+
public void foo() {
41+
String foo = "foo";
42+
throw new RuntimeException(foo);
43+
}
44+
45+
@Test(timeout = 500)
46+
public void bar() { }
47+
}

src/main/java/org/openrewrite/java/testing/junit5/ChangeTestAnnotation.java

Lines changed: 67 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,13 @@
1515
*/
1616
package org.openrewrite.java.testing.junit5;
1717

18+
import org.openrewrite.AutoConfigure;
19+
import org.openrewrite.Formatting;
20+
import org.openrewrite.java.AddAnnotation;
1821
import org.openrewrite.java.AddImport;
1922
import org.openrewrite.java.AutoFormat;
2023
import org.openrewrite.java.ChangeType;
2124
import org.openrewrite.java.JavaIsoRefactorVisitor;
22-
import org.openrewrite.java.JavaRefactorVisitor;
2325
import org.openrewrite.java.tree.*;
2426

2527
import java.util.ArrayList;
@@ -32,6 +34,7 @@
3234
import static org.openrewrite.Formatting.format;
3335
import static org.openrewrite.Tree.randomId;
3436

37+
@AutoConfigure
3538
public class ChangeTestAnnotation extends JavaIsoRefactorVisitor {
3639
public ChangeTestAnnotation() {
3740
setCursoringOn();
@@ -57,65 +60,73 @@ public J.MethodDecl visitMethod(J.MethodDecl method) {
5760
J.Annotation a = annotations.get(i);
5861
if (TypeUtils.isOfClassType(a.getType(), "org.junit.Test")) {
5962
annotations.set(i, a.withArgs(null));
60-
63+
if(a.getArgs() == null) {
64+
continue;
65+
}
6166
List<Expression> args = a.getArgs().getArgs();
6267
for (Expression arg : args) {
6368
if (arg instanceof J.Assign) {
6469
J.Assign assign = (J.Assign) arg;
65-
switch (((J.Ident) assign.getVariable()).getSimpleName()) {
66-
case "expected":
67-
Expression e = assign.getAssignment();
68-
List<Statement> statements = m.getBody().getStatements();
69-
70-
Statement assertBlock = statements.size() == 1 ?
71-
statements.get(0).withPrefix(" ") :
72-
new J.Block<>(
73-
randomId(),
74-
null,
75-
statements,
76-
format(" "),
77-
new J.Block.End(randomId(), format("\n"))
78-
);
79-
80-
J.MethodInvocation assertThrows = new J.MethodInvocation(
81-
randomId(),
82-
null,
83-
null,
84-
J.Ident.build(randomId(), "assertThrows", JavaType.Primitive.Void, EMPTY),
85-
new J.MethodInvocation.Arguments(
86-
randomId(),
87-
Arrays.asList(
88-
e.withFormatting(EMPTY),
89-
new J.Lambda(
90-
randomId(),
91-
new J.Lambda.Parameters(
92-
randomId(),
93-
true,
94-
Collections.emptyList()
95-
),
96-
new J.Lambda.Arrow(randomId(), format(" ")),
97-
assertBlock,
98-
JavaType.Primitive.Void,
99-
format(" ")
100-
)
101-
),
102-
EMPTY
103-
),
104-
null,
105-
format("\n")
106-
);
107-
108-
AddImport addAssertThrows = new AddImport();
109-
addAssertThrows.setType("org.junit.jupiter.api.Assertions");
110-
addAssertThrows.setStaticMethod("assertThrows");
111-
addAssertThrows.setOnlyIfReferenced(false);
112-
andThen(addAssertThrows);
113-
114-
andThen(new AutoFormat(assertThrows));
115-
andThen(new AutoFormat(assertBlock));
116-
117-
m = method.withBody(m.getBody().withStatements(singletonList(assertThrows)));
118-
break;
70+
String assignParamName = ((J.Ident) assign.getVariable()).getSimpleName();
71+
Expression e = assign.getAssignment();
72+
if(m.getBody() == null) {
73+
continue;
74+
}
75+
if(assignParamName.equals("expected")) {
76+
List<Statement> statements = m.getBody().getStatements();
77+
78+
Statement assertBlock = statements.size() == 1 ?
79+
statements.get(0).withPrefix(" ") :
80+
new J.Block<>(
81+
randomId(),
82+
null,
83+
statements,
84+
format(" "),
85+
new J.Block.End(randomId(), format("\n"))
86+
);
87+
88+
J.MethodInvocation assertThrows = new J.MethodInvocation(
89+
randomId(),
90+
null,
91+
null,
92+
J.Ident.build(randomId(), "assertThrows", JavaType.Primitive.Void, EMPTY),
93+
new J.MethodInvocation.Arguments(
94+
randomId(),
95+
Arrays.asList(
96+
e.withFormatting(EMPTY),
97+
new J.Lambda(
98+
randomId(),
99+
new J.Lambda.Parameters(
100+
randomId(),
101+
true,
102+
Collections.emptyList()
103+
),
104+
new J.Lambda.Arrow(randomId(), format(" ")),
105+
assertBlock,
106+
JavaType.Primitive.Void,
107+
format(" ")
108+
)
109+
),
110+
EMPTY
111+
),
112+
null,
113+
format("\n")
114+
);
115+
116+
AddImport addAssertThrows = new AddImport();
117+
addAssertThrows.setType("org.junit.jupiter.api.Assertions");
118+
addAssertThrows.setStaticMethod("assertThrows");
119+
addAssertThrows.setOnlyIfReferenced(false);
120+
andThen(addAssertThrows);
121+
122+
andThen(new AutoFormat(assertThrows));
123+
andThen(new AutoFormat(assertBlock));
124+
125+
m = method.withBody(m.getBody().withStatements(singletonList(assertThrows)));
126+
} else if (assignParamName.equals("timeout")) {
127+
AddAnnotation.Scoped aa = new AddAnnotation.Scoped(m, "org.junit.jupiter.api.Timeout", e.withFormatting(EMPTY));
128+
andThen(aa);
129+
andThen(new AutoFormat(m));
119130
}
120131
}
121132
changed = true;

src/main/resources/META-INF/rewrite/junit5.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@ visitors:
3232
- org.openrewrite.java.ChangeType:
3333
type: org.junit.Ignore
3434
targetType: org.junit.jupiter.api.Disabled
35+
---
36+
type: specs.openrewrite.org/v1beta/visitor
37+
name: org.openrewrite.java.testing.junit5.AssumeToAssumptions
38+
visitors:
3539
- org.openrewrite.java.ChangeType:
3640
type: org.junit.Assume
3741
targetType: org.junit.jupiter.api.Assumptions
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/*
2+
* Copyright 2020 the original author or authors.
3+
* <p>
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
* <p>
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
* <p>
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.openrewrite.java.testing.junit5
17+
18+
import org.openrewrite.Refactor
19+
import org.openrewrite.loadVisitorsForTest
20+
import org.openrewrite.java.JavaParser
21+
import java.nio.file.Files
22+
import java.nio.file.Path
23+
import java.nio.file.Paths
24+
import java.util.stream.Collectors
25+
26+
fun main(args: Array<String>) {
27+
val beforeDir = Paths.get(args[0]).resolve("before")
28+
val afterDir = Paths.get(args[0]).resolve("after")
29+
val parser: JavaParser = JavaParser.fromJavaVersion()
30+
.classpath("mockito-all", "junit")
31+
.build()
32+
33+
val visitors = loadVisitorsForTest("org.openrewrite.java.testing.Mockito", "org.openrewrite.java.testing.junit5.migration")
34+
val sources = parser.parse(listJavaSources(beforeDir), beforeDir)
35+
val changes = Refactor(true)
36+
.visit(visitors)
37+
.fix(sources)
38+
39+
changes.asSequence()
40+
.filter { change -> change.fixed != null }
41+
.map { change -> change.fixed!! }
42+
.forEach { fixed ->
43+
val file = afterDir.resolve(fixed.sourcePath).toFile()
44+
if(!file.parentFile.exists()) {
45+
file.parentFile.mkdirs()
46+
}
47+
file.writeText(fixed.printTrimmed())
48+
}
49+
}
50+
51+
private fun listJavaSources(sourceDirectory: Path): List<Path> {
52+
val sourceDirectoryFile = sourceDirectory.toFile()
53+
if (!sourceDirectoryFile.exists()) {
54+
return emptyList()
55+
}
56+
val sourceRoot = sourceDirectoryFile.toPath()
57+
return Files.walk(sourceRoot)
58+
.filter { f: Path -> !Files.isDirectory(f) && f.toFile().name.endsWith(".java") }
59+
.collect(Collectors.toList())
60+
}

src/test/kotlin/org/openrewrite/java/testing/junit5/ChangeTestAnnotationTest.kt

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ class ChangeTestAnnotationTest: RefactorVisitorTestForParser<J.CompilationUnit>
3535
import org.junit.Test;
3636
3737
public class A {
38+
3839
@Test(expected = IllegalArgumentException.class)
3940
public void test() {
4041
throw new IllegalArgumentException("boom");
@@ -47,11 +48,88 @@ class ChangeTestAnnotationTest: RefactorVisitorTestForParser<J.CompilationUnit>
4748
import static org.junit.jupiter.api.Assertions.assertThrows;
4849
4950
public class A {
51+
5052
@Test
5153
public void test() {
5254
assertThrows(IllegalArgumentException.class, () -> throw new IllegalArgumentException("boom"));
5355
}
5456
}
5557
""".trimIndent()
5658
)
59+
60+
@Test
61+
fun noTestAnnotationValues() = assertRefactored(
62+
before = """
63+
import org.junit.Test;
64+
65+
public class A {
66+
67+
@Test
68+
public void test() { }
69+
}
70+
""",
71+
after = """
72+
import org.junit.jupiter.api.Test;
73+
74+
public class A {
75+
76+
@Test
77+
public void test() { }
78+
}
79+
"""
80+
)
81+
82+
@Test
83+
fun testAnnotationWithTimeout() = assertRefactored(
84+
before = """
85+
import org.junit.Test;
86+
87+
public class A {
88+
89+
@Test(timeout = 500)
90+
public void test() { }
91+
}
92+
""",
93+
after = """
94+
import org.junit.jupiter.api.Test;
95+
import org.junit.jupiter.api.Timeout;
96+
97+
public class A {
98+
99+
@Test
100+
@Timeout(500)
101+
public void test() { }
102+
}
103+
"""
104+
)
105+
106+
@Test
107+
fun testAnnotationWithTimeoutAndException() = assertRefactored(
108+
before = """
109+
import org.junit.Test;
110+
111+
public class A {
112+
113+
@Test(expected = IllegalArgumentException.class, timeout = 500)
114+
public void test() {
115+
throw new IllegalArgumentException("boom");
116+
}
117+
}
118+
""",
119+
after = """
120+
import org.junit.jupiter.api.Test;
121+
import org.junit.jupiter.api.Timeout;
122+
123+
import static org.junit.jupiter.api.Assertions.assertThrows;
124+
125+
public class A {
126+
127+
@Test
128+
@Timeout(500)
129+
public void test() {
130+
assertThrows(IllegalArgumentException.class, () -> throw new IllegalArgumentException("boom"));
131+
}
132+
}
133+
"""
134+
)
57135
}

0 commit comments

Comments
 (0)