Skip to content

Commit

Permalink
feat: FIX #539 replace all occurences of original name (#540)
Browse files Browse the repository at this point in the history
* test: create amplified test class should replace all occurences of original test name with amplified test name

* feat: replaces all the occurences of the original test class in literal

* fix: removes parameter to use singleton

* fix: checks if the literal is a String
  • Loading branch information
danglotb authored Sep 5, 2018
1 parent 8fe41b3 commit 7917f8a
Show file tree
Hide file tree
Showing 16 changed files with 104 additions and 32 deletions.
2 changes: 1 addition & 1 deletion dspot/src/main/java/eu/stamp_project/dspot/DSpot.java
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ public CtType amplifyTest(CtType test, List<CtMethod<?>> methods) {
final File outputDirectory = new File(inputConfiguration.getOutputDirectory());
LOGGER.info("Print {} with {} amplified test cases in {}", amplification.getSimpleName(),
testSelector.getAmplifiedTestCases().size(), this.inputConfiguration.getOutputDirectory());
DSpotUtils.printAmplifiedTestClass(amplification, outputDirectory, this.inputConfiguration.withComment());
DSpotUtils.printAmplifiedTestClass(amplification, outputDirectory);
FileUtils.cleanDirectory(compiler.getSourceOutputDirectory());
try {
String pathToDotClass = compiler.getBinaryOutputDirectory().getAbsolutePath() + "/" +
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ public List<CtMethod<?>> selectToKeep(List<CtMethod<?>> amplifiedTestToBeKept) {
.forEach(clone::removeMethod);
amplifiedTestToBeKept.forEach(clone::addMethod);

DSpotUtils.printCtTypeToGivenDirectory(clone, new File(DSpotCompiler.PATH_TO_AMPLIFIED_TEST_SRC), InputConfiguration.get().withComment());
DSpotUtils.printCtTypeToGivenDirectory(clone, new File(DSpotCompiler.PATH_TO_AMPLIFIED_TEST_SRC));

InputConfiguration.get().setAbsolutePathToProjectRoot(this.pathToSecondVersionOfProgram);
DSpotCompiler.compile(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ public List<CtMethod<?>> selectToKeep(List<CtMethod<?>> amplifiedTestToBeKept) {
.filter(AmplificationChecker::isTest)
.forEach(clone::removeMethod);
amplifiedTestToBeKept.forEach(clone::addMethod);
DSpotUtils.printCtTypeToGivenDirectory(clone, new File(PATH_TO_COPIED_FILES), configuration.withComment());
DSpotUtils.printCtTypeToGivenDirectory(clone, new File(PATH_TO_COPIED_FILES));
final Map<String, Map<String, List<Integer>>> lineCoveragePerTestMethods =
CloverExecutor.execute(this.configuration, PATH_TO_COPIED_FILES, clone.getQualifiedName());
final List<CtMethod<?>> selectedTests = this.selectTests(clone, lineCoveragePerTestMethods);
Expand Down Expand Up @@ -168,7 +168,7 @@ private Coverage computeAmplifiedCoverage() {
clone.setParent(this.currentClassTestToBeAmplified.getParent());
this.selectedAmplifiedTest.forEach(clone::addMethod);

DSpotUtils.printCtTypeToGivenDirectory(clone, new File(DSpotCompiler.PATH_TO_AMPLIFIED_TEST_SRC), configuration.withComment());
DSpotUtils.printCtTypeToGivenDirectory(clone, new File(DSpotCompiler.PATH_TO_AMPLIFIED_TEST_SRC));

final String classpath =
this.configuration.getDependencies()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ public List<CtMethod<?>> selectToKeep(List<CtMethod<?>> amplifiedTestToBeKept) {
amplifiedTestToBeKept.forEach(clone::addMethod);

// pretty print it
DSpotUtils.printCtTypeToGivenDirectory(clone, new File(DSpotCompiler.PATH_TO_AMPLIFIED_TEST_SRC), configuration.withComment());
DSpotUtils.printCtTypeToGivenDirectory(clone, new File(DSpotCompiler.PATH_TO_AMPLIFIED_TEST_SRC));

// then compile
final String classpath = this.configuration.getDependencies()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ public void report() {
} catch (IOException ignored) {
//ignored
}
DSpotUtils.printCtTypeToGivenDirectory(clone, new File(DSpotCompiler.PATH_TO_AMPLIFIED_TEST_SRC), configuration.withComment());
DSpotUtils.printCtTypeToGivenDirectory(clone, new File(DSpotCompiler.PATH_TO_AMPLIFIED_TEST_SRC));
this.currentClassTestToBeAmplified.getPackage().removeType(clone);

final String fileSeparator = System.getProperty("file.separator");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ public List<CtMethod<?>> selectToKeep(List<CtMethod<?>> amplifiedTestToBeKept) {
.forEach(clone::removeMethod);
amplifiedTestToBeKept.forEach(clone::addMethod);

DSpotUtils.printCtTypeToGivenDirectory(clone, new File(DSpotCompiler.PATH_TO_AMPLIFIED_TEST_SRC), configuration.withComment());
DSpotUtils.printCtTypeToGivenDirectory(clone, new File(DSpotCompiler.PATH_TO_AMPLIFIED_TEST_SRC));
final AutomaticBuilder automaticBuilder = InputConfiguration.get().getBuilder();
final String classpath = InputConfiguration.get().getBuilder()
.buildClasspath()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ private boolean printAndCompile(InputConfiguration configuration, CtType<?> clon
.filter(AmplificationChecker::isTest)
.forEach(clone::removeMethod);
clone.addMethod(amplifiedTestToBeMinimized);
DSpotUtils.printCtTypeToGivenDirectory(clone, new File(DSpotCompiler.PATH_TO_AMPLIFIED_TEST_SRC), configuration.withComment());
DSpotUtils.printCtTypeToGivenDirectory(clone, new File(DSpotCompiler.PATH_TO_AMPLIFIED_TEST_SRC));
return DSpotCompiler.compile(configuration, DSpotCompiler.PATH_TO_AMPLIFIED_TEST_SRC,
this.configuration.getFullClassPathWithExtraDependencies(),
new File(this.configuration.getAbsolutePathToTestClasses()));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import org.slf4j.LoggerFactory;
import spoon.reflect.code.CtComment;
import spoon.reflect.code.CtInvocation;
import spoon.reflect.code.CtLiteral;
import spoon.reflect.declaration.CtImport;
import spoon.reflect.declaration.CtMethod;
import spoon.reflect.declaration.CtPackage;
Expand Down Expand Up @@ -61,11 +62,12 @@ public static void reset() {
importByClass.clear();
}

@SuppressWarnings("unchecked")
public static CtType<?> createAmplifiedTest(List<CtMethod<?>> ampTest, CtType<?> classTest) {
final Stream<CtMethod<?>> methodToAdd;
if (InputConfiguration.get().shouldMinimize()) {
final Minimizer minimizer = InputConfiguration.get().getSelector().getMinimizer();
methodToAdd = ampTest.stream().map(minimizer::minimize);
methodToAdd = ampTest.stream().map(minimizer::minimize);
} else {
methodToAdd = ampTest.stream();
}
Expand All @@ -76,12 +78,23 @@ public static CtType<?> createAmplifiedTest(List<CtMethod<?>> ampTest, CtType<?>
classTest.getMethods().stream().filter(AmplificationChecker::isTest).forEach(amplifiedTest::removeMethod);
methodToAdd.forEach(amplifiedTest::addMethod);
final CtTypeReference classTestReference = classTest.getReference();
// renaming all the Spoon nodes
amplifiedTest.getElements(new TypeFilter<CtTypeReference>(CtTypeReference.class) {
@Override
public boolean matches(CtTypeReference element) {
return element.equals(classTestReference) && super.matches(element);
}
}).forEach(ctTypeReference -> ctTypeReference.setSimpleName(getAmplifiedName(classTest)));
// need to update also all the String literals
amplifiedTest.getElements(new TypeFilter<CtLiteral>(CtLiteral.class) {
@Override
public boolean matches(CtLiteral element) {
return element.getValue() instanceof String &&
((String)element.getValue()).contains(classTest.getSimpleName());
}
}).forEach(stringCtLiteral ->
stringCtLiteral.setValue(((String)stringCtLiteral.getValue()).replaceAll(classTest.getSimpleName(), amplifiedName))
);
classTest.getPackage().addType(amplifiedTest);
return amplifiedTest;
} else {
Expand Down
10 changes: 5 additions & 5 deletions dspot/src/main/java/eu/stamp_project/utils/DSpotUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -56,25 +56,25 @@ public static String[] getAllTestClasses(InputConfiguration configuration) {
.map(CtType::getQualifiedName).toArray(String[]::new);
}

public static void printCtTypeToGivenDirectory(CtType<?> type, File directory, boolean withComment) {
public static void printCtTypeToGivenDirectory(CtType<?> type, File directory) {
Factory factory = type.getFactory();
Environment env = factory.getEnvironment();
env.setAutoImports(true);
env.setCommentEnabled(withComment);
env.setCommentEnabled(InputConfiguration.get().withComment());
JavaOutputProcessor processor = new JavaOutputProcessor(new DefaultJavaPrettyPrinter(env));
processor.setFactory(factory);
processor.getEnvironment().setSourceOutputDirectory(directory);
processor.createJavaFile(type);
env.setAutoImports(false);
}

public static void printAmplifiedTestClass(CtType<?> type, File directory, boolean withComment) {
public static void printAmplifiedTestClass(CtType<?> type, File directory) {
final String pathname = directory.getAbsolutePath() + "/" + type.getQualifiedName().replaceAll("\\.", "/")
+ ".java";
if (new File(pathname).exists()) {
printCtTypeToGivenDirectory(addGeneratedTestToExistingClass(type, pathname), directory, withComment);
printCtTypeToGivenDirectory(addGeneratedTestToExistingClass(type, pathname), directory);
} else {
printCtTypeToGivenDirectory(type, directory, withComment);
printCtTypeToGivenDirectory(type, directory);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ public static CtType<?> convertToJUnit4(CtType<?> testClassJUnit3,
final CtType<?> convertedSuperclass =
convertToJUnit4(superclass, configuration);
DSpotUtils.printCtTypeToGivenDirectory(convertedSuperclass,
new File(configuration.getAbsolutePathToTestClasses()), configuration.withComment());
new File(configuration.getAbsolutePathToTestClasses()));
final String classpath = configuration.getDependencies()
+ AmplificationHelper.PATH_SEPARATOR +
configuration.getClasspathClassesProject()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ public static List<CtMethod<?>> compileRunAndDiscardUncompilableAndFailingTestMe
* This method will compile the given test class,
* using the {@link eu.stamp_project.utils.compilation.DSpotCompiler}.
* If any compilation problems is reported, the method discard involved test methods, by modifying given test methods, (it has side-effect)
* (see {@link #compileAndDiscardUncompilableMethods(DSpotCompiler, CtType, String, List, boolean)} and then try again to compile.
* (see {@link #compileAndDiscardUncompilableMethods(DSpotCompiler, CtType, String, List)} and then try again to compile.
* </p>
*
* @param testClass the test class to be compiled
Expand All @@ -90,7 +90,7 @@ public static TestListener compileAndRun(CtType<?> testClass,
final String dependencies = configuration.getClasspathClassesProject()
+ AmplificationHelper.PATH_SEPARATOR + "target/dspot/dependencies/";
DSpotUtils.copyPackageFromResources();
testsToRun = TestCompiler.compileAndDiscardUncompilableMethods(compiler, testClass, dependencies, testsToRun, configuration.withComment());
testsToRun = TestCompiler.compileAndDiscardUncompilableMethods(compiler, testClass, dependencies, testsToRun);
final String classPath = AmplificationHelper.getClassPath(compiler, configuration);
EntryPoint.timeoutInMs = 1000 + (configuration.getTimeOutInMs() * testsToRun.size());
if (testClass.getModifiers().contains(ModifierKind.ABSTRACT)) { // if the test class is abstract, we use one of its implementation
Expand All @@ -116,9 +116,8 @@ public static TestListener compileAndRun(CtType<?> testClass,
public static List<CtMethod<?>> compileAndDiscardUncompilableMethods(DSpotCompiler compiler,
CtType<?> testClassToBeCompiled,
String dependencies,
List<CtMethod<?>> testsToRun,
boolean withComment) throws AmplificationException {
final List<CtMethod<?>> uncompilableMethod = compileAndDiscardUncompilableMethods(compiler, testClassToBeCompiled, dependencies, 0, withComment);
List<CtMethod<?>> testsToRun) throws AmplificationException {
final List<CtMethod<?>> uncompilableMethod = compileAndDiscardUncompilableMethods(compiler, testClassToBeCompiled, dependencies, 0);
testsToRun.removeAll(uncompilableMethod);
uncompilableMethod.forEach(testClassToBeCompiled::removeMethod);
if (testsToRun.isEmpty()) {
Expand All @@ -130,10 +129,9 @@ public static List<CtMethod<?>> compileAndDiscardUncompilableMethods(DSpotCompil
private static List<CtMethod<?>> compileAndDiscardUncompilableMethods(DSpotCompiler compiler,
CtType<?> testClassToBeCompiled,
String dependencies,
int numberOfTry,
boolean withComment) throws AmplificationException {
int numberOfTry) throws AmplificationException {

printJavaFileAndDeleteClassFile(compiler, testClassToBeCompiled, withComment);
printJavaFileAndDeleteClassFile(compiler, testClassToBeCompiled);
final List<CategorizedProblem> problems = compiler.compileAndReturnProblems(dependencies)
.stream()
.filter(IProblem::isError)
Expand Down Expand Up @@ -172,7 +170,7 @@ private static List<CtMethod<?>> compileAndDiscardUncompilableMethods(DSpotCompi
);*/
methodsToRemoveInOriginalModel.forEach(testClassToBeCompiled::removeMethod);
final List<CtMethod<?>> recursiveMethodToRemove =
compileAndDiscardUncompilableMethods(compiler, testClassToBeCompiled, dependencies, numberOfTry + 1, withComment);
compileAndDiscardUncompilableMethods(compiler, testClassToBeCompiled, dependencies, numberOfTry + 1);
methodsToRemoveInOriginalModel.addAll(recursiveMethodToRemove);
return new ArrayList<>(methodsToRemoveInOriginalModel);
}
Expand Down Expand Up @@ -205,9 +203,9 @@ private static CtClass<?> getNewModelCtClass(String pathToSrcFolder, String full

// output the .java of the test class to be compiled
// this method delete also the old .class, i.e. the old compiled file of the same test class, if exists
private static void printJavaFileAndDeleteClassFile(DSpotCompiler compiler, CtType classTest, boolean withComment) {
private static void printJavaFileAndDeleteClassFile(DSpotCompiler compiler, CtType classTest) {
try {
DSpotUtils.printCtTypeToGivenDirectory(classTest, compiler.getSourceOutputDirectory(), withComment);
DSpotUtils.printCtTypeToGivenDirectory(classTest, compiler.getSourceOutputDirectory());
} catch (Exception e) {
throw new RuntimeException(e);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ public void test() throws Exception {
Collections.singletonList(Utils.findMethod("example.TestSuiteExample", "test8")));

// pretty print it
DSpotUtils.printCtTypeToGivenDirectory(amplifyTest, new File(DSpotCompiler.PATH_TO_AMPLIFIED_TEST_SRC), Utils.getInputConfiguration().withComment());
DSpotUtils.printCtTypeToGivenDirectory(amplifyTest, new File(DSpotCompiler.PATH_TO_AMPLIFIED_TEST_SRC));

// then compile
final String classpath = InputConfiguration.get().getBuilder()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,17 @@
import eu.stamp_project.AbstractTest;
import eu.stamp_project.Utils;
import eu.stamp_project.program.InputConfiguration;
import org.junit.After;
import org.junit.Test;
import spoon.reflect.code.CtLiteral;
import spoon.reflect.code.CtTypeAccess;
import spoon.reflect.declaration.CtClass;
import spoon.reflect.declaration.CtMethod;
import spoon.reflect.declaration.CtType;
import spoon.reflect.reference.CtTypeReference;
import spoon.reflect.visitor.filter.TypeFilter;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

Expand All @@ -24,6 +28,31 @@
*/
public class AmplificationHelperTest extends AbstractTest {

@After
public void tearDown() throws Exception {
InputConfiguration.get().setGenerateAmplifiedTestClass(false);
}

@Test
public void testCreateAmplifiedTestWithReferenceInString() throws Exception {

/*
test that literals are also replaced if they contain the original test class name when
using --generate-new-test-class command line option
*/

InputConfiguration.get().setGenerateAmplifiedTestClass(true);
final CtClass testClass = Utils.findClass("fr.inria.amplified.AmplifiedTestClassWithReferenceToName");
final CtType amplifiedTest = AmplificationHelper.createAmplifiedTest(new ArrayList<>(testClass.getMethods()), testClass);
assertEquals("AmplAmplifiedTestClassWithReferenceToName", amplifiedTest.getElements(new TypeFilter<>(CtLiteral.class)).get(0).getValue()); // must be updated if the resource change
assertEquals("AmplAmplifiedTestClassWithReferenceToName",
amplifiedTest.getElements(new TypeFilter<>(CtTypeAccess.class))
.get(0)
.getAccessedType()
.getSimpleName()
);
}

@Test
public void testConvertWithSuperClassIsJUnit3() throws Exception {

Expand Down
19 changes: 16 additions & 3 deletions dspot/src/test/java/eu/stamp_project/utils/DSpotUtilsTest.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package eu.stamp_project.utils;

import eu.stamp_project.program.InputConfiguration;
import org.apache.commons.io.FileUtils;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import spoon.Launcher;
import spoon.reflect.declaration.CtMethod;
Expand All @@ -22,6 +25,16 @@ public class DSpotUtilsTest {

private final static File outputDirectory = new File("target/trash/");

@Before
public void setUp() throws Exception {
InputConfiguration.get().setWithComment(true);
}

@After
public void tearDown() throws Exception {
InputConfiguration.get().setWithComment(false);
}

@Test
public void testPrintAmplifiedTestClass() throws Exception {
final File javaFile = new File(outputDirectory.getAbsolutePath() + "/" + "example.TestSuiteExample".replaceAll("\\.", "\\/") + ".java");
Expand All @@ -38,7 +51,7 @@ public void testPrintAmplifiedTestClass() throws Exception {
final CtType<?> type = launcher.getFactory().Type().get("example.TestSuiteExample");

assertFalse(javaFile.exists());
DSpotUtils.printAmplifiedTestClass(type, outputDirectory, true);
DSpotUtils.printAmplifiedTestClass(type, outputDirectory);
assertTrue(javaFile.exists());

final CtMethod<?> clone = type.getMethods().stream()
Expand All @@ -48,7 +61,7 @@ public void testPrintAmplifiedTestClass() throws Exception {
clone.setSimpleName("MyNewMethod");
type.addMethod(clone);

DSpotUtils.printAmplifiedTestClass(type, outputDirectory, true);
DSpotUtils.printAmplifiedTestClass(type, outputDirectory);
launcher = new Launcher();
launcher.addInputResource(outputDirectory.getAbsolutePath() + "/" + "example.TestSuiteExample".replaceAll("\\.", "\\/") + ".java");
launcher.getEnvironment().setNoClasspath(true);
Expand All @@ -60,7 +73,7 @@ public void testPrintAmplifiedTestClass() throws Exception {
clone.setSimpleName("MyNewMethod2");
type.addMethod(clone);

DSpotUtils.printAmplifiedTestClass(type, outputDirectory, true);
DSpotUtils.printAmplifiedTestClass(type, outputDirectory);
launcher = new Launcher();
launcher.addInputResource(outputDirectory.getAbsolutePath() + "/" + "example.TestSuiteExample".replaceAll("\\.", "\\/") + ".java");
launcher.getEnvironment().setNoClasspath(true);
Expand Down
Loading

0 comments on commit 7917f8a

Please sign in to comment.