diff --git a/pitest-ant/pom.xml b/pitest-ant/pom.xml
index 310c02f6f..077759c07 100644
--- a/pitest-ant/pom.xml
+++ b/pitest-ant/pom.xml
@@ -18,6 +18,12 @@
${project.version}
+
+ org.pitest
+ pitest-aggregator
+ ${project.version}
+
+
org.apache.ant
ant
diff --git a/pitest-ant/src/main/java/org/pitest/ant/aggregator/ReportAggregatorFacade.java b/pitest-ant/src/main/java/org/pitest/ant/aggregator/ReportAggregatorFacade.java
new file mode 100644
index 000000000..7336fd549
--- /dev/null
+++ b/pitest-ant/src/main/java/org/pitest/ant/aggregator/ReportAggregatorFacade.java
@@ -0,0 +1,20 @@
+package org.pitest.ant.aggregator;
+
+
+import org.apache.tools.ant.types.Path;
+import org.pitest.aggregate.ReportAggregationException;
+
+import java.util.List;
+
+
+public interface ReportAggregatorFacade {
+ void aggregateReport() throws ReportAggregationException;
+
+ void setLineCoverageFiles(List lineCoverageFiles);
+
+ void setMutationFiles(List mutationFiles);
+
+ void setSourceCodeDirs(List sourceCodeDirs);
+
+ void setCompiledCodeDirs(List compiledCodeDirs);
+}
diff --git a/pitest-ant/src/main/java/org/pitest/ant/aggregator/ReportAggregatorFacadeImpl.java b/pitest-ant/src/main/java/org/pitest/ant/aggregator/ReportAggregatorFacadeImpl.java
new file mode 100644
index 000000000..9c506668f
--- /dev/null
+++ b/pitest-ant/src/main/java/org/pitest/ant/aggregator/ReportAggregatorFacadeImpl.java
@@ -0,0 +1,63 @@
+package org.pitest.ant.aggregator;
+
+import org.apache.tools.ant.types.Path;
+import org.pitest.aggregate.ReportAggregationException;
+import org.pitest.aggregate.ReportAggregator;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.function.Consumer;
+
+
+public class ReportAggregatorFacadeImpl implements ReportAggregatorFacade {
+ private List lineCoverageFiles = new ArrayList<>();
+ private List mutationFiles = new ArrayList<>();
+ private List sourceCodeDirs = new ArrayList<>();
+ private List compiledCodeDirs = new ArrayList<>();
+
+ @Override
+ public void aggregateReport() throws ReportAggregationException {
+ aggregateReport(ReportAggregator.builder()).aggregateReport();
+ }
+
+ ReportAggregator aggregateReport(ReportAggregator.Builder builder) {
+ setParameter(lineCoverageFiles, builder::addLineCoverageFile);
+ setParameter(mutationFiles, builder::addMutationResultsFile);
+ setParameter(sourceCodeDirs, builder::addSourceCodeDirectory);
+ setParameter(compiledCodeDirs, builder::addCompiledCodeDirectory);
+ return builder.build();
+ }
+
+ private void setParameter(List lineCoverageFiles, Consumer pathConsumer)
+ {
+ lineCoverageFiles
+ .stream()
+ .map(Path::list)
+ .map(Arrays::asList)
+ .flatMap(List::stream)
+ .map(File::new)
+ .forEach(pathConsumer);
+ }
+
+ @Override
+ public void setLineCoverageFiles(List lineCoverageFiles) {
+ this.lineCoverageFiles = lineCoverageFiles;
+ }
+
+ @Override
+ public void setMutationFiles(List mutationFiles) {
+ this.mutationFiles = mutationFiles;
+ }
+
+ @Override
+ public void setSourceCodeDirs(List sourceCodeDirs) {
+ this.sourceCodeDirs = sourceCodeDirs;
+ }
+
+ @Override
+ public void setCompiledCodeDirs(List compiledCodeDirs) {
+ this.compiledCodeDirs = compiledCodeDirs;
+ }
+}
diff --git a/pitest-ant/src/main/java/org/pitest/ant/aggregator/ReportAggregatorTask.java b/pitest-ant/src/main/java/org/pitest/ant/aggregator/ReportAggregatorTask.java
new file mode 100644
index 000000000..dfa3182ca
--- /dev/null
+++ b/pitest-ant/src/main/java/org/pitest/ant/aggregator/ReportAggregatorTask.java
@@ -0,0 +1,52 @@
+package org.pitest.ant.aggregator;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.types.Path;
+import org.pitest.aggregate.ReportAggregationException;
+
+import java.util.ArrayList;
+import java.util.List;
+
+
+public class ReportAggregatorTask extends Task {
+
+ private List lineCoverageFilePaths = new ArrayList<>();
+ private List mutationFiles = new ArrayList<>();
+ private List sourceCodeDirs = new ArrayList<>();
+ private List compiledCodeDirs = new ArrayList<>();
+
+ @Override
+ public void execute() {
+ try {
+ execute(new ReportAggregatorFacadeImpl());
+ } catch (ReportAggregationException e) {
+ throw new BuildException(e);
+ }
+ }
+
+ void execute(ReportAggregatorFacade aggregator) throws ReportAggregationException {
+
+ aggregator.setLineCoverageFiles(lineCoverageFilePaths);
+ aggregator.setSourceCodeDirs(sourceCodeDirs);
+ aggregator.setMutationFiles(mutationFiles);
+ aggregator.setCompiledCodeDirs(compiledCodeDirs);
+ aggregator.aggregateReport();
+ }
+
+ public void addLineCoverageFiles(Path path) {
+ this.lineCoverageFilePaths.add(path);
+ }
+
+ public void addMutationFiles(Path path) {
+ this.mutationFiles.add(path);
+ }
+
+ public void addSourceCodeDirs(Path path) {
+ this.sourceCodeDirs.add(path);
+ }
+
+ public void addCompiledCodeDirs(Path path) {
+ this.compiledCodeDirs.add(path);
+ }
+}
diff --git a/pitest-ant/src/test/java/org/pitest/ant/aggregator/ReportAggregatorFacadeTest.java b/pitest-ant/src/test/java/org/pitest/ant/aggregator/ReportAggregatorFacadeTest.java
new file mode 100644
index 000000000..640ed5d04
--- /dev/null
+++ b/pitest-ant/src/test/java/org/pitest/ant/aggregator/ReportAggregatorFacadeTest.java
@@ -0,0 +1,89 @@
+package org.pitest.ant.aggregator;
+
+import org.apache.tools.ant.types.Path;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.runners.MockitoJUnitRunner;
+import org.pitest.aggregate.ReportAggregator;
+
+import java.io.File;
+import java.util.Collections;
+
+import static org.mockito.Mockito.*;
+
+
+@RunWith(MockitoJUnitRunner.class)
+public class ReportAggregatorFacadeTest
+{
+ private static final String MOCK_LINE_COVERAGE_FILE_NAME = "fakeFileCoverageFile";
+ private static final String MOCK_LINE_MUTATION_FILE_NAME = "fakeMutationFile";
+ private static final String MOCK_LINE_SOURCE_CODE_DIR_NAME = "fakeSourceDir";
+ private static final String MOCK_LINE_COMPILED_CODE_DIR_NAME = "fakeSourceDir";
+
+ private final File mockLineCoverageFile = new File(MOCK_LINE_COVERAGE_FILE_NAME);
+ private final File mockMutationFile = new File(MOCK_LINE_MUTATION_FILE_NAME);
+ private final File mockSourceCodeDir = new File(MOCK_LINE_SOURCE_CODE_DIR_NAME);
+ private final File mockCompiledCodeDir = new File(MOCK_LINE_COMPILED_CODE_DIR_NAME);
+
+ @Mock
+ private Path mockLineCoverageFilePath;
+ @Mock
+ private Path mockMutationFilePath;
+ @Mock
+ private Path mockSourceCodeDirPath;
+ @Mock
+ private Path mockCompiledCodeDirPath;
+
+ @Mock
+ ReportAggregator.Builder builder;
+
+ private ReportAggregatorFacadeImpl facade = new ReportAggregatorFacadeImpl();
+
+ @Before
+ public void setup() {
+ when(mockLineCoverageFilePath.list()).thenReturn(new String[] { MOCK_LINE_COVERAGE_FILE_NAME });
+ when(mockMutationFilePath.list()).thenReturn(new String[] { MOCK_LINE_MUTATION_FILE_NAME });
+ when(mockSourceCodeDirPath.list()).thenReturn(new String[] { MOCK_LINE_SOURCE_CODE_DIR_NAME });
+ when(mockCompiledCodeDirPath.list()).thenReturn(new String[] { MOCK_LINE_COMPILED_CODE_DIR_NAME});
+ }
+
+ @Test
+ public void aggregateReportBuilder() {
+ facade.aggregateReport(builder);
+ verify(builder).build();
+ }
+
+ @Test
+ public void setLineCoverageFiles() {
+ facade.setLineCoverageFiles(Collections.singletonList(mockLineCoverageFilePath));
+
+ facade.aggregateReport(builder);
+ verify(builder).addLineCoverageFile(mockLineCoverageFile);
+ }
+
+ @Test
+ public void setMutationFiles() {
+ facade.setMutationFiles(Collections.singletonList(mockMutationFilePath));
+
+ facade.aggregateReport(builder);
+ verify(builder).addMutationResultsFile(mockMutationFile);
+ }
+
+ @Test
+ public void setSourceCodeDirs() {
+ facade.setSourceCodeDirs(Collections.singletonList(mockSourceCodeDirPath));
+
+ facade.aggregateReport(builder);
+ verify(builder).addSourceCodeDirectory(mockSourceCodeDir);
+ }
+
+ @Test
+ public void setCompiledCodeDirs() {
+ facade.setCompiledCodeDirs(Collections.singletonList(mockCompiledCodeDirPath));
+
+ facade.aggregateReport(builder);
+ verify(builder).addCompiledCodeDirectory(mockCompiledCodeDir);
+ }
+}
diff --git a/pitest-ant/src/test/java/org/pitest/ant/aggregator/ReportAggregatorTaskTest.java b/pitest-ant/src/test/java/org/pitest/ant/aggregator/ReportAggregatorTaskTest.java
new file mode 100644
index 000000000..08aa7c955
--- /dev/null
+++ b/pitest-ant/src/test/java/org/pitest/ant/aggregator/ReportAggregatorTaskTest.java
@@ -0,0 +1,92 @@
+package org.pitest.ant.aggregator;
+
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.types.Path;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.runners.MockitoJUnitRunner;
+import org.pitest.aggregate.ReportAggregationException;
+
+import static java.util.Collections.singletonList;
+import static org.mockito.Mockito.verify;
+
+
+@RunWith(MockitoJUnitRunner.class)
+public class ReportAggregatorTaskTest {
+
+ private ReportAggregatorTask reportAggregatorTask;
+
+ @Mock
+ private Project project;
+
+ @Mock
+ private ReportAggregatorFacade aggregatorFacade;
+
+ @Rule
+ public ExpectedException exception = ExpectedException.none();
+
+ @Mock
+ public Path lineCoverageFiles;
+ @Mock
+ private Path mutationFiles;
+ @Mock
+ private Path sourceCodeDirs;
+ @Mock
+ private Path compiledCodeDirs;
+
+ @Before
+ public void setUp() {
+ this.reportAggregatorTask = new ReportAggregatorTask();
+ this.reportAggregatorTask.setProject(this.project);
+ }
+
+ @Test
+ public void testExecuteAggregator() throws ReportAggregationException {
+ this.reportAggregatorTask.execute(aggregatorFacade);
+ verify(aggregatorFacade).aggregateReport();
+ }
+
+ @Test
+ public void testAggregatorShouldSupportLineCoverageFiles() throws ReportAggregationException {
+
+ this.reportAggregatorTask.addLineCoverageFiles(lineCoverageFiles);
+
+ this.reportAggregatorTask.execute(aggregatorFacade);
+
+ verify(aggregatorFacade).setLineCoverageFiles(singletonList(lineCoverageFiles));
+ }
+
+ @Test
+ public void testAggregatorShouldSupportMutationFiles() throws ReportAggregationException {
+
+ this.reportAggregatorTask.addMutationFiles(mutationFiles);
+
+ this.reportAggregatorTask.execute(aggregatorFacade);
+
+ verify(aggregatorFacade).setMutationFiles(singletonList(mutationFiles));
+ }
+
+ @Test
+ public void testAggregatorShouldSupportSourceCodeDirs() throws ReportAggregationException {
+
+ this.reportAggregatorTask.addSourceCodeDirs(sourceCodeDirs);
+
+ this.reportAggregatorTask.execute(aggregatorFacade);
+
+ verify(aggregatorFacade).setSourceCodeDirs(singletonList(sourceCodeDirs));
+ }
+
+ @Test
+ public void testAggregatorShouldCompiledCodeDirs() throws ReportAggregationException {
+
+ this.reportAggregatorTask.addCompiledCodeDirs(compiledCodeDirs);
+
+ this.reportAggregatorTask.execute(aggregatorFacade);
+
+ verify(aggregatorFacade).setCompiledCodeDirs(singletonList(compiledCodeDirs));
+ }
+}