View Javadoc

    1   package net.sourceforge.pmd.rules.junit;
    2
    3   import java.util.List;
    4
    5   import net.sourceforge.pmd.AbstractJavaRule;
    6   import net.sourceforge.pmd.ast.ASTClassOrInterfaceDeclaration;
    7   import net.sourceforge.pmd.ast.ASTClassOrInterfaceType;
    8   import net.sourceforge.pmd.ast.ASTCompilationUnit;
    9   import net.sourceforge.pmd.ast.ASTExtendsList;
    10  import net.sourceforge.pmd.ast.ASTMarkerAnnotation;
    11  import net.sourceforge.pmd.ast.ASTMethodDeclaration;
    12  import net.sourceforge.pmd.ast.ASTName;
    13  import net.sourceforge.pmd.ast.ASTResultType;
    14  import net.sourceforge.pmd.ast.ASTTypeParameters;
    15  import net.sourceforge.pmd.ast.Node;
    16  import net.sourceforge.pmd.ast.SimpleNode;
    17  import net.sourceforge.pmd.typeresolution.TypeHelper;
    18
    19  @SuppressWarnings("PMD.AvoidCatchingThrowable") // Don't think we can otherwise here...
    20  public abstract class AbstractJUnitRule extends AbstractJavaRule {
    21
    22      public static Class junit4Class = null;
    23
    24      public static Class junit3Class = null;
    25
    26      private boolean isJUnit3Class;
    27      private boolean isJUnit4Class;
    28
    29
    30      static {
    31          try {
    32              junit4Class = Class.forName("org.junit.Test");
    33          } catch (Throwable t) {
    34              junit4Class = null;
    35          }
    36
    37          try {
    38              junit3Class = Class.forName("junit.framework.TestCase");
    39          } catch (Throwable t) {
    40              junit3Class = null;
    41          }
    42      }
    43
    44      public Object visit(ASTCompilationUnit node, Object data){
    45
    46      	isJUnit3Class = isJUnit4Class = false;
    47
    48      	isJUnit3Class = isJUnit3Class(node);
    49      	if (!isJUnit3Class) {
    50      		isJUnit4Class = isJUnit4Class(node);
    51      	}
    52
    53          if(isJUnit3Class || isJUnit4Class){
    54              return super.visit(node, data);
    55          }
    56          return data;
    57      }
    58
    59      public boolean isJUnitMethod(ASTMethodDeclaration method, Object data) {
    60
    61          if (!method.isPublic() || method.isAbstract() || method.isNative() || method.isStatic()) {
    62              return false; // skip various inapplicable method variations
    63          }
    64
    65          if (isJUnit3Class) {
    66          	return isJUnit3Method(method);
    67          }
    68          else {
    69          	return isJUnit4Method(method);
    70          }
    71      }
    72
    73      private boolean isJUnit4Method(ASTMethodDeclaration method){
    74      	return doesNodeContainJUnitAnnotation((SimpleNode)method.jjtGetParent());
    75      }
    76
    77      private boolean isJUnit3Method(ASTMethodDeclaration method) {
    78      	Node node = method.jjtGetChild(0);
    79          if (node instanceof ASTTypeParameters) {
    80              node = method.jjtGetChild(1);
    81          }
    82          return ((ASTResultType) node).isVoid() && method.getMethodName().startsWith("test");
    83      }
    84
    85      private boolean isJUnit3Class(ASTCompilationUnit node) {
    86      	if (node.getType() != null && TypeHelper.isA(node, junit3Class)) {
    87              return true;
    88
    89          } else if (node.getType() == null) {
    90              ASTClassOrInterfaceDeclaration cid = node.getFirstChildOfType(ASTClassOrInterfaceDeclaration.class);
    91              if (cid == null) {
    92                  return false;
    93              }
    94              ASTExtendsList extendsList = cid.getFirstChildOfType(ASTExtendsList.class);
    95              if(extendsList == null){
    96                  return false;
    97              }
    98              if(((ASTClassOrInterfaceType)extendsList.jjtGetChild(0)).getImage().endsWith("TestCase")){
    99                  return true;
    100             }
    101             String className = cid.getImage();
    102             return className.endsWith("Test");
    103         }
    104         return false;
    105     }
    106
    107     private boolean isJUnit4Class(ASTCompilationUnit node){
    108         return doesNodeContainJUnitAnnotation(node);
    109     }
    110
    111     private boolean doesNodeContainJUnitAnnotation(SimpleNode node) {
    112     	List<ASTMarkerAnnotation> lstAnnotations = node.findChildrenOfType(ASTMarkerAnnotation.class);
    113         for(ASTMarkerAnnotation annotation : lstAnnotations){
    114         	if(annotation.getType() == null){
    115                 ASTName name = (ASTName)annotation.jjtGetChild(0);
    116                 if("Test".equals(name.getImage())){
    117                     return true;
    118                 }
    119             }
    120             else if(annotation.getType().equals(junit4Class)){
    121                 return true;
    122             }
    123         }
    124         return false;
    125     }
    126
    127 }