From 255ba9d3261877313545afc546a38b7acfce0707 Mon Sep 17 00:00:00 2001 From: Bonajo Date: Sun, 26 Mar 2023 15:13:35 +0200 Subject: [PATCH 1/2] fix: quote killingTest in CSV report The method definition of killingTest can contain commas, in case the method has parameters. These commos break CSV parsing as the are interpreted as starting a new column. By quoting the killingTest in the output, the commas should no longer be parsed as starting a new column. --- .../org/pitest/mutationtest/report/csv/CSVReportListener.java | 2 +- .../pitest/mutationtest/report/csv/CSVReportListenerTest.java | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pitest-entry/src/main/java/org/pitest/mutationtest/report/csv/CSVReportListener.java b/pitest-entry/src/main/java/org/pitest/mutationtest/report/csv/CSVReportListener.java index c8b14bf01..1d1ad730a 100644 --- a/pitest-entry/src/main/java/org/pitest/mutationtest/report/csv/CSVReportListener.java +++ b/pitest-entry/src/main/java/org/pitest/mutationtest/report/csv/CSVReportListener.java @@ -37,7 +37,7 @@ public CSVReportListener(final Writer out) { } private String createKillingTestDesc(final Optional killingTest) { - return killingTest.orElse("none"); + return (killingTest.isPresent()) ? String.format("\"%s\"", killingTest.get()) : "none"; } private String makeCsv(final Object... os) { diff --git a/pitest-entry/src/test/java/org/pitest/mutationtest/report/csv/CSVReportListenerTest.java b/pitest-entry/src/test/java/org/pitest/mutationtest/report/csv/CSVReportListenerTest.java index 7eeae4f8e..fbaab714f 100644 --- a/pitest-entry/src/test/java/org/pitest/mutationtest/report/csv/CSVReportListenerTest.java +++ b/pitest-entry/src/test/java/org/pitest/mutationtest/report/csv/CSVReportListenerTest.java @@ -47,10 +47,10 @@ public void setup() { public void shouldOutputKillingTestWhenOneFound() throws IOException { final MutationResult mr = new MutationResult( MutationTestResultMother.createDetails(), new MutationStatusTestPair(1, - DetectionStatus.KILLED, "foo")); + DetectionStatus.KILLED, "foo(java.lang.String, java.lang.String)")); this.testee.handleMutationResult(MutationTestResultMother .createClassResults(mr)); - final String expected = "file,clazz,mutator,method,42,KILLED,foo" + final String expected = "file,clazz,mutator,method,42,KILLED,\"foo(java.lang.String, java.lang.String)\"" + NEW_LINE; verify(this.out).write(expected); } From 4dbd349afbf500fb7d41bd6f52a401f23333435d Mon Sep 17 00:00:00 2001 From: Bonajo Date: Sun, 26 Mar 2023 18:40:31 +0200 Subject: [PATCH 2/2] fix: escape killingTest when needed Just quoting the killingTest can break when using Kotlin. However as 'commons-text' is already a dependency we can use `escapeCsv` to escape. --- .../report/csv/CSVReportListener.java | 4 +++- .../report/csv/CSVReportListenerTest.java | 16 ++++++++++++++-- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/pitest-entry/src/main/java/org/pitest/mutationtest/report/csv/CSVReportListener.java b/pitest-entry/src/main/java/org/pitest/mutationtest/report/csv/CSVReportListener.java index 1d1ad730a..96828ed4b 100644 --- a/pitest-entry/src/main/java/org/pitest/mutationtest/report/csv/CSVReportListener.java +++ b/pitest-entry/src/main/java/org/pitest/mutationtest/report/csv/CSVReportListener.java @@ -18,6 +18,8 @@ import java.io.Writer; import java.util.Optional; + +import org.apache.commons.text.StringEscapeUtils; import org.pitest.mutationtest.ClassMutationResults; import org.pitest.mutationtest.MutationResult; import org.pitest.mutationtest.MutationResultListener; @@ -37,7 +39,7 @@ public CSVReportListener(final Writer out) { } private String createKillingTestDesc(final Optional killingTest) { - return (killingTest.isPresent()) ? String.format("\"%s\"", killingTest.get()) : "none"; + return (killingTest.isPresent()) ? StringEscapeUtils.escapeCsv(killingTest.get()) : "none"; } private String makeCsv(final Object... os) { diff --git a/pitest-entry/src/test/java/org/pitest/mutationtest/report/csv/CSVReportListenerTest.java b/pitest-entry/src/test/java/org/pitest/mutationtest/report/csv/CSVReportListenerTest.java index fbaab714f..152cab752 100644 --- a/pitest-entry/src/test/java/org/pitest/mutationtest/report/csv/CSVReportListenerTest.java +++ b/pitest-entry/src/test/java/org/pitest/mutationtest/report/csv/CSVReportListenerTest.java @@ -47,14 +47,26 @@ public void setup() { public void shouldOutputKillingTestWhenOneFound() throws IOException { final MutationResult mr = new MutationResult( MutationTestResultMother.createDetails(), new MutationStatusTestPair(1, - DetectionStatus.KILLED, "foo(java.lang.String, java.lang.String)")); + DetectionStatus.KILLED, "foo")); this.testee.handleMutationResult(MutationTestResultMother .createClassResults(mr)); - final String expected = "file,clazz,mutator,method,42,KILLED,\"foo(java.lang.String, java.lang.String)\"" + final String expected = "file,clazz,mutator,method,42,KILLED,foo" + NEW_LINE; verify(this.out).write(expected); } + @Test + public void shouldQuoteKillingTestWhenNeeded() throws IOException { + final MutationResult mr = new MutationResult( + MutationTestResultMother.createDetails(), new MutationStatusTestPair(1, + DetectionStatus.KILLED, "foo(java.lang.String, java.lang.String)")); + this.testee.handleMutationResult(MutationTestResultMother + .createClassResults(mr)); + final String expected = "file,clazz,mutator,method,42,KILLED,\"foo(java.lang.String, java.lang.String)\"" + + NEW_LINE; + verify(this.out).write(expected); + } + @Test public void shouldOutputNoneWhenNoKillingTestFound() throws IOException { final MutationResult mr = new MutationResult(