Skip to content

Commit

Permalink
Merge a93e5f4 into 241ff9c
Browse files Browse the repository at this point in the history
  • Loading branch information
danglotb committed Dec 7, 2016
2 parents 241ff9c + a93e5f4 commit ca609ed
Show file tree
Hide file tree
Showing 9 changed files with 197 additions and 27 deletions.
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
package fr.inria.diversify.dspot.amp;

import spoon.reflect.code.CtCase;
import spoon.reflect.code.CtInvocation;
import spoon.reflect.code.CtLiteral;
import spoon.reflect.code.CtStatement;
import spoon.reflect.code.*;

/**
* Created by Benjamin DANGLOT
Expand Down Expand Up @@ -37,4 +34,8 @@ private static boolean isAssertInstance(Class cl) {
Class superCl = cl.getSuperclass();
return superCl != null && isAssertInstance(superCl);
}

public static boolean canBeAdded(CtInvocation invocation) {
return !invocation.toString().startsWith("super(") && invocation.getParent() instanceof CtBlock;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public static Random getRandom() {
return random;
}

static void reset() {
public static void reset() {
cloneNumber = 1;
ampTestToParent = new HashMap<>();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package fr.inria.diversify.dspot.amp;

import fr.inria.diversify.log.branch.Coverage;
import spoon.reflect.code.CtBlock;
import spoon.reflect.code.CtInvocation;
import spoon.reflect.declaration.CtMethod;
import spoon.reflect.declaration.CtType;
Expand All @@ -12,6 +11,7 @@
import java.util.List;



public class TestMethodCallAdder implements Amplifier {

public List<CtMethod> apply(CtMethod method) {
Expand All @@ -24,10 +24,11 @@ public List<CtMethod> apply(CtMethod method) {
int invocation_index = 0;
for (CtInvocation invocation : invocations) {
try {
if (toAdd(invocation) && !AmplifierChecker.isAssert(invocation)) {
if (AmplifierChecker.canBeAdded(invocation) && !AmplifierChecker.isAssert(invocation)) {
methods.add(apply(method, invocation_index));
}
} catch (Exception e) {
throw new RuntimeException(e);
}
invocation_index++;
}
Expand All @@ -38,12 +39,12 @@ public List<CtMethod> apply(CtMethod method) {
public CtMethod applyRandom(CtMethod method) {
if (method.getDeclaringType() != null) {
List<CtInvocation> invocations = Query.getElements(method, new TypeFilter(CtInvocation.class));

while (!invocations.isEmpty()) {
try {
int invocation_index = AmplifierHelper.getRandom().nextInt(invocations.size());
return apply(method, invocation_index);
} catch (Exception e) {
} catch (Exception ignored) {

}
}
}
Expand All @@ -55,7 +56,7 @@ public void reset(Coverage coverage, CtType testClass) {
AmplifierHelper.reset();
}

protected CtMethod apply(CtMethod method, int invocation_index) {
private CtMethod apply(CtMethod method, int invocation_index) {
CtMethod cloned_method = AmplifierHelper.cloneMethodTest(method, "_add", 1000);
//add the cloned method in the same class as the original method
//get the lit_indexth literal of the cloned method
Expand All @@ -67,8 +68,5 @@ protected CtMethod apply(CtMethod method, int invocation_index) {
return cloned_method;
}

public boolean toAdd(CtInvocation invocation) {
return !invocation.toString().startsWith("super(")
&& invocation.getParent() instanceof CtBlock;
}

}
10 changes: 10 additions & 0 deletions src/test/java/fr/inria/diversify/Utils.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import fr.inria.diversify.runner.InputConfiguration;
import fr.inria.diversify.runner.InputProgram;
import fr.inria.diversify.util.InitUtils;
import spoon.Launcher;
import spoon.reflect.declaration.CtClass;
import spoon.reflect.declaration.CtMethod;

Expand Down Expand Up @@ -72,4 +73,13 @@ public static CtMethod findMethod(String className, String methodName) throws In
.findFirst()
.orElse(null);
}

public static Launcher buildSpoon() {
Launcher launcher = new Launcher();
launcher.getEnvironment().setNoClasspath(true);
launcher.addInputResource("src/test/resources/mutation/ClassUnderTestTest.java");
launcher.addInputResource("src/test/resources/mutation/ClassUnderTest.java");
launcher.buildModel();
return launcher;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package fr.inria.diversify.dspot.amp;

import fr.inria.diversify.Utils;
import org.junit.Test;
import spoon.Launcher;
import spoon.reflect.code.CtStatement;
import spoon.reflect.declaration.CtClass;
import spoon.reflect.declaration.CtMethod;

import java.util.List;

import static org.junit.Assert.assertEquals;

/**
* Created by Benjamin DANGLOT
* benjamin.danglot@inria.fr
* on 12/7/16
*/
public class TestMethodCallAdderTest {

@Test
public void testMethodCallAddAll() throws Exception {

/*
Test that we reuse method call in a test for each used method in the test.
3 method are called in the original test, we produce 3 test methods.
*/

Launcher launcher = Utils.buildSpoon();
CtClass<Object> testClass = launcher.getFactory().Class().get("mutation.ClassUnderTestTest");

TestMethodCallAdder methodCallAdder = new TestMethodCallAdder();
methodCallAdder.reset(null, null);

final CtMethod<?> originalMethod = testClass.getMethods().stream().filter(m -> "testAddCall".equals(m.getSimpleName())).findFirst().get();
List<CtMethod> amplifiedMethods = methodCallAdder.apply(originalMethod);

assertEquals(3, amplifiedMethods.size());

for (int i = 0; i < amplifiedMethods.size(); i++) {
CtMethod amplifiedMethod = amplifiedMethods.get(i);
assertEquals(originalMethod.getBody().getStatements().size() + 1, amplifiedMethod.getBody().getStatements().size());
CtStatement expectedStatement = originalMethod.getBody().getStatements().get(i + 1);//+1 to skip the construction statement.
assertEquals(expectedStatement, amplifiedMethod.getBody().getStatements().get(i + 1));
assertEquals(expectedStatement, amplifiedMethod.getBody().getStatements().get(i + 2));
}
}

@Test
public void testMethodCallAddRandom() throws Exception {

/*
Test that we duplicate method call in a test for each used method in the test.
Here, we test the applyRandom feature that will build one method randomly by reusing an existing call.
*/

AmplifierHelper.setSeedRandom(23L);
Launcher launcher = Utils.buildSpoon();
CtClass<Object> testClass = launcher.getFactory().Class().get("mutation.ClassUnderTestTest");

TestMethodCallAdder methodCallAdder = new TestMethodCallAdder();
methodCallAdder.reset(null, null);

final CtMethod<?> originalMethod = testClass.getMethods().stream().filter(m -> "testAddCall".equals(m.getSimpleName())).findFirst().get();
CtMethod amplifiedMethod = methodCallAdder.applyRandom(originalMethod);

assertEquals(originalMethod.getBody().getStatements().size() + 1, amplifiedMethod.getBody().getStatements().size());
CtStatement expectedStatement = originalMethod.getBody().getStatements().get(2);
assertEquals(expectedStatement, amplifiedMethod.getBody().getStatements().get(2));
assertEquals(expectedStatement, amplifiedMethod.getBody().getStatements().get(3));


amplifiedMethod = methodCallAdder.applyRandom(originalMethod);
assertEquals(originalMethod.getBody().getStatements().size() + 1, amplifiedMethod.getBody().getStatements().size());
expectedStatement = originalMethod.getBody().getStatements().get(3);
assertEquals(expectedStatement, amplifiedMethod.getBody().getStatements().get(3));
assertEquals(expectedStatement, amplifiedMethod.getBody().getStatements().get(4));

amplifiedMethod = methodCallAdder.applyRandom(originalMethod);
assertEquals(originalMethod.getBody().getStatements().size() + 1, amplifiedMethod.getBody().getStatements().size());
expectedStatement = originalMethod.getBody().getStatements().get(1);
assertEquals(expectedStatement, amplifiedMethod.getBody().getStatements().get(1));
assertEquals(expectedStatement, amplifiedMethod.getBody().getStatements().get(2));

// stack random amplification
CtMethod stackedAmplifiedMethod = methodCallAdder.applyRandom(amplifiedMethod);
assertEquals(amplifiedMethod.getBody().getStatements().size() + 1, stackedAmplifiedMethod.getBody().getStatements().size());
assertEquals(originalMethod.getBody().getStatements().size() + 2, stackedAmplifiedMethod.getBody().getStatements().size());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package fr.inria.diversify.dspot.amp;

import fr.inria.diversify.Utils;
import org.junit.Test;
import spoon.Launcher;
import spoon.reflect.code.CtStatement;
import spoon.reflect.declaration.CtClass;
import spoon.reflect.declaration.CtMethod;

import java.util.List;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;

/**
* Created by Benjamin DANGLOT
* benjamin.danglot@inria.fr
* on 12/7/16
*/
public class TestMethodCallRemove {

@Test
public void testMethodCallRemoveAll() throws Exception {

/*
Test that we remove method call in a test for each used method in the test.
3 method are called in the original test, we produce 3 test methods.
*/

Launcher launcher = Utils.buildSpoon();
CtClass<Object> testClass = launcher.getFactory().Class().get("mutation.ClassUnderTestTest");

TestMethodCallRemover methodCallRemove = new TestMethodCallRemover();
methodCallRemove.reset(null, null);

final CtMethod<?> originalMethod = testClass.getMethods().stream().filter(m -> "testAddCall".equals(m.getSimpleName())).findFirst().get();
List<CtMethod> amplifiedMethods = methodCallRemove.apply(originalMethod);

assertEquals(3, amplifiedMethods.size());

for (int i = 0; i < amplifiedMethods.size(); i++) {
assertEquals(originalMethod.getBody().getStatements().size() - 1, amplifiedMethods.get(i).getBody().getStatements().size());
assertNotEquals(amplifiedMethods.get((i+1) % amplifiedMethods.size()).getBody(), amplifiedMethods.get(i).getBody());//checks that all generated methods are different
}
}

@Test
public void testMethodCallRemoveRnd() throws Exception {

/*
Test that we remove method call in a test for each used method in the test.
3 method are called in the original test, we produce 2 test methods randomly among them.
*/

AmplifierHelper.setSeedRandom(23L);
Launcher launcher = Utils.buildSpoon();
CtClass<Object> testClass = launcher.getFactory().Class().get("mutation.ClassUnderTestTest");

TestMethodCallRemover methodCallRemove = new TestMethodCallRemover();
methodCallRemove.reset(null, null);

final CtMethod<?> originalMethod = testClass.getMethods().stream().filter(m -> "testAddCall".equals(m.getSimpleName())).findFirst().get();
CtMethod amplifiedMethod = methodCallRemove.applyRandom(originalMethod);
CtMethod amplifiedMethod2 = methodCallRemove.applyRandom(originalMethod);

assertEquals(originalMethod.getBody().getStatements().size() - 1, amplifiedMethod.getBody().getStatements().size());
assertEquals(originalMethod.getBody().getStatements().size() - 1, amplifiedMethod2.getBody().getStatements().size());
assertNotEquals(amplifiedMethod.getBody().getStatements(), amplifiedMethod2.getBody().getStatements());
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package fr.inria.diversify.dspot.amp;

import fr.inria.diversify.Utils;
import org.junit.Test;
import spoon.Launcher;
import spoon.reflect.code.CtInvocation;
import spoon.reflect.code.CtLocalVariable;
import spoon.reflect.declaration.CtClass;
import spoon.reflect.declaration.CtElement;
import spoon.reflect.declaration.CtMethod;
import spoon.reflect.visitor.filter.TypeFilter;

Expand Down Expand Up @@ -34,13 +34,13 @@ public void testStatementAdderOnAssertLiteral() throws Exception {
*/

AmplifierHelper.setSeedRandom(23L);
Launcher launcher = buildSpoon();
Launcher launcher = Utils.buildSpoon();
CtClass<Object> ctClass = launcher.getFactory().Class().get("mutation.ClassUnderTestTest");

StatementAdderOnAssert amplificator = new StatementAdderOnAssert();
amplificator.reset(null, ctClass);

CtMethod originalMethod = ctClass.getElements(new TypeFilter<>(CtMethod.class)).get(0);
CtMethod originalMethod = ctClass.getElements(new TypeFilter<>(CtMethod.class)).stream().filter(m -> "testLit".equals(m.getSimpleName())).findFirst().get();
List<CtMethod> amplifiedMethods = amplificator.apply(originalMethod);

amplifiedMethods.forEach(method -> {
Expand Down Expand Up @@ -76,12 +76,5 @@ public boolean matches(CtLocalVariable ctLocalVariable) {
assertTrue(amplifiedMethods.get(8).getBody().getStatement(3) instanceof CtInvocation);
}

private Launcher buildSpoon() {
Launcher launcher = new Launcher();
launcher.getEnvironment().setNoClasspath(true);
launcher.addInputResource("src/test/resources/mutation/ClassUnderTestTest.java");
launcher.addInputResource("src/test/resources/mutation/ClassUnderTest.java");
launcher.buildModel();
return launcher;
}

}
2 changes: 1 addition & 1 deletion src/test/resources/mutation/ClassUnderTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ public int plusOne(int integer) {
return integer + 1;
}

public int minueOne(int integer) {
public int minusOne(int integer) {
return integer - 1;
}

Expand Down
10 changes: 9 additions & 1 deletion src/test/resources/mutation/ClassUnderTestTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,14 @@ public class ClassUnderTestTest {
public void testLit() {
ClassUnderTest underTest = new ClassUnderTest();
assertEquals(1, underTest.plusOne(0));
assertEquals(0, underTest.minueOne(1));
assertEquals(0, underTest.minusOne(1));
}

@Test
public void testAddCall() throws Exception {
ClassUnderTest underTest = new ClassUnderTest();
underTest.plusOne(0);
underTest.minusOne(1);
underTest.timesTwo(1);
}
}

0 comments on commit ca609ed

Please sign in to comment.