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)
32 && !containsExpect(method.jjtGetParent())) {
33 addViolation(data, method);
34 }
35 }
36 return data;
37 }
38
39 private boolean containsAssert(Node n, boolean assertFound) {
40 if (!assertFound) {
41 if (n instanceof ASTStatementExpression) {
42 if (isAssertOrFailStatement((ASTStatementExpression)n)) {
43 return true;
44 }
45 }
46 if (!assertFound) {
47 for (int i=0;i<n.jjtGetNumChildren() && ! assertFound;i++) {
48 Node c = n.jjtGetChild(i);
49 if (containsAssert(c, assertFound)) {
50 return true;
51 }
52 }
53 }
54 }
55 return false;
56 }
57
58
59
60
61 private boolean containsExpect(Node methodParent) {
62 List<ASTNormalAnnotation> annotations = methodParent.findDescendantsOfType(ASTNormalAnnotation.class);
63 for (ASTNormalAnnotation annotation : annotations) {
64 ASTName name = annotation.getFirstChildOfType(ASTName.class);
65 if (name != null && ("Test".equals(name.getImage())
66 || (name.getType() != null && name.getType().equals(JUNIT4_CLASS)))) {
67 List<ASTMemberValuePair> memberValues = annotation.findDescendantsOfType(ASTMemberValuePair.class);
68 for (ASTMemberValuePair pair : memberValues) {
69 if ("expected".equals(pair.getImage())) {
70 return true;
71 }
72 }
73 }
74 }
75 return false;
76 }
77
78
79
80
81 private boolean isAssertOrFailStatement(ASTStatementExpression expression) {
82 if (expression!=null
83 && expression.jjtGetNumChildren()>0
84 && expression.jjtGetChild(0) instanceof ASTPrimaryExpression
85 ) {
86 ASTPrimaryExpression pe = (ASTPrimaryExpression) expression.jjtGetChild(0);
87 if (pe.jjtGetNumChildren()> 0 && pe.jjtGetChild(0) instanceof ASTPrimaryPrefix) {
88 ASTPrimaryPrefix pp = (ASTPrimaryPrefix) pe.jjtGetChild(0);
89 if (pp.jjtGetNumChildren()>0 && pp.jjtGetChild(0) instanceof ASTName) {
90 String img = ((ASTName) pp.jjtGetChild(0)).getImage();
91 if (img != null && (img.startsWith("assert") || img.startsWith("fail") || img.startsWith("Assert.assert") || img.startsWith("Assert.fail") )) {
92 return true;
93 }
94 }
95 }
96 }
97 return false;
98 }
99 }