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  }