diff --git a/java/.mvn/jvm.config b/java/.mvn/jvm.config new file mode 100644 index 0000000..32599ce --- /dev/null +++ b/java/.mvn/jvm.config @@ -0,0 +1,10 @@ +--add-exports jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED +--add-exports jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED +--add-exports jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED +--add-exports jdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED +--add-exports jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED +--add-exports jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED +--add-exports jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED +--add-exports jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED +--add-opens jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED +--add-opens jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED diff --git a/java/pom.xml b/java/pom.xml index 50486b9..360a706 100644 --- a/java/pom.xml +++ b/java/pom.xml @@ -5,11 +5,11 @@ io.cucumber cucumber-parent - 4.5.0 + 5.0.0-SNAPSHOT testng-xml-formatter - 0.7.1-SNAPSHOT + 0.8.0-SNAPSHOT jar TestNG XML Formatter Renders Cucumber Messages as TestNG XML @@ -59,12 +59,12 @@ io.cucumber messages - [29.0.1,31.0.0) + [32.0.0-SNAPSHOT,33.0.0) io.cucumber query - [14.0.1,15.0.0) + [15.0.0-SNAPSHOT,16.0.0) @@ -85,13 +85,6 @@ test - - org.hamcrest - hamcrest - 3.0 - test - - org.assertj assertj-core @@ -111,4 +104,22 @@ test + + + + + org.apache.maven.plugins + maven-checkstyle-plugin + + + validate + validate + + check + + + + + + diff --git a/java/src/main/java/io/cucumber/testngxmlformatter/EscapingXmlStreamWriter.java b/java/src/main/java/io/cucumber/testngxmlformatter/EscapingXmlStreamWriter.java index 25f0443..5acf46e 100644 --- a/java/src/main/java/io/cucumber/testngxmlformatter/EscapingXmlStreamWriter.java +++ b/java/src/main/java/io/cucumber/testngxmlformatter/EscapingXmlStreamWriter.java @@ -20,6 +20,7 @@ public void close() throws XMLStreamException { writer.close(); } + @SuppressWarnings("SameParameterValue") void writeStartDocument(String encoding, String version) throws XMLStreamException { writer.writeStartDocument(encoding, version); } @@ -56,7 +57,7 @@ void writeAttribute(String localName, String value) throws XMLStreamException { void writeCData(String data) throws XMLStreamException { // https://stackoverflow.com/questions/223652/is-there-a-way-to-escape-a-cdata-end-token-in-xml - for (String part : CDATA_TERMINATOR_SPLIT.split(data)) { + for (String part : CDATA_TERMINATOR_SPLIT.split(data, -1)) { // see https://www.w3.org/TR/xml/#dt-cdsection writer.writeCData(escapeIllegalChars(part)); } @@ -88,6 +89,7 @@ private static String escapeIllegalChars(String value) { return escaped.toString(); } + @SuppressWarnings("UnnecessaryParentheses") private static boolean isLegal(int codePoint) { // see https://www.w3.org/TR/xml/#charsets return codePoint == 0x9 diff --git a/java/src/main/java/io/cucumber/testngxmlformatter/XmlReportData.java b/java/src/main/java/io/cucumber/testngxmlformatter/XmlReportData.java index c9c880b..005ca8e 100644 --- a/java/src/main/java/io/cucumber/testngxmlformatter/XmlReportData.java +++ b/java/src/main/java/io/cucumber/testngxmlformatter/XmlReportData.java @@ -41,7 +41,7 @@ class XmlReportData { private static final io.cucumber.messages.types.Duration ZERO_DURATION = - new io.cucumber.messages.types.Duration(0L, 0L); + new io.cucumber.messages.types.Duration(0L, 0); // By definition, but see https://github.com/cucumber/gherkin/issues/11 private static final TestStepResult SCENARIO_WITH_NO_STEPS = new TestStepResult(ZERO_DURATION, null, PASSED, null); private final Repository repository = Repository.builder() diff --git a/java/src/main/java/io/cucumber/testngxmlformatter/XmlReportWriter.java b/java/src/main/java/io/cucumber/testngxmlformatter/XmlReportWriter.java index 478e05c..1044127 100644 --- a/java/src/main/java/io/cucumber/testngxmlformatter/XmlReportWriter.java +++ b/java/src/main/java/io/cucumber/testngxmlformatter/XmlReportWriter.java @@ -50,8 +50,8 @@ private void writeTestngResultsAttributes(EscapingXmlStreamWriter writer) throws Map counts = data.getTestCaseStatusCounts(); writer.writeAttribute("failed", String.valueOf(countFailures(counts))); - writer.writeAttribute("passed", counts.get(PASSED).toString()); - writer.writeAttribute("skipped", counts.get(SKIPPED).toString()); + writer.writeAttribute("passed", String.valueOf(counts.get(PASSED))); + writer.writeAttribute("skipped", String.valueOf(counts.get(SKIPPED))); writer.writeAttribute("total", String.valueOf(data.getTestCaseCount())); } @@ -142,14 +142,11 @@ private void writeTestMethodAttributes(EscapingXmlStreamWriter writer, TestCaseS } private String writeStatus(TestStepResult status) { - switch (status.getStatus()) { - case PASSED: - return "PASS"; - case SKIPPED: - return "SKIP"; - default: - return "FAIL"; - } + return switch (status.getStatus()) { + case PASSED -> "PASS"; + case SKIPPED -> "SKIP"; + default -> "FAIL"; + }; } private void writeException(EscapingXmlStreamWriter writer, TestCaseStarted testCaseStarted, TestStepResult result) throws XMLStreamException { @@ -216,9 +213,7 @@ private String createStepResultList(List> results) { String status = r.getValue(); sb.append(stepText); sb.append("."); - for (int i = 75 - stepText.length(); i > 0; i--) { - sb.append("."); - } + sb.append(".".repeat(Math.max(0, 75 - stepText.length()))); sb.append(status); sb.append("\n"); }); diff --git a/java/src/main/java/io/cucumber/testngxmlformatter/package-info.java b/java/src/main/java/io/cucumber/testngxmlformatter/package-info.java new file mode 100644 index 0000000..1dba1b9 --- /dev/null +++ b/java/src/main/java/io/cucumber/testngxmlformatter/package-info.java @@ -0,0 +1,4 @@ +@NullMarked +package io.cucumber.testngxmlformatter; + +import org.jspecify.annotations.NullMarked; diff --git a/java/src/test/java/io/cucumber/testngxmlformatter/EscapingXmlStreamWriterTest.java b/java/src/test/java/io/cucumber/testngxmlformatter/EscapingXmlStreamWriterTest.java index 57537a8..9e4084e 100644 --- a/java/src/test/java/io/cucumber/testngxmlformatter/EscapingXmlStreamWriterTest.java +++ b/java/src/test/java/io/cucumber/testngxmlformatter/EscapingXmlStreamWriterTest.java @@ -64,7 +64,7 @@ void shouldEscapeCDataElement() throws XMLStreamException { } private static String asString(ByteArrayOutputStream out) { - String s = new String(out.toByteArray(), UTF_8); + String s = out.toString(UTF_8); return removeXmlHeader(s); } diff --git a/java/src/test/java/io/cucumber/testngxmlformatter/Jackson.java b/java/src/test/java/io/cucumber/testngxmlformatter/Jackson.java index cdf2430..34593f9 100644 --- a/java/src/test/java/io/cucumber/testngxmlformatter/Jackson.java +++ b/java/src/test/java/io/cucumber/testngxmlformatter/Jackson.java @@ -1,7 +1,6 @@ package io.cucumber.testngxmlformatter; import com.fasterxml.jackson.annotation.JsonCreator.Mode; -import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; @@ -11,11 +10,14 @@ import com.fasterxml.jackson.datatype.jdk8.Jdk8Module; import com.fasterxml.jackson.module.paramnames.ParameterNamesModule; +import static com.fasterxml.jackson.annotation.JsonInclude.Include.NON_ABSENT; +import static com.fasterxml.jackson.annotation.JsonInclude.Value.construct; + final class Jackson { public static final ObjectMapper OBJECT_MAPPER = JsonMapper.builder() .addModule(new Jdk8Module()) .addModule(new ParameterNamesModule(Mode.PROPERTIES)) - .serializationInclusion(Include.NON_ABSENT) + .defaultPropertyInclusion(construct(NON_ABSENT, NON_ABSENT)) .constructorDetector(ConstructorDetector.USE_PROPERTIES_BASED) .enable(SerializationFeature.WRITE_ENUMS_USING_TO_STRING) .enable(DeserializationFeature.READ_ENUMS_USING_TO_STRING) diff --git a/java/src/test/java/io/cucumber/testngxmlformatter/MessagesToTestngXmlWriterAcceptanceTest.java b/java/src/test/java/io/cucumber/testngxmlformatter/MessagesToTestngXmlWriterAcceptanceTest.java index 347f0bf..d004b55 100644 --- a/java/src/test/java/io/cucumber/testngxmlformatter/MessagesToTestngXmlWriterAcceptanceTest.java +++ b/java/src/test/java/io/cucumber/testngxmlformatter/MessagesToTestngXmlWriterAcceptanceTest.java @@ -22,10 +22,11 @@ import java.util.stream.Stream; import static io.cucumber.testngxmlformatter.Jackson.OBJECT_MAPPER; +import static java.util.Objects.requireNonNull; import static org.xmlunit.assertj.XmlAssert.assertThat; class MessagesToTestngXmlWriterAcceptanceTest { - private static final NdjsonToMessageIterable.Deserializer deserializer = (json) -> OBJECT_MAPPER.readValue(json, Envelope.class); + private static final NdjsonToMessageIterable.Deserializer deserializer = json -> OBJECT_MAPPER.readValue(json, Envelope.class); static List acceptance() throws IOException { try (Stream paths = Files.list(Paths.get("../testdata/src"))) { @@ -68,17 +69,16 @@ private static T writeTestngXmlReport(TestCase testCase return out; } - static class TestCase { + private static final class TestCase { private final Path source; private final Path expected; - private final String name; TestCase(Path source) { this.source = source; String fileName = source.getFileName().toString(); this.name = fileName.substring(0, fileName.lastIndexOf(".ndjson")); - this.expected = source.getParent().resolve(name + ".xml"); + this.expected = requireNonNull(source.getParent()).resolve(name + ".xml"); } @Override @@ -88,15 +88,13 @@ public String toString() { @Override public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - TestCase testCase = (TestCase) o; - return source.equals(testCase.source); + if (!(o instanceof TestCase testCase)) return false; + return Objects.equals(source, testCase.source) && Objects.equals(expected, testCase.expected) && Objects.equals(name, testCase.name); } @Override public int hashCode() { - return Objects.hash(source); + return Objects.hash(source, expected, name); } } diff --git a/java/src/test/java/io/cucumber/testngxmlformatter/MessagesToTestngXmlWriterTest.java b/java/src/test/java/io/cucumber/testngxmlformatter/MessagesToTestngXmlWriterTest.java index cd34bd0..72bd2ae 100644 --- a/java/src/test/java/io/cucumber/testngxmlformatter/MessagesToTestngXmlWriterTest.java +++ b/java/src/test/java/io/cucumber/testngxmlformatter/MessagesToTestngXmlWriterTest.java @@ -3,6 +3,7 @@ import io.cucumber.messages.types.Envelope; import io.cucumber.messages.types.TestRunFinished; import io.cucumber.messages.types.TestRunStarted; +import io.cucumber.messages.types.Timestamp; import org.junit.jupiter.api.Test; import java.io.ByteArrayOutputStream; @@ -26,28 +27,30 @@ void it_writes_two_messages_to_xml() throws IOException { Envelope.of(new TestRunStarted(toMessage(started), null)), Envelope.of(new TestRunFinished(null, true, toMessage(finished), null, null))); - assertThat(html).isEqualTo("" + - "\n" + - "\n" + - "\n" + - "\n" + - "\n" + - "\n" + - "\n" + assertThat(html).isEqualTo(""" + + + + + + + + """ ); } @Test void it_writes_no_message_to_xml() throws IOException { String html = renderAsJunitXml(); - assertThat(html).isEqualTo("" + - "\n" + - "\n" + - "\n" + - "\n" + - "\n" + - "\n" + - "\n" + assertThat(html).isEqualTo(""" + + + + + + + + """ ); } @@ -56,7 +59,9 @@ void it_throws_when_writing_after_close() throws IOException { ByteArrayOutputStream bytes = new ByteArrayOutputStream(); MessagesToTestngXmlWriter messagesToHtmlWriter = new MessagesToTestngXmlWriter(bytes); messagesToHtmlWriter.close(); - assertThrows(IOException.class, () -> messagesToHtmlWriter.write(null)); + assertThrows(IOException.class, () -> messagesToHtmlWriter.write( + Envelope.of(new TestRunStarted(new Timestamp(0L, 0), "")) + )); } @Test @@ -92,6 +97,6 @@ private static String renderAsJunitXml(Envelope... messages) throws IOException } } - return new String(bytes.toByteArray(), UTF_8); + return bytes.toString(UTF_8); } }