Skip to content

Commit

Permalink
MutationOperator is now an interface and the construction methods wer…
Browse files Browse the repository at this point in the history
…e placed in the MutationOperatorCreator class.
  • Loading branch information
oscarlvp committed Sep 25, 2017
1 parent c5e4af4 commit 34e8de0
Show file tree
Hide file tree
Showing 11 changed files with 62 additions and 53 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,14 @@
import java.util.logging.Level;
import java.util.regex.Pattern;

import fr.inria.stamp.mutationtest.descartes.operators.NullMutationOperator;
import fr.inria.stamp.mutationtest.descartes.operators.VoidMutationOperator;
import fr.inria.stamp.mutationtest.descartes.operators.*;
import org.pitest.reloc.asm.commons.Method;

import org.pitest.functional.predicate.*;

import org.pitest.mutationtest.MutationEngineFactory;
import org.pitest.mutationtest.engine.MutationEngine;

import fr.inria.stamp.mutationtest.descartes.operators.MutationOperator;
import fr.inria.stamp.mutationtest.descartes.operators.WrongOperatorException;

public class DescartesEngineFactory implements MutationEngineFactory{

/**
Expand Down Expand Up @@ -66,7 +62,7 @@ private static Collection<MutationOperator> getMutationOperators(Collection<Stri
for (String id :
mutators) {
try {
result.add(MutationOperator.fromID(id));
result.add(MutationOperatorCreator.fromID(id));
}catch (WrongOperatorException exc) {
org.pitest.util.Log.getLogger().log(Level.WARNING, "Illegal ID value. Details: " + exc.getMessage());
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package fr.inria.stamp.mutationtest.descartes.codegeneration;

import fr.inria.stamp.mutationtest.descartes.operators.MutationOperatorCreator;
import org.pitest.reloc.asm.Opcodes;
import org.pitest.reloc.asm.ClassVisitor;
import org.pitest.reloc.asm.MethodVisitor;
Expand All @@ -25,7 +26,7 @@ public MethodVisitor visitMethod(int access, String name, String desc, String si
Location location = mID.getLocation();
if(location.getMethodDesc().equals(desc) && location.getMethodName().name().equals(name)) {
return new MutationMethodAdapter(
MutationOperator.fromID(mID.getMutator()),
MutationOperatorCreator.fromID(mID.getMutator()),
new Method(location.getMethodName().name(), location.getMethodDesc()),
methodVisitor);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
/**
* A mutation operator that replaces the method body by a return instruction whose result is the given constant
*/
public class ConstantMutationOperator extends MutationOperator {
public class ConstantMutationOperator implements MutationOperator {

final private Object constant;
final private String id;
Expand Down Expand Up @@ -41,7 +41,6 @@ public ConstantMutationOperator(String id, Object constant) {
* @param method Method to be tested by the operator
* @return A boolean value indicating if the return type and the constant value type are the same
*/
@Override
public boolean canMutate(Method method) {
Type methodType = method.getReturnType();
int typeSort = methodType.getSort();
Expand All @@ -62,7 +61,6 @@ public boolean canMutate(Method method) {
* @param method Method to which the mutation should be applied
* @param mv MethodVisitor in charge of code generation.
*/
@Override
public void generateCode(Method method, MethodVisitor mv) {
assert canMutate(method);
mv.visitLdcInsn(constant);
Expand All @@ -71,12 +69,10 @@ public void generateCode(Method method, MethodVisitor mv) {
mv.visitInsn(methodType.getOpcode(Opcodes.IRETURN));
}

@Override
public String getID() {
return id;
}

@Override
public String getDescription() {
return "All method body replaced by: return " + id;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import org.pitest.reloc.asm.Type;
import org.pitest.reloc.asm.commons.Method;

public class EmptyArrayMutationOperator extends MutationOperator {
public class EmptyArrayMutationOperator implements MutationOperator {

/**
* Returns a value indicating whether the operator can transform the given method.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,40 +7,33 @@
/**
* Mutation operator definition
*/
public abstract class MutationOperator {
public interface MutationOperator {

/**
* Returns a value indicating whether the operator can transform the given method.
*
* @param method Method to be tested by the operator
* @return A boolean value indicating if the mutation can be performed
*/
public abstract boolean canMutate(Method method);
boolean canMutate(Method method);

public abstract void generateCode(Method method, MethodVisitor mv);

public abstract String getID();
/**
* Generates the mutated code for the given method.
* @param method method to be mutated
* @param mv Method visitor for code generation.
*/
void generateCode(Method method, MethodVisitor mv);

public abstract String getDescription();
/**
* Gets the ID of this mutation operator to be used in the final report.
* @return A string identifying the mutation operator.
*/
String getID();

public static MutationOperator fromID(String id) {
OperatorParser parser = new OperatorParser(id);
Object value = parser.parse();
if(parser.hasErrors())
throw new WrongOperatorException("Invalid operator id: " + parser.getErrors().get(0));
if(value == null)
return NullMutationOperator.getInstance();
if(value.equals(Void.class)) {
return VoidMutationOperator.getInstance();
}
if(value.equals(EmptyArrayMutationOperator.getInstance().getID())) {
return EmptyArrayMutationOperator.getInstance();
}
try {
return new ConstantMutationOperator(id, value);
}catch (IllegalArgumentException exc) {
throw new WrongOperatorException("Invalid operator id", exc);
}
}
/**
* Gets the description of this mutation operator to be used in the final report.
* @return A string containing the description of the mutation operator.
*/
String getDescription();

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package fr.inria.stamp.mutationtest.descartes.operators;

import fr.inria.stamp.mutationtest.descartes.operators.parsing.OperatorParser;

public final class MutationOperatorCreator {

private MutationOperatorCreator() {}

public static MutationOperator fromID(String id) {
OperatorParser parser = new OperatorParser(id);
Object value = parser.parse();
if(parser.hasErrors())
throw new WrongOperatorException("Invalid operator id: " + parser.getErrors().get(0));
if(value == null)
return NullMutationOperator.getInstance();
if(value.equals(Void.class)) {
return VoidMutationOperator.getInstance();
}
if(value.equals(EmptyArrayMutationOperator.getInstance().getID())) {
return EmptyArrayMutationOperator.getInstance();
}
try {
return new ConstantMutationOperator(id, value);
}catch (IllegalArgumentException exc) {
throw new WrongOperatorException("Invalid operator id", exc);
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
/**
* Replaces the method body with a <code>return null<code/> statement
*/
public class NullMutationOperator extends MutationOperator{
public class NullMutationOperator implements MutationOperator{

/**
* Returns a value indicating whether the operator can transform the given method.
Expand All @@ -18,25 +18,22 @@ public class NullMutationOperator extends MutationOperator{
* @param method Method to be tested by the operator
* @return A boolean value indicating if null can be assigned to the return type
*/
@Override
public boolean canMutate(Method method) {
int target = method.getReturnType().getSort();
return target == Type.OBJECT || target == Type.ARRAY;
}

@Override
public void generateCode(Method method, MethodVisitor mv) {
assert canMutate(method);
mv.visitInsn(Opcodes.ACONST_NULL);
mv.visitInsn(method.getReturnType().getOpcode(Opcodes.IRETURN));
}

@Override
public String getID() {
return "null";
}

@Override

public String getDescription(){
return "All methods instructions replaced by: return null;";
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
* A class whose instances are able to mutate void methods and static initializers
* (Constructors should call super constructors and so they aren't considered here)
*/
public final class VoidMutationOperator extends MutationOperator {
public final class VoidMutationOperator implements MutationOperator {

/**
* Returns a value indicating whether the operator can transform the given method.
Expand All @@ -18,23 +18,19 @@ public final class VoidMutationOperator extends MutationOperator {
* @param method Method to be tested by the operator
* @return True if the given method is void, false otherwise
*/
@Override
public boolean canMutate(Method method) {
//TODO: Detect methods that contain only calls to logging classes or System.out
return !method.getName().equals("<init>") && method.getReturnType().equals(Type.VOID_TYPE);
}

@Override
public void generateCode(Method method, MethodVisitor mv) {
mv.visitInsn(Opcodes.RETURN);
}

@Override
public String getID() {
return "void";
}

@Override
public String getDescription() {
return "All method instructions removed";
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import java.util.Arrays;


import fr.inria.stamp.mutationtest.descartes.operators.MutationOperatorCreator;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
Expand Down Expand Up @@ -37,7 +38,7 @@ public void initialize() {
engine = new DescartesMutationEngine(FCollection.map(operators, new F<String, MutationOperator>()
{
public MutationOperator apply(String id) {
return MutationOperator.fromID(id);
return MutationOperatorCreator.fromID(id);
}

}));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,21 @@ public class MutationOperatorFactoryTest {

@Test
public void shouldCreateVoidMutator() {
MutationOperator operator = MutationOperator.fromID("void");
MutationOperator operator = MutationOperatorCreator.fromID("void");
assertThat(operator, is((MutationOperator) VoidMutationOperator.getInstance()));
}

@Test
public void shouldCreateNullMutator() {
MutationOperator operator = MutationOperator.fromID("null");
MutationOperator operator = MutationOperatorCreator.fromID("null");
assertThat(operator, is((MutationOperator) NullMutationOperator.getInstance()));
}

@Test
public void shouldGetIntegerMutator() {
int value = 3;
String id = String.valueOf(value);
MutationOperator operator = MutationOperator.fromID(id);
MutationOperator operator = MutationOperatorCreator.fromID(id);
assertTrue(operator.getClass().equals(ConstantMutationOperator.class));
assertThat(operator.getID(), is(id));
Object constant = ((ConstantMutationOperator)operator).getConstant();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ public static Collection<Object[]> parameters() {

@Test
public void shouldFilterMethods() {
MutationOperator operator = MutationOperator.fromID(operatorID);
MutationOperator operator = MutationOperatorCreator.fromID(operatorID);
for (Method method: targets) {
if(operator.canMutate(method))
assertEquals("Wrong method accepted", expectedMethod, method.getName());
Expand Down

0 comments on commit 34e8de0

Please sign in to comment.