diff --git a/dspot/src/main/java/eu/stamp_project/dspot/amplifier/amplifiers/AmplifierHelper.java b/dspot/src/main/java/eu/stamp_project/dspot/amplifier/amplifiers/AmplifierHelper.java index db355fccc..08cdd530a 100644 --- a/dspot/src/main/java/eu/stamp_project/dspot/amplifier/amplifiers/AmplifierHelper.java +++ b/dspot/src/main/java/eu/stamp_project/dspot/amplifier/amplifiers/AmplifierHelper.java @@ -4,13 +4,8 @@ import eu.stamp_project.dspot.amplifier.amplifiers.value.ValueCreatorHelper; import eu.stamp_project.dspot.common.miscellaneous.CloneHelper; import eu.stamp_project.dspot.amplifier.amplifiers.utils.RandomHelper; -import spoon.reflect.code.CtBlock; -import spoon.reflect.code.CtBodyHolder; -import spoon.reflect.code.CtExpression; -import spoon.reflect.code.CtInvocation; -import spoon.reflect.code.CtLocalVariable; -import spoon.reflect.code.CtStatement; -import spoon.reflect.code.CtStatementList; +import eu.stamp_project.dspot.common.miscellaneous.DSpotUtils; +import spoon.reflect.code.*; import spoon.reflect.declaration.CtElement; import spoon.reflect.declaration.CtMethod; import spoon.reflect.declaration.CtParameter; @@ -69,7 +64,8 @@ public static CtMethod addInvocation(CtMethod testMethod, CtMethod methodToInvokeToAdd, CtExpression target, CtStatement position, - String suffix) { + String suffix, + String comment) { final Factory factory = testMethod.getFactory(); CtMethod methodClone = CloneHelper.cloneTestMethodForAmp(testMethod, suffix); @@ -99,6 +95,7 @@ public static CtMethod addInvocation(CtMethod testMethod, localVariable = ValueCreator.createRandomLocalVar(parameter.getType(), parameter.getSimpleName()); } body.insertBegin(localVariable); + DSpotUtils.addComment(localVariable, comment, CtComment.CommentType.INLINE); arguments.add(factory.createVariableRead(localVariable.getReference(), false)); } catch (Exception e) { throw new RuntimeException(e); @@ -106,7 +103,7 @@ public static CtMethod addInvocation(CtMethod testMethod, }); CtExpression targetClone = target.clone(); CtInvocation newInvocation = factory.Code().createInvocation(targetClone, methodToInvokeToAdd.getReference(), arguments); - //DSpotUtils.addComment(newInvocation, "MethodGenerator", CtComment.CommentType.INLINE); + DSpotUtils.addComment(newInvocation, comment, CtComment.CommentType.INLINE); body.insertEnd(newInvocation); return methodClone; } diff --git a/dspot/src/main/java/eu/stamp_project/dspot/amplifier/amplifiers/FastLiteralAmplifier.java b/dspot/src/main/java/eu/stamp_project/dspot/amplifier/amplifiers/FastLiteralAmplifier.java index a6c3c2868..0bc83db7c 100644 --- a/dspot/src/main/java/eu/stamp_project/dspot/amplifier/amplifiers/FastLiteralAmplifier.java +++ b/dspot/src/main/java/eu/stamp_project/dspot/amplifier/amplifiers/FastLiteralAmplifier.java @@ -86,6 +86,7 @@ private CtMethod createNumberMutant(CtMethod method, int original_lit_inde //get the lit_indexth literal of the cloned method CtLiteral newLiteral = Query.getElements(cloned_method.getBody(), new LiteralToBeMutedFilter()) .get(original_lit_index); + Object oldValue = newLiteral.getValue(); CtElement toReplace = newLiteral; @@ -110,7 +111,7 @@ private CtMethod createNumberMutant(CtMethod method, int original_lit_inde } toReplace.replace(newLiteral); Counter.updateInputOf(cloned_method, 1); - DSpotUtils.addComment(toReplace, "FastLiteralAmplifier on numbers", CtComment.CommentType.INLINE); + addComment(toReplace, "number", oldValue, newValue); return cloned_method; } @@ -132,8 +133,9 @@ private CtMethod createStringMutant(CtMethod method, int original_lit_inde Counter.updateInputOf(cloned_method, 1); CtLiteral toReplace = Query.getElements(cloned_method.getBody(), new LiteralToBeMutedFilter()) .get(original_lit_index); + Object oldValue = toReplace.getValue(); toReplace.replace(cloned_method.getFactory().Code().createLiteral(newValue)); - DSpotUtils.addComment(toReplace, "FastLiteralAmplifier on strings", CtComment.CommentType.INLINE); + addComment(toReplace, "string", oldValue, newValue); return cloned_method; } @@ -148,8 +150,9 @@ private CtMethod createCharacterMutant(CtMethod method, int original_lit_inde Counter.updateInputOf(cloned_method, 1); CtLiteral toReplace = Query.getElements(cloned_method.getBody(), new LiteralToBeMutedFilter()) .get(original_lit_index); + Object oldValue = toReplace.getValue(); toReplace.replace(cloned_method.getFactory().Code().createLiteral(newValue)); - DSpotUtils.addComment(toReplace, "FastLiteralAmplifier on strings", CtComment.CommentType.INLINE); + addComment(toReplace, "char", oldValue, newValue); return cloned_method; } @@ -223,7 +226,7 @@ public boolean matches(CtLiteral element) { newValue.setValue(!value); newValue.setTypeCasts(booleanLiteral.getTypeCasts()); Counter.updateInputOf(cloned_method, 1); - DSpotUtils.addComment(newValue, "FastLiteralAmplifier on boolean", CtComment.CommentType.INLINE); + addComment(newValue, "boolean", value, !value); return cloned_method; } @@ -243,4 +246,8 @@ private Set getLiterals(CtType type) { } return literalByClass.get(type); } + + private void addComment(CtElement element, String kind, Object oldValue, Object newValue) { + DSpotUtils.addComment(element, "FastLiteralAmplifier: change " + kind + " from '" + oldValue + "' to '" + newValue + "'", CtComment.CommentType.INLINE); + } } diff --git a/dspot/src/main/java/eu/stamp_project/dspot/amplifier/amplifiers/MethodAdderOnExistingObjectsAmplifier.java b/dspot/src/main/java/eu/stamp_project/dspot/amplifier/amplifiers/MethodAdderOnExistingObjectsAmplifier.java index b26d26cd5..9c5ee08e2 100644 --- a/dspot/src/main/java/eu/stamp_project/dspot/amplifier/amplifiers/MethodAdderOnExistingObjectsAmplifier.java +++ b/dspot/src/main/java/eu/stamp_project/dspot/amplifier/amplifiers/MethodAdderOnExistingObjectsAmplifier.java @@ -40,7 +40,8 @@ public Stream> amplify(CtMethod testMethod, int iteration) { methodToBeAdd, AmplifierHelper.createLocalVarRef(existingObject), existingObject, - "_mg") + "_mg", + "MethodAdderOnExistingObjectsAmplifier: added method on existing object") ).map(amplifiedTestMethod -> { Counter.updateInputOf(amplifiedTestMethod, 1); return amplifiedTestMethod; diff --git a/dspot/src/main/java/eu/stamp_project/dspot/amplifier/amplifiers/MethodDuplicationAmplifier.java b/dspot/src/main/java/eu/stamp_project/dspot/amplifier/amplifiers/MethodDuplicationAmplifier.java index 3776a7fe6..156a59489 100644 --- a/dspot/src/main/java/eu/stamp_project/dspot/amplifier/amplifiers/MethodDuplicationAmplifier.java +++ b/dspot/src/main/java/eu/stamp_project/dspot/amplifier/amplifiers/MethodDuplicationAmplifier.java @@ -1,14 +1,12 @@ package eu.stamp_project.dspot.amplifier.amplifiers; +import eu.stamp_project.dspot.common.miscellaneous.DSpotUtils; import eu.stamp_project.dspot.common.test_framework.TestFramework; import eu.stamp_project.dspot.amplifier.amplifiers.utils.AmplificationChecker; import eu.stamp_project.dspot.common.miscellaneous.AmplificationHelper; import eu.stamp_project.dspot.common.miscellaneous.CloneHelper; import eu.stamp_project.dspot.common.miscellaneous.Counter; -import spoon.reflect.code.CtBlock; -import spoon.reflect.code.CtExpression; -import spoon.reflect.code.CtInvocation; -import spoon.reflect.code.CtStatement; +import spoon.reflect.code.*; import spoon.reflect.declaration.CtMethod; import spoon.reflect.declaration.CtType; import spoon.reflect.visitor.filter.TypeFilter; @@ -53,6 +51,7 @@ private CtMethod apply(CtMethod method, CtInvocation invocation) { removeAllTypeCast(invocationToBeInserted); final CtStatement insertionPoint = this.getRightInsertionPoint(invocation); insertionPoint.insertBefore(invocationToBeInserted); + DSpotUtils.addComment(invocationToBeInserted, "MethodDuplicationAmplifier: duplicated method call", CtComment.CommentType.INLINE); final CtMethod clone = CloneHelper.cloneTestMethodForAmp(method, "_add"); AmplifierHelper.getParent(invocationToBeInserted).getStatements().remove(invocationToBeInserted); Counter.updateInputOf(clone, 1); diff --git a/dspot/src/main/java/eu/stamp_project/dspot/amplifier/amplifiers/ReturnValueAmplifier.java b/dspot/src/main/java/eu/stamp_project/dspot/amplifier/amplifiers/ReturnValueAmplifier.java index 4de519ba3..1bbb3aaf5 100644 --- a/dspot/src/main/java/eu/stamp_project/dspot/amplifier/amplifiers/ReturnValueAmplifier.java +++ b/dspot/src/main/java/eu/stamp_project/dspot/amplifier/amplifiers/ReturnValueAmplifier.java @@ -55,7 +55,7 @@ public Stream> amplify(CtMethod testMethod, int iteration) { ); DSpotUtils.addComment(localVar, "StatementAdd: generate variable from return value", CtComment.CommentType.INLINE); ampMethods.addAll(methodsWithTargetType.stream() - .map(addMth -> AmplifierHelper.addInvocation(methodClone, addMth, target, localVar, "_rv")) + .map(addMth -> AmplifierHelper.addInvocation(methodClone, addMth, target, localVar, "_rv", "ReturnValueAmplifier: add method call")) .collect(Collectors.toList())); Counter.updateInputOf(methodClone, 1); } diff --git a/dspot/src/main/java/eu/stamp_project/dspot/assertiongenerator/assertiongenerator/MethodReconstructor.java b/dspot/src/main/java/eu/stamp_project/dspot/assertiongenerator/assertiongenerator/MethodReconstructor.java index 370b8a3d5..ee16e82eb 100644 --- a/dspot/src/main/java/eu/stamp_project/dspot/assertiongenerator/assertiongenerator/MethodReconstructor.java +++ b/dspot/src/main/java/eu/stamp_project/dspot/assertiongenerator/assertiongenerator/MethodReconstructor.java @@ -23,10 +23,8 @@ import spoon.reflect.factory.Factory; import spoon.reflect.visitor.Query; import spoon.reflect.visitor.filter.TypeFilter; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.Set; + +import java.util.*; import java.util.stream.Collectors; /** @@ -120,23 +118,23 @@ private CtMethod buildTestWithAssert(CtMethod test, Map an assertion identical to the last assertion put into the test method */ if (assertStatements.stream() .map(Object::toString) - .map("// AssertionGenerator add assertion\n"::concat) + .map("// AssertionGenerator: add assertion\n"::concat) .anyMatch(testWithAssert.getBody().getLastStatement().toString()::equals)) { continue; } - goThroughAssertionStatements(assertStatements,id,statements,numberOfAddedAssertion); + numberOfAddedAssertion = goThroughAssertionStatements(assertStatements,id,statements,numberOfAddedAssertion); } Counter.updateAssertionOf(testWithAssert, numberOfAddedAssertion); return decideReturn(testWithAssert,test); } - private void goThroughAssertionStatements(List assertStatements,String id, - List statements,Integer numberOfAddedAssertion){ + private int goThroughAssertionStatements(List assertStatements,String id, + List statements, int numberOfAddedAssertion){ int line = Integer.parseInt(id.split("__")[1]); CtStatement lastStmt = null; for (CtStatement assertStatement : assertStatements) { DSpotUtils.addComment(assertStatement, - "AssertionGenerator add assertion", + "AssertionGenerator: add assertion", CtComment.CommentType.INLINE); try { CtStatement statementToBeAsserted = statements.get(line); @@ -153,6 +151,7 @@ private void goThroughAssertionStatements(List assertStatements,Str throw new RuntimeException(e); } } + return numberOfAddedAssertion; } private void decideInvocationReplacement(CtStatement statementToBeAsserted,String id,CtStatement assertStatement, @@ -184,8 +183,15 @@ private void replaceInvocation(CtStatement statementToBeAsserted,String id,CtSta // put the new local variable into the assertion and the assertion into the test method statementToBeAsserted.replace(localVariable); + // move comments from invocation to new variable statement + List invocationComments = new ArrayList<>(statementToBeAsserted.getComments()); + invocationComments.forEach(comment -> { + invocationToBeReplaced.removeComment(comment); + localVariable.addComment(comment); + }); + DSpotUtils.addComment(localVariable, - "AssertionGenerator create local variable with return value of invocation", + "AssertionGenerator: create local variable with return value of invocation", CtComment.CommentType.INLINE); localVariable.setParent(statementToBeAsserted.getParent()); addAtCorrectPlace(id, localVariable, assertStatement, statementToBeAsserted); diff --git a/dspot/src/main/java/eu/stamp_project/dspot/common/miscellaneous/Counter.java b/dspot/src/main/java/eu/stamp_project/dspot/common/miscellaneous/Counter.java index ade7e60bf..e163a85fb 100644 --- a/dspot/src/main/java/eu/stamp_project/dspot/common/miscellaneous/Counter.java +++ b/dspot/src/main/java/eu/stamp_project/dspot/common/miscellaneous/Counter.java @@ -64,8 +64,10 @@ public static Integer getAssertionOfSinceOrigin(CtMethod method) { CtMethod parent; int countAssertion = getAssertionOf(currentMethod); while ((parent = AmplificationHelper.getAmpTestParent(currentMethod)) != null) { + if (!parent.getSimpleName().equals(currentMethod.getSimpleName())) { + countAssertion += getAssertionOf(parent); + } currentMethod = parent; - countAssertion += getAssertionOf(currentMethod); } return countAssertion; } @@ -73,12 +75,13 @@ public static Integer getAssertionOfSinceOrigin(CtMethod method) { public static Integer getInputOfSinceOrigin(CtMethod method) { CtMethod currentMethod = method; CtMethod parent; - int countAssertion = 0; + int countAssertion = getInputOf(currentMethod); while ((parent = AmplificationHelper.getAmpTestParent(currentMethod)) != null) { - countAssertion += getInputOf(currentMethod); + if (!parent.getSimpleName().equals(currentMethod.getSimpleName())) { + countAssertion += getInputOf(parent); + } currentMethod = parent; } - countAssertion += getInputOf(currentMethod); return countAssertion; } diff --git a/dspot/src/main/java/eu/stamp_project/dspot/common/miscellaneous/DSpotUtils.java b/dspot/src/main/java/eu/stamp_project/dspot/common/miscellaneous/DSpotUtils.java index 9ef3058d2..661c958a1 100644 --- a/dspot/src/main/java/eu/stamp_project/dspot/common/miscellaneous/DSpotUtils.java +++ b/dspot/src/main/java/eu/stamp_project/dspot/common/miscellaneous/DSpotUtils.java @@ -11,8 +11,10 @@ import spoon.Launcher; import spoon.compiler.Environment; import spoon.reflect.code.CtComment; +import spoon.reflect.code.CtLiteral; import spoon.reflect.declaration.*; import spoon.reflect.reference.CtTypeReference; +import spoon.reflect.visitor.filter.LineFilter; import spoon.support.JavaOutputProcessor; import java.io.*; @@ -175,6 +177,17 @@ private static CtClass getExistingClass(CtType type, String pathname) { } public static void addComment(CtElement element, String content, CtComment.CommentType type) { + if (element instanceof CtLiteral) { + try { + CtElement parentLine = element.getParent(new LineFilter()); + if (parentLine != null) { + element = parentLine; + } + } catch (ParentNotInitializedException ignored) { + + } + } + CtComment comment = element.getFactory().createComment(content, type); if (!element.getComments().contains(comment)) { element.addComment(comment); diff --git a/dspot/src/main/java/eu/stamp_project/dspot/common/report/output/Output.java b/dspot/src/main/java/eu/stamp_project/dspot/common/report/output/Output.java index 18a6afc5b..25b8d9c5f 100644 --- a/dspot/src/main/java/eu/stamp_project/dspot/common/report/output/Output.java +++ b/dspot/src/main/java/eu/stamp_project/dspot/common/report/output/Output.java @@ -91,11 +91,10 @@ private void outputSeedTestClassWithSuccessTestMethods(CtType testClassToBeAm .distinct() .forEach(clone::addMethod); final File outputDirectory = new File(this.outputPathDirectory + "/original/"); - DSpotState.GLOBAL_REPORT.addNumberAmplifiedTestMethodsToTotal(amplifiedTestMethods.size()); DSpotState.GLOBAL_REPORT.addPrintedTestClasses( - String.format("Print %s with %d amplified test cases in %s", + String.format("Print %s with %d original test cases in %s", clone.getQualifiedName() + ".java", - amplifiedTestMethods.size(), + clone.getMethods().size(), this.outputPathDirectory + "/original/" ) ); diff --git a/dspot/src/main/java/eu/stamp_project/dspot/common/report/output/selector/coverage/json/TestCaseJSON.java b/dspot/src/main/java/eu/stamp_project/dspot/common/report/output/selector/coverage/json/TestCaseJSON.java index 281e691b0..63248028d 100644 --- a/dspot/src/main/java/eu/stamp_project/dspot/common/report/output/selector/coverage/json/TestCaseJSON.java +++ b/dspot/src/main/java/eu/stamp_project/dspot/common/report/output/selector/coverage/json/TestCaseJSON.java @@ -20,4 +20,24 @@ public TestCaseJSON(String name, int nbAssertionAdded, int nbInputAdded, int ins this.instructionCovered = instructionCovered; this.instructionTotal = instructionTotal; } + + public String getName() { + return name; + } + + public int getNbAssertionAdded() { + return nbAssertionAdded; + } + + public int getNbInputAdded() { + return nbInputAdded; + } + + public int getInstructionCovered() { + return instructionCovered; + } + + public int getInstructionTotal() { + return instructionTotal; + } } diff --git a/dspot/src/main/java/eu/stamp_project/dspot/common/report/output/selector/coverage/json/TestClassJSON.java b/dspot/src/main/java/eu/stamp_project/dspot/common/report/output/selector/coverage/json/TestClassJSON.java index f87cf0bcf..d2e65516c 100644 --- a/dspot/src/main/java/eu/stamp_project/dspot/common/report/output/selector/coverage/json/TestClassJSON.java +++ b/dspot/src/main/java/eu/stamp_project/dspot/common/report/output/selector/coverage/json/TestClassJSON.java @@ -50,4 +50,40 @@ public String toString() { String jsonString = new JSONObject().put(this.name,subJson).toString(); return jsonString; } + + public String getName() { + return name; + } + + public long getNbOriginalTestCases() { + return nbOriginalTestCases; + } + + public long getInitialInstructionCovered() { + return initialInstructionCovered; + } + + public long getInitialInstructionTotal() { + return initialInstructionTotal; + } + + public double getPercentageinitialInstructionCovered() { + return percentageinitialInstructionCovered; + } + + public long getAmplifiedInstructionCovered() { + return amplifiedInstructionCovered; + } + + public long getAmplifiedInstructionTotal() { + return amplifiedInstructionTotal; + } + + public double getPercentageamplifiedInstructionCovered() { + return percentageamplifiedInstructionCovered; + } + + public List getTestCases() { + return testCases; + } } diff --git a/dspot/src/main/java/eu/stamp_project/dspot/selector/JacocoCoverageSelector.java b/dspot/src/main/java/eu/stamp_project/dspot/selector/JacocoCoverageSelector.java index 9e617825b..19eaa8ac1 100644 --- a/dspot/src/main/java/eu/stamp_project/dspot/selector/JacocoCoverageSelector.java +++ b/dspot/src/main/java/eu/stamp_project/dspot/selector/JacocoCoverageSelector.java @@ -242,12 +242,12 @@ private TestClassJSON jsonReport(Coverage coverageResults) { ); } this.selectedAmplifiedTest.forEach(ctMethod -> - new TestCaseJSON(ctMethod.getSimpleName(), - Counter.getInputOfSinceOrigin(ctMethod), + testClassJSON.addTestCase(new TestCaseJSON(ctMethod.getSimpleName(), Counter.getAssertionOfSinceOrigin(ctMethod), + Counter.getInputOfSinceOrigin(ctMethod), this.selectedToBeAmplifiedCoverageResultsMap.get(ctMethod.getSimpleName()).getInstructionsCovered(), this.selectedToBeAmplifiedCoverageResultsMap.get(ctMethod.getSimpleName()).getInstructionsTotal() - ) + )) ); // TODO // CollectorConfig.getInstance().getInformationCollector().reportSelectorInformation(testClassJSON.toString()); diff --git a/dspot/src/test/java/eu/stamp_project/dspot/amplifier/TestMethodCallAdder.java b/dspot/src/test/java/eu/stamp_project/dspot/amplifier/TestMethodCallAdder.java index a85c91731..c728d0de4 100644 --- a/dspot/src/test/java/eu/stamp_project/dspot/amplifier/TestMethodCallAdder.java +++ b/dspot/src/test/java/eu/stamp_project/dspot/amplifier/TestMethodCallAdder.java @@ -59,8 +59,8 @@ public void testMethodCallAddAll() throws Exception { 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.toString(), + CtStatement expectedStatement =originalMethod.getBody().getStatements().get(i + 1);//+1 to skip the construction statement. + assertEquals( "// MethodDuplicationAmplifier: duplicated method call\n" + expectedStatement.toString(), amplifiedMethod.getBody().getStatements().get(i + 1).toString()); assertEquals(expectedStatement.toString(), amplifiedMethod.getBody().getStatements().get(i + 2).toString());