1
2
3
4 package net.sourceforge.pmd.lang.java.rule.junit;
5
6 import java.util.List;
7
8 import net.sourceforge.pmd.lang.ast.Node;
9 import net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceDeclaration;
10 import net.sourceforge.pmd.lang.java.ast.ASTMemberValuePair;
11 import net.sourceforge.pmd.lang.java.ast.ASTMethodDeclaration;
12 import net.sourceforge.pmd.lang.java.ast.ASTName;
13 import net.sourceforge.pmd.lang.java.ast.ASTNormalAnnotation;
14 import net.sourceforge.pmd.lang.java.ast.ASTPrimaryExpression;
15 import net.sourceforge.pmd.lang.java.ast.ASTPrimaryPrefix;
16 import net.sourceforge.pmd.lang.java.ast.ASTStatementExpression;
17
18 public class JUnitTestsShouldIncludeAssertRule extends AbstractJUnitRule {
19
20 @Override
21 public Object visit(ASTClassOrInterfaceDeclaration node, Object data) {
22 if (node.isInterface()) {
23 return data;
24 }
25 return super.visit(node, data);
26 }
27
28 @Override
29 public Object visit(ASTMethodDeclaration method, Object data) {
30 if (isJUnitMethod(method, data)) {
31 if (!containsAssert(method.getBlock(), false) && !containsExpect(method.jjtGetParent())) {
32 addViolation(data, method);
33 }
34 }
35 return data;
36 }
37
38 private boolean containsAssert(Node n, boolean assertFound) {
39 if (!assertFound) {
40 if (n instanceof ASTStatementExpression) {
41 if (isAssertOrFailStatement((ASTStatementExpression) n)) {
42 return true;
43 }
44 }
45 if (!assertFound) {
46 for (int i = 0; i < n.jjtGetNumChildren() && !assertFound; i++) {
47 Node c = n.jjtGetChild(i);
48 if (containsAssert(c, assertFound)) {
49 return true;
50 }
51 }
52 }
53 }
54 return false;
55 }
56
57
58
59
60 private boolean containsExpect(Node methodParent) {
61 List<ASTNormalAnnotation> annotations = methodParent.findDescendantsOfType(ASTNormalAnnotation.class);
62 for (ASTNormalAnnotation annotation : annotations) {
63 ASTName name = annotation.getFirstChildOfType(ASTName.class);
64 if (name != null
65 && ("Test".equals(name.getImage()) || name.getType() != null && name.getType().equals(JUNIT4_CLASS))) {
66 List<ASTMemberValuePair> memberValues = annotation.findDescendantsOfType(ASTMemberValuePair.class);
67 for (ASTMemberValuePair pair : memberValues) {
68 if ("expected".equals(pair.getImage())) {
69 return true;
70 }
71 }
72 }
73 }
74 return false;
75 }
76
77
78
79
80 private boolean isAssertOrFailStatement(ASTStatementExpression expression) {
81 if (expression != null && expression.jjtGetNumChildren() > 0
82 && expression.jjtGetChild(0) instanceof ASTPrimaryExpression) {
83 ASTPrimaryExpression pe = (ASTPrimaryExpression) expression.jjtGetChild(0);
84 if (pe.jjtGetNumChildren() > 0 && pe.jjtGetChild(0) instanceof ASTPrimaryPrefix) {
85 ASTPrimaryPrefix pp = (ASTPrimaryPrefix) pe.jjtGetChild(0);
86 if (pp.jjtGetNumChildren() > 0 && pp.jjtGetChild(0) instanceof ASTName) {
87 String img = ((ASTName) pp.jjtGetChild(0)).getImage();
88 if (img != null
89 && (img.startsWith("assert") || img.startsWith("fail") || img.startsWith("Assert.assert") || img
90 .startsWith("Assert.fail"))) {
91 return true;
92 }
93 }
94 }
95 }
96 return false;
97 }
98 }