package fr.inria.diversify.processor.test; import spoon.processing.AbstractProcessor; import spoon.reflect.code.CtInvocation; import spoon.reflect.declaration.CtAnnotation; import spoon.reflect.declaration.CtMethod; import spoon.reflect.declaration.CtType; import spoon.reflect.declaration.ModifierKind; import spoon.reflect.reference.CtPackageReference; import spoon.reflect.reference.CtTypeReference; import java.util.*; /** * Created by Simon on 03/12/14. */ public abstract class TestProcessor extends AbstractProcessor<CtMethod> { public static List<CtMethod> notHarmanTest = new LinkedList<>(); protected static List<CtMethod> mutatedMethod = new LinkedList<>(); protected static int count = 0; protected String logName = "fr.inria.diversify.testamplification.logger.Logger"; public static Set<CtType> ampclasses = new HashSet<>(); protected boolean guavaTestlib = false; protected int cloneNumber = 1; @Override public boolean isToBeProcessed(CtMethod candidate) { return isTest(candidate) && !mutatedMethod.contains(candidate) && !testWhitThread(candidate); } protected boolean isTest(CtMethod candidate) { if(candidate.isImplicit() || !candidate.getModifiers().contains(ModifierKind.PUBLIC) || candidate.getBody() == null || candidate.getBody().getStatements().size() == 0) { return false; } if(!guavaTestlib) { return candidate.getSimpleName().contains("test") || candidate.getAnnotations().stream() .map(annotation -> annotation.toString()) .anyMatch(annotation -> annotation.startsWith("@org.junit.Test")); } else { return candidate.getDeclaringType().getSimpleName().endsWith("Tester") && (candidate.getSimpleName().contains("test") || candidate.getAnnotations().stream() .map(annotation -> annotation.toString()) .anyMatch(annotation -> annotation.startsWith("@org.junit.Test"))); } } public void setGuavaTestlib(boolean guavaTestlib) { this.guavaTestlib = guavaTestlib; } protected CtMethod cloneMethod(CtMethod method, String suffix) { count++; CtMethod cloned_method = this.getFactory().Core().clone(method); cloned_method.setParent(method.getParent()); //rename the clone cloned_method.setSimpleName(method.getSimpleName()+suffix+cloneNumber); cloneNumber++; CtAnnotation toRemove = cloned_method.getAnnotations().stream() .filter(annotation -> annotation.toString().contains("Override")) .findFirst().orElse(null); if(toRemove != null) { cloned_method.removeAnnotation(toRemove); } mutatedMethod.add(cloned_method); return cloned_method; } protected CtMethod cloneMethodTest(CtMethod method, String suffix, int timeOut) { CtMethod cloned_method = cloneMethod(method,suffix); CtAnnotation testAnnotation = cloned_method.getAnnotations().stream() .filter(annotation -> annotation.toString().contains("Test")) .findFirst().orElse(null); if(testAnnotation != null) { cloned_method.removeAnnotation(testAnnotation); } testAnnotation = getFactory().Core().createAnnotation(); CtTypeReference<Object> ref = getFactory().Core().createTypeReference(); ref.setSimpleName("Test"); CtPackageReference refPackage = getFactory().Core().createPackageReference(); refPackage.setSimpleName("org.junit"); ref.setPackage(refPackage); testAnnotation.setAnnotationType(ref); Map<String, Object> elementValue = new HashMap<String, Object>(); elementValue.put("timeout", timeOut); testAnnotation.setElementValues(elementValue); cloned_method.addAnnotation(testAnnotation); ampclasses.add(cloned_method.getDeclaringType()); return cloned_method; } protected boolean isAssert(CtInvocation invocation) { try { Class cl = invocation.getExecutable().getDeclaringType().getActualClass(); String signature = invocation.getSignature(); return (signature.contains("assert") || signature.contains("fail")) && isAssertInstance(cl); } catch (Exception e) { return false; } } protected boolean isAssertInstance(Class cl) { if (cl.equals(org.junit.Assert.class) || cl.equals(junit.framework.Assert.class)) return true; Class superCl = cl.getSuperclass(); if(superCl != null) { return isAssertInstance(superCl); } return false; } public static int getCount() { return count; } protected boolean testWhitThread(CtMethod method) { return method.toString().contains("Thread"); } protected String getLogName() { return logName; } public void setLogger(String logName) { this.logName = logName; } }