1 /***
2 * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
3 */
4 package net.sourceforge.pmd.rules.junit;
5
6 import net.sourceforge.pmd.AbstractRule;
7 import net.sourceforge.pmd.Rule;
8 import net.sourceforge.pmd.ast.ASTClassOrInterfaceDeclaration;
9 import net.sourceforge.pmd.ast.ASTMethodDeclaration;
10 import net.sourceforge.pmd.ast.ASTName;
11 import net.sourceforge.pmd.ast.ASTPrimaryExpression;
12 import net.sourceforge.pmd.ast.ASTPrimaryPrefix;
13 import net.sourceforge.pmd.ast.ASTResultType;
14 import net.sourceforge.pmd.ast.ASTStatementExpression;
15 import net.sourceforge.pmd.ast.Node;
16
17 public class JUnitTestsShouldContainAsserts extends AbstractRule implements Rule {
18
19 public Object visit(ASTClassOrInterfaceDeclaration node, Object data) {
20 if (node.isInterface()) {
21 return data;
22 }
23 return super.visit(node, data);
24 }
25
26 public Object visit(ASTMethodDeclaration method, Object data) {
27 if (!method.isPublic() || method.isAbstract() || method.isNative() || method.isStatic()) {
28 return data;
29 }
30
31 if (((ASTResultType) method.jjtGetChild(0)).isVoid() && method.getMethodName().startsWith("test")) {
32 if (!containsAssert(method.getBlock(), false)) {
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 return false;
55 }
56
57 /***
58 * Tells if the expression is an assert statement or not.
59 */
60 private boolean isAssertOrFailStatement(ASTStatementExpression expression) {
61 if (expression!=null
62 && expression.jjtGetNumChildren()>0
63 && expression.jjtGetChild(0) instanceof ASTPrimaryExpression
64 ) {
65 ASTPrimaryExpression pe = (ASTPrimaryExpression) expression.jjtGetChild(0);
66 if (pe.jjtGetNumChildren()> 0 && pe.jjtGetChild(0) instanceof ASTPrimaryPrefix) {
67 ASTPrimaryPrefix pp = (ASTPrimaryPrefix) pe.jjtGetChild(0);
68 if (pp.jjtGetNumChildren()>0 && pp.jjtGetChild(0) instanceof ASTName) {
69 ASTName n = (ASTName) pp.jjtGetChild(0);
70 if (n.getImage()!=null && (n.getImage().startsWith("assert") || n.getImage().startsWith("fail") )) {
71 return true;
72 }
73 }
74 }
75 }
76 return false;
77 }
78 }