This repository was archived by the owner on Jun 1, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 14
Expand file tree
/
Copy pathAssertConversion.java
More file actions
125 lines (105 loc) · 5.04 KB
/
Copy pathAssertConversion.java
File metadata and controls
125 lines (105 loc) · 5.04 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
package jb.convert.ast;
import com.github.javaparser.ast.CompilationUnit;
import com.github.javaparser.ast.ImportDeclaration;
import com.github.javaparser.ast.Node;
import com.github.javaparser.ast.NodeList;
import com.github.javaparser.ast.expr.DoubleLiteralExpr;
import com.github.javaparser.ast.expr.Expression;
import com.github.javaparser.ast.expr.MethodCallExpr;
import com.github.javaparser.ast.visitor.VoidVisitorAdapter;
import jb.convert.MatchDetector;
import jb.convert.ast.tools.ImportDeclarations;
import org.junit.Assert;
import org.junit.jupiter.api.Assertions;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import static jb.convert.ast.tools.Expressions.fieldAccessExpressionFor;
import static jb.convert.ast.tools.StaticImportBuilder.staticImportFrom;
public class AssertConversion extends VoidVisitorAdapter<Object> implements Conversion {
private static final MatchDetector matchDetector = new MatchDetector();
private static final Set<String> convertibleAssertMethods = matchDetector.publicStaticMethodsWithMatchingNames(Assert.class, Assertions.class);
private static final String assertEquals = "assertEquals";
private static final Set<String> ONE_PARAM_METHODS = new HashSet<>(
Arrays.asList("assertFalse", "assertTrue", "assertNull", "assertNotNull"));
private static final Set<String> TWO_PARAM_METHODS = new HashSet<>(
Arrays.asList(assertEquals, "assertArrayEquals", "assertNotEquals"));
private static final Set<String> THREE_PARAM_METHODS = new HashSet<>(Collections.singletonList(assertEquals));
private boolean updated = false;
@Override
public boolean convert(CompilationUnit cu) {
visit(cu, null);
return updated;
}
@Override
public void visit(ImportDeclaration n, Object arg) {
super.visit(n, arg);
ImportDeclarations.replace(n, Assert.class, Assertions.class, this::updated);
ImportDeclarations.replace(n, staticImportFrom(Assert.class).star(), staticImportFrom(Assertions.class).star(), this::updated);
convertibleAssertMethods.forEach(methodName -> {
ImportDeclarations.replace(n, staticImportFrom(Assert.class).method(methodName), staticImportFrom(Assertions.class).method(methodName), this::updated);
});
}
@Override
public void visit(final MethodCallExpr methodCall, final Object arg) {
String methodName = methodCall.getNameAsString();
if (convertibleAssertMethods.contains(methodName)) {
if (scopeMatchesAssert(methodCall)) {
methodCall.getScope().ifPresent(scope -> {
scope.ifNameExpr(name -> name.setName("Assertions"));
scope.ifFieldAccessExpr(fieldAccessExpr -> fieldAccessExpr.replace(fieldAccessExpressionFor("org.junit.jupiter.api.Assertions")));
});
updated();
}
if (failMessageNeedsUpdating(methodCall, methodName)) {
if (assertEquals.equals(methodName)) {
convertAssertEquals(methodCall);
} else {
moveMessageArgumentToTheEnd(methodCall);
}
}
}
super.visit(methodCall, arg);
}
private boolean scopeMatchesAssert(MethodCallExpr methodCall) {
String scopeAsString = methodCall.getScope().map(Node::toString).orElse("");
return Arrays.asList("Assert", "org.junit.Assert").contains(scopeAsString);
}
private void convertAssertEquals(MethodCallExpr methodCall) {
NodeList<Expression> arguments = methodCall.getArguments();
if (arguments.size() == 3) {
Expression expression = arguments.get(2);
if (expression instanceof DoubleLiteralExpr) {
DoubleLiteralExpr deltaArgument = (DoubleLiteralExpr) expression;
if (deltaArgument.asDouble() == 0.0) {
methodCall.remove(deltaArgument);
updated();
return;
}
}
} else if (arguments.size() == 4) {
throw new RuntimeException("this looks like a float/double assert with message and delta, not implemented yet");
}
moveMessageArgumentToTheEnd(methodCall);
}
private void moveMessageArgumentToTheEnd(MethodCallExpr methodCall) {
Expression messageArgument = methodCall.getArgument(0);
methodCall.remove(messageArgument);
methodCall.addArgument(messageArgument);
updated();
}
private boolean failMessageNeedsUpdating(MethodCallExpr methodCall, String methodName) {
int numParams = methodCall.getArguments().size();
return (numParams == 2 && ONE_PARAM_METHODS.contains(methodName))
|| (numParams == 3 && TWO_PARAM_METHODS.contains(methodName))
|| (numParams == 4 && THREE_PARAM_METHODS.contains(methodName));
}
private void updated() {
this.updated = true;
}
@Override
public String toString() {
return "updated: " + updated;
}
}