Skip to content

Commit 09037ed

Browse files
committed
Add AssertToAssertions which turns JUnit4 Assert into JUnit5 Assertions
1 parent 2eca150 commit 09037ed

File tree

4 files changed

+247
-7
lines changed

4 files changed

+247
-7
lines changed

src/before/java/org/openrewrite/java/testing/junit5/ExampleJunitTestClass.java

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -58,11 +58,14 @@ public void foo2() {
5858

5959
@Test
6060
public void assertsStuff() {
61-
Assert.assertEquals(1, 1);
62-
Assert.assertArrayEquals(new int[]{}, new int[]{});
63-
Assert.assertNotEquals(1, 2);
64-
Assert.assertFalse(false);
65-
Assert.assertTrue(true);
61+
Assert.assertEquals("One is one", 1, 1);
62+
Assert.assertArrayEquals("Empty is empty", new int[]{}, new int[]{});
63+
Assert.assertNotEquals("one is not two", 1, 2);
64+
Assert.assertFalse("false is false", false);
65+
Assert.assertTrue("true is true", true);
66+
Assert.assertEquals("foo is foo", "foo", "foo");
67+
Assert.assertNull("null is null", null);
68+
Assert.fail("fail");
6669
}
6770

6871
@Test
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
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.AutoConfigure;
19+
import org.openrewrite.Formatting;
20+
import org.openrewrite.java.ChangeType;
21+
import org.openrewrite.java.JavaIsoRefactorVisitor;
22+
import org.openrewrite.java.search.SemanticallyEqual;
23+
import org.openrewrite.java.tree.Expression;
24+
import org.openrewrite.java.tree.J;
25+
import org.openrewrite.java.tree.JavaType;
26+
27+
import java.util.List;
28+
import java.util.stream.Collectors;
29+
import java.util.stream.Stream;
30+
31+
/**
32+
* Change JUnit4's org.junit.Assert into JUnit5's org.junit.jupiter.api.Assertions
33+
* The most significant difference between these classes is that in JUnit4 the optional String message is the first
34+
* parameter, and the JUnit5 versions have the optional message as the final parameter
35+
*/
36+
@AutoConfigure
37+
public class AssertToAssertions extends JavaIsoRefactorVisitor {
38+
39+
@Override
40+
public J.ClassDecl visitClassDecl(J.ClassDecl classDecl) {
41+
ChangeType ct = new ChangeType();
42+
ct.setType("org.junit.Assert");
43+
ct.setTargetType("org.junit.jupiter.api.Assertions");
44+
andThen(ct);
45+
return super.visitClassDecl(classDecl);
46+
}
47+
48+
@Override
49+
public J.MethodInvocation visitMethodInvocation(J.MethodInvocation method) {
50+
J.MethodInvocation m = super.visitMethodInvocation(method);
51+
if(!isJunitAssertMethod(m)) {
52+
return m;
53+
}
54+
List<Expression> args = m.getArgs().getArgs();
55+
Expression firstArg = args.get(0);
56+
// Suppress arg-switching for Assertions.assertEquals(String, String)
57+
if(args.size() == 2 && isString(firstArg.getType()) && isString(args.get(1).getType())) {
58+
return m;
59+
}
60+
if(isString(firstArg.getType())) {
61+
// Move the first arg to be the last argument, then switch the formatting of the first and last arguments
62+
Formatting firstFormatting = firstArg.getFormatting();
63+
Formatting lastFormatting = args.get(args.size() - 1).getFormatting();
64+
65+
List<Expression> newArgs = Stream.concat(
66+
args.stream().skip(1),
67+
Stream.of(firstArg)
68+
).collect(Collectors.toList());
69+
70+
int lastIndex = newArgs.size() - 1;
71+
newArgs.set(0, newArgs.get(0).withFormatting(firstFormatting));
72+
newArgs.set(lastIndex, newArgs.get(lastIndex).withFormatting(lastFormatting));
73+
74+
m = m.withArgs(m.getArgs().withArgs(newArgs));
75+
}
76+
77+
return m;
78+
}
79+
80+
private boolean isJunitAssertMethod(J.MethodInvocation method) {
81+
if(!(method.getSelect() instanceof J.Ident)) {
82+
return false;
83+
}
84+
J.Ident receiver = (J.Ident) method.getSelect();
85+
if(!(receiver.getType() instanceof JavaType.FullyQualified)) {
86+
return false;
87+
}
88+
JavaType.FullyQualified receiverType = (JavaType.FullyQualified) receiver.getType();
89+
return receiverType.getFullyQualifiedName().equals("org.junit.Assert");
90+
}
91+
92+
private boolean isString(JavaType type) {
93+
return type instanceof JavaType.Primitive
94+
&& ((JavaType.Primitive)type).name().equals("String");
95+
}
96+
}

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

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,6 @@ visitors:
4040
type: org.junit.Assume
4141
targetType: org.junit.jupiter.api.Assumptions
4242
---
43-
44-
---
4543
type: specs.openrewrite.org/v1beta/recipe
4644
name: org.openrewrite.java.testing.JUnit5Migration
4745
include:
Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
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.jupiter.api.Test
19+
import org.openrewrite.RefactorVisitorTestForParser
20+
import org.openrewrite.java.JavaParser
21+
import org.openrewrite.java.tree.J
22+
23+
class AssertToAssertionsTest : RefactorVisitorTestForParser<J.CompilationUnit> {
24+
override val parser: JavaParser = JavaParser.fromJavaVersion()
25+
.classpath("junit")
26+
.build()
27+
28+
override val visitors = listOf(AssertToAssertions())
29+
30+
@Test
31+
fun assertWithoutMessage() = assertRefactored(
32+
before = """
33+
import org.junit.Assert;
34+
35+
class A {
36+
37+
void foo() {
38+
Assert.assertEquals(1, 1);
39+
Assert.assertArrayEquals(new int[]{}, new int[]{});
40+
Assert.assertNotEquals(1, 2);
41+
Assert.assertFalse(false);
42+
Assert.assertTrue(true);
43+
Assert.assertEquals("foo", "foo");
44+
Assert.assertNull(null);
45+
Assert.fail();
46+
}
47+
}
48+
""",
49+
after = """
50+
import org.junit.jupiter.api.Assertions;
51+
52+
class A {
53+
54+
void foo() {
55+
Assertions.assertEquals(1, 1);
56+
Assertions.assertArrayEquals(new int[]{}, new int[]{});
57+
Assertions.assertNotEquals(1, 2);
58+
Assertions.assertFalse(false);
59+
Assertions.assertTrue(true);
60+
Assertions.assertEquals("foo", "foo");
61+
Assertions.assertNull(null);
62+
Assertions.fail();
63+
}
64+
}
65+
"""
66+
)
67+
68+
@Test
69+
fun staticAssertWithoutMessage() = assertRefactored(
70+
before = """
71+
import static org.junit.Assert.*;
72+
73+
class A {
74+
75+
void foo() {
76+
assertEquals(1, 1);
77+
assertArrayEquals(new int[]{}, new int[]{});
78+
assertNotEquals(1, 2);
79+
assertFalse(false);
80+
assertTrue(true);
81+
assertEquals("foo", "foo");
82+
assertNull(null);
83+
fail();
84+
}
85+
}
86+
""",
87+
after = """
88+
import static org.junit.jupiter.api.Assertions.*;
89+
90+
class A {
91+
92+
void foo() {
93+
assertEquals(1, 1);
94+
assertArrayEquals(new int[]{}, new int[]{});
95+
assertNotEquals(1, 2);
96+
assertFalse(false);
97+
assertTrue(true);
98+
assertEquals("foo", "foo");
99+
assertNull(null);
100+
fail();
101+
}
102+
}
103+
"""
104+
)
105+
106+
@Test
107+
fun assertWithMessage() = assertRefactored(
108+
before = """
109+
import org.junit.Assert;
110+
111+
class A {
112+
113+
void foo() {
114+
Assert.assertEquals("One is one", 1, 1);
115+
Assert.assertArrayEquals("Empty is empty", new int[]{}, new int[]{});
116+
Assert.assertNotEquals("one is not two", 1, 2);
117+
Assert.assertFalse("false is false", false);
118+
Assert.assertTrue("true is true", true);
119+
Assert.assertEquals("foo is foo", "foo", "foo");
120+
Assert.assertNull("null is null", null);
121+
Assert.fail("fail");
122+
}
123+
}
124+
""",
125+
after = """
126+
import org.junit.jupiter.api.Assertions;
127+
128+
class A {
129+
130+
void foo() {
131+
Assertions.assertEquals(1, 1, "One is one");
132+
Assertions.assertArrayEquals(new int[]{}, new int[]{}, "Empty is empty");
133+
Assertions.assertNotEquals(1, 2, "one is not two");
134+
Assertions.assertFalse(false, "false is false");
135+
Assertions.assertTrue(true, "true is true");
136+
Assertions.assertEquals("foo", "foo", "foo is foo");
137+
Assertions.assertNull(null, "null is null");
138+
Assertions.fail("fail");
139+
}
140+
}
141+
"""
142+
)
143+
}

0 commit comments

Comments
 (0)