/**
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
package net.sourceforge.pmd.lang.apex.rule.apexunit;
import net.sourceforge.pmd.lang.apex.ast.ASTMethod;
import net.sourceforge.pmd.lang.apex.ast.ASTModifierNode;
import net.sourceforge.pmd.lang.apex.ast.ASTUserClass;
import net.sourceforge.pmd.lang.apex.ast.ApexNode;
import apex.jorje.semantic.ast.modifier.Annotation;
import apex.jorje.semantic.ast.modifier.AnnotationParameter;
import apex.jorje.semantic.ast.modifier.ModifierOrAnnotation;
import apex.jorje.semantic.symbol.type.AnnotationTypeInfos;
import apex.jorje.semantic.symbol.type.TypeInfoEquivalence;
import apex.jorje.services.Version;
/**
* <p>
* It's a very bad practice to use @isTest(seeAllData=true) in Apex unit tests,
* because it opens up the existing database data for unexpected modification by
* tests.
* </p>
*
* @author a.subramanian
*/
public class ApexUnitTestShouldNotUseSeeAllDataTrue extends AbstractApexUnitTestRule {
@Override
public Object visit(final ASTUserClass node, final Object data) {
// @isTest(seeAllData) was introduced in v24, and was set to false by
// default
final Version classApiVersion = node.getNode().getDefiningType().getCodeUnitDetails().getVersion();
if (!isTestMethodOrClass(node) && classApiVersion.isGreaterThan(Version.V174)) {
return data;
}
checkForSeeAllData(node, data);
return super.visit(node, data);
}
@Override
public Object visit(ASTMethod node, Object data) {
if (!isTestMethodOrClass(node)) {
return data;
}
return checkForSeeAllData(node, data);
}
private Object checkForSeeAllData(final ApexNode<?> node, final Object data) {
final ASTModifierNode modifierNode = node.getFirstChildOfType(ASTModifierNode.class);
if (modifierNode != null) {
for (final ModifierOrAnnotation modifierOrAnnotation : modifierNode.getNode().getModifiers().allNodes()) {
if (modifierOrAnnotation instanceof Annotation && TypeInfoEquivalence
.isEquivalent(modifierOrAnnotation.getType(), AnnotationTypeInfos.IS_TEST)) {
final Annotation annotation = (Annotation) modifierOrAnnotation;
final AnnotationParameter parameter = annotation.getParameter("seeAllData");
if (parameter != null && parameter.getBooleanValue() == true) {
addViolation(data, node);
return data;
}
}
}
}
return data;
}
}