diff --git a/.github/install_examples.sh b/.github/install_examples.sh index 24a2c4d2..e55b5d9e 100755 --- a/.github/install_examples.sh +++ b/.github/install_examples.sh @@ -9,6 +9,7 @@ mvn clean test -DskipTests -Dmaven.compiler.source=$SRC_VERSION -Dmaven.compiler mvn clean test -DskipTests -Dmaven.compiler.source=$SRC_VERSION -Dmaven.compiler.target=$SRC_VERSION -B -f examples/exampleFL5JUnit3/FLtest1/ mvn clean test -DskipTests -Dmaven.compiler.source=$SRC_VERSION -Dmaven.compiler.target=$SRC_VERSION -B -f examples/exampleFL6Mixed/FLtest1/ mvn clean test -DskipTests -Dmaven.compiler.source=$SRC_VERSION -Dmaven.compiler.target=$SRC_VERSION -B -f examples/exampleFL7SameNamedMethods/FLtest1/ +mvn clean test -DskipTests -Dmaven.compiler.source=$SRC_VERSION -Dmaven.compiler.target=$SRC_VERSION -B -f examples/exampleFL10/FLtest1/ # Copy compiled classes to non-maven mirror projects rm -r examples/exampleFL8NotMaven/bin/ diff --git a/examples/exampleFL10/FLtest1/pom.xml b/examples/exampleFL10/FLtest1/pom.xml new file mode 100644 index 00000000..bb81de64 --- /dev/null +++ b/examples/exampleFL10/FLtest1/pom.xml @@ -0,0 +1,27 @@ + + 4.0.0 + + fr.spoonlabs + FLtest1 + 0.0.1-SNAPSHOT + jar + + FLtest1 + http://maven.apache.org + + + UTF-8 + 1.8 + 1.8 + + + + + junit + junit + 4.12 + test + + + diff --git a/examples/exampleFL10/FLtest1/src/main/java/fr/spoonlabs/FLtest1/Calculator.java b/examples/exampleFL10/FLtest1/src/main/java/fr/spoonlabs/FLtest1/Calculator.java new file mode 100644 index 00000000..f163cdb6 --- /dev/null +++ b/examples/exampleFL10/FLtest1/src/main/java/fr/spoonlabs/FLtest1/Calculator.java @@ -0,0 +1,26 @@ +package fr.spoonlabs.FLtest1; + +public class Calculator { + + public Calculator() { + } + + public int calculate(String op, int op1, int op2) { + + while(true) { + if (op.equals("+")) { + return op1 + op2; + } else if (op.equals("-")) { + return op1 - op2; + } else if (op.equals("*")) { + return op1 / op2;//buggy + } else if (op.equals("/")) { + return op1 / op2; + } else if (op.equals("%")) { + return op1 % op2; + } + throw new UnsupportedOperationException(op); + } + + } +} diff --git a/examples/exampleFL10/FLtest1/src/test/java/fr/spoonlabs/FLtest1/CalculatorTest.java b/examples/exampleFL10/FLtest1/src/test/java/fr/spoonlabs/FLtest1/CalculatorTest.java new file mode 100644 index 00000000..3cb1ed5d --- /dev/null +++ b/examples/exampleFL10/FLtest1/src/test/java/fr/spoonlabs/FLtest1/CalculatorTest.java @@ -0,0 +1,39 @@ +package fr.spoonlabs.FLtest1; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +public class CalculatorTest { + + Calculator c = new Calculator(); + + @Test + public void testSum() { + + assertEquals(4, c.calculate("+", 3, 1)); + + } + + @Test + public void testSubs() { + + assertEquals(2, c.calculate("-", 3, 1)); + + } + + @Test + public void testMul() { + + assertEquals(8, c.calculate("*", 4, 2)); + + } + + @Test + public void testDiv() { + + assertEquals(2, c.calculate("/", 12, 6)); + + } + +} diff --git a/src/test/java/fr/spoonlabs/flacoco/api/FlacocoTest.java b/src/test/java/fr/spoonlabs/flacoco/api/FlacocoTest.java index 0400af6f..eb7b51ff 100644 --- a/src/test/java/fr/spoonlabs/flacoco/api/FlacocoTest.java +++ b/src/test/java/fr/spoonlabs/flacoco/api/FlacocoTest.java @@ -913,4 +913,37 @@ public void testExampleFL9SpectrumBasedOchiaiSpoonMode() { } } + @Test + public void testExampleFL10SpectrumBasedOchiaiDefaultMode() { + // Setup config + FlacocoConfig config = FlacocoConfig.getInstance(); + config.setProjectPath(new File("./examples/exampleFL10/FLtest1").getAbsolutePath()); + config.setFamily(FlacocoConfig.FaultLocalizationFamily.SPECTRUM_BASED); + config.setSpectrumFormula(SpectrumFormula.OCHIAI); + + // Run Flacoco + Flacoco flacoco = new Flacoco(); + + // Run default mode + Map susp = flacoco.runDefault(); + + for (String line : susp.keySet()) { + System.out.println("" + line + " " + susp.get(line)); + } + + assertEquals(5, susp.size()); + + // Line executed only by the failing + assertEquals(1.0, susp.get("fr/spoonlabs/FLtest1/Calculator@-@16").getScore(), 0); + + // Line executed by a mix of failing and passing + assertEquals(0.70, susp.get("fr/spoonlabs/FLtest1/Calculator@-@15").getScore(), 0.01); + assertEquals(0.57, susp.get("fr/spoonlabs/FLtest1/Calculator@-@13").getScore(), 0.01); + + // Lines executed by all test + // the first one is the while(true) + assertEquals(0.5, susp.get("fr/spoonlabs/FLtest1/Calculator@-@10").getScore(), 0); + assertEquals(0.5, susp.get("fr/spoonlabs/FLtest1/Calculator@-@11").getScore(), 0); + } + } \ No newline at end of file diff --git a/src/test/java/fr/spoonlabs/flacoco/core/coverage/CoverageRunnerTest.java b/src/test/java/fr/spoonlabs/flacoco/core/coverage/CoverageRunnerTest.java index c5ae69f2..a925db11 100644 --- a/src/test/java/fr/spoonlabs/flacoco/core/coverage/CoverageRunnerTest.java +++ b/src/test/java/fr/spoonlabs/flacoco/core/coverage/CoverageRunnerTest.java @@ -959,4 +959,102 @@ public void testExampleFL9() { assertNull(modCond); } + @Test + public void testExampleFL10() { + // Setup config + FlacocoConfig config = FlacocoConfig.getInstance(); + config.setProjectPath(new File("./examples/exampleFL10/FLtest1").getAbsolutePath()); + + CoverageRunner detector = new CoverageRunner(); + + // Find the tests + TestDetector testDetector = new TestDetector(); + List tests = testDetector.getTests(); + + assertTrue(tests.size() > 0); + + CoverageMatrix matrix = detector.getCoverageMatrix(tests); + + // verify nr of test + assertEquals(4, matrix.getTests().size()); + assertEquals(1, matrix.getFailingTestCases().size()); + + // 9 executed lines + assertEquals(9, matrix.getResultExecution().keySet().size()); + + // This line is the first if, so it's covered by all tests + // this is the while(true) + Set firstLineExecuted = matrix.getResultExecution().get("fr/spoonlabs/FLtest1/Calculator@-@10"); + + assertEquals(4, firstLineExecuted.size()); + + Set executedTestKeys = firstLineExecuted.stream() + .map(TestMethod::getFullyQualifiedMethodName).collect(Collectors.toSet()); + + assertTrue(executedTestKeys.contains("fr.spoonlabs.FLtest1.CalculatorTest#testSubs")); + assertTrue(executedTestKeys.contains("fr.spoonlabs.FLtest1.CalculatorTest#testSum")); + + assertTrue(executedTestKeys.contains("fr.spoonlabs.FLtest1.CalculatorTest#testDiv")); + assertTrue(executedTestKeys.contains("fr.spoonlabs.FLtest1.CalculatorTest#testMul")); + + // This one is only executed by the sum + Set returnSum = matrix.getResultExecution().get("fr/spoonlabs/FLtest1/Calculator@-@12"); + + executedTestKeys = returnSum.stream() + .map(TestMethod::getFullyQualifiedMethodName).collect(Collectors.toSet()); + + assertEquals(1, returnSum.size()); + + assertTrue(executedTestKeys.contains("fr.spoonlabs.FLtest1.CalculatorTest#testSum")); + + // This line is the second if, so it's covered by all tests, except the first one + Set secondIfExecuted = matrix.getResultExecution().get("fr/spoonlabs/FLtest1/Calculator@-@13"); + assertEquals(3, secondIfExecuted.size()); + + executedTestKeys = secondIfExecuted.stream() + .map(TestMethod::getFullyQualifiedMethodName).collect(Collectors.toSet()); + + // The first one returns before + assertFalse(executedTestKeys.contains("fr.spoonlabs.FLtest1.CalculatorTest#testSum")); + + assertTrue(executedTestKeys.contains("fr.spoonlabs.FLtest1.CalculatorTest#testSubs")); + assertTrue(executedTestKeys.contains("fr.spoonlabs.FLtest1.CalculatorTest#testDiv")); + assertTrue(executedTestKeys.contains("fr.spoonlabs.FLtest1.CalculatorTest#testMul")); + + Set oneMultCond = matrix.getResultExecution().get("fr/spoonlabs/FLtest1/Calculator@-@15"); + assertEquals(2, oneMultCond.size()); + executedTestKeys = oneMultCond.stream() + .map(TestMethod::getFullyQualifiedMethodName).collect(Collectors.toSet()); + assertFalse(executedTestKeys.contains("fr.spoonlabs.FLtest1.CalculatorTest#testSum")); + assertFalse(executedTestKeys.contains("fr.spoonlabs.FLtest1.CalculatorTest#testSubs")); + assertTrue(executedTestKeys.contains("fr.spoonlabs.FLtest1.CalculatorTest#testDiv")); + assertTrue(executedTestKeys.contains("fr.spoonlabs.FLtest1.CalculatorTest#testMul")); + + // This line is inside one if, so it's executed only one + Set oneReturnLineExecuted = matrix.getResultExecution().get("fr/spoonlabs/FLtest1/Calculator@-@16"); + assertEquals(1, oneReturnLineExecuted.size()); + + executedTestKeys = oneReturnLineExecuted.stream() + .map(TestMethod::getFullyQualifiedMethodName).collect(Collectors.toSet()); + + assertFalse(executedTestKeys.contains("fr.spoonlabs.FLtest1.CalculatorTest#testSum")); + assertTrue(executedTestKeys.contains("fr.spoonlabs.FLtest1.CalculatorTest#testMul")); + assertFalse(executedTestKeys.contains("fr.spoonlabs.FLtest1.CalculatorTest#testSubs")); + assertFalse(executedTestKeys.contains("fr.spoonlabs.FLtest1.CalculatorTest#testDiv")); + + Set divisionCond = matrix.getResultExecution().get("fr/spoonlabs/FLtest1/Calculator@-@17"); + assertEquals(1, divisionCond.size()); + executedTestKeys = divisionCond.stream() + .map(TestMethod::getFullyQualifiedMethodName).collect(Collectors.toSet()); + + assertFalse(executedTestKeys.contains("fr.spoonlabs.FLtest1.CalculatorTest#testSum")); + assertFalse(executedTestKeys.contains("fr.spoonlabs.FLtest1.CalculatorTest#testMul")); + assertFalse(executedTestKeys.contains("fr.spoonlabs.FLtest1.CalculatorTest#testSubs")); + assertTrue(executedTestKeys.contains("fr.spoonlabs.FLtest1.CalculatorTest#testDiv")); + + // Any test executes that + Set modCond = matrix.getResultExecution().get("fr/spoonlabs/FLtest1/Calculator@-@19"); + assertNull(modCond); + } + } \ No newline at end of file