View Javadoc

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; // skip various inapplicable method variations
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  }