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.ASTTypeParameters;
16  import net.sourceforge.pmd.ast.Node;
17  
18  public class JUnitTestsShouldContainAsserts extends AbstractRule implements Rule {
19  
20      public Object visit(ASTClassOrInterfaceDeclaration node, Object data) {
21          if (node.isInterface()) {
22              return data;
23          }
24          return super.visit(node, data);
25      }
26  
27      public Object visit(ASTMethodDeclaration method, Object data) {
28          if (!method.isPublic() || method.isAbstract() || method.isNative() || method.isStatic()) {
29              return data; // skip various inapplicable method variations
30          }
31  
32          Node node = method.jjtGetChild(0);
33          if (node instanceof ASTTypeParameters) {
34              node = method.jjtGetChild(1);
35          }
36          if (((ASTResultType)node).isVoid() && method.getMethodName().startsWith("test"))  {
37              if (!containsAssert(method.getBlock(), false)) {
38                  addViolation(data, method);
39              }
40          }
41  		return data;
42  	}
43  
44      private boolean containsAssert(Node n, boolean assertFound) {
45          if (!assertFound) {
46              if (n instanceof ASTStatementExpression) {
47                  if (isAssertOrFailStatement((ASTStatementExpression)n)) {
48                      return true;
49                  }
50              }
51              if (!assertFound) {
52                  for (int i=0;i<n.jjtGetNumChildren() && ! assertFound;i++) {
53                      Node c = n.jjtGetChild(i);
54                      if (containsAssert(c, assertFound)) 
55                          return true;
56                  }
57              }
58          }
59          return false;
60      }
61  
62      /***
63       * Tells if the expression is an assert statement or not.
64       */
65      private boolean isAssertOrFailStatement(ASTStatementExpression expression) {
66          if (expression!=null 
67                  && expression.jjtGetNumChildren()>0
68                  && expression.jjtGetChild(0) instanceof ASTPrimaryExpression
69                  ) {
70              ASTPrimaryExpression pe = (ASTPrimaryExpression) expression.jjtGetChild(0);
71              if (pe.jjtGetNumChildren()> 0 && pe.jjtGetChild(0) instanceof ASTPrimaryPrefix) {
72                  ASTPrimaryPrefix pp = (ASTPrimaryPrefix) pe.jjtGetChild(0);
73                  if (pp.jjtGetNumChildren()>0 && pp.jjtGetChild(0) instanceof ASTName) {
74                      ASTName n = (ASTName) pp.jjtGetChild(0);
75                      if (n.getImage()!=null && (n.getImage().startsWith("assert") || n.getImage().startsWith("fail") )) {
76                          return true;
77                      }
78                  }
79              }
80          }
81          return false;
82      }
83  }