Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions java/.mvn/jvm.config
Original file line number Diff line number Diff line change
@@ -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
33 changes: 22 additions & 11 deletions java/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@
<parent>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-parent</artifactId>
<version>4.5.0</version>
<version>5.0.0-SNAPSHOT</version>
</parent>

<artifactId>testng-xml-formatter</artifactId>
<version>0.7.1-SNAPSHOT</version>
<version>0.8.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>TestNG XML Formatter</name>
<description>Renders Cucumber Messages as TestNG XML</description>
Expand Down Expand Up @@ -59,12 +59,12 @@
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>messages</artifactId>
<version>[29.0.1,31.0.0)</version>
<version>[32.0.0-SNAPSHOT,33.0.0)</version>
</dependency>
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>query</artifactId>
<version>[14.0.1,15.0.0)</version>
<version>[15.0.0-SNAPSHOT,16.0.0)</version>
</dependency>

<dependency>
Expand All @@ -85,13 +85,6 @@
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest</artifactId>
<version>3.0</version>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
Expand All @@ -111,4 +104,22 @@
<scope>test</scope>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<executions>
<execution>
<id>validate</id>
<phase>validate</phase>
<goals>
<goal>check</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down Expand Up @@ -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));
}
Expand Down Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@ private void writeTestngResultsAttributes(EscapingXmlStreamWriter writer) throws
Map<TestStepResultStatus, Long> 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()));
}

Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -216,9 +213,7 @@ private String createStepResultList(List<Entry<String, String>> 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");
});
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
@NullMarked
package io.cucumber.testngxmlformatter;

import org.jspecify.annotations.NullMarked;
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<TestCase> acceptance() throws IOException {
try (Stream<Path> paths = Files.list(Paths.get("../testdata/src"))) {
Expand Down Expand Up @@ -68,17 +69,16 @@ private static <T extends OutputStream> 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
Expand All @@ -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);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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("" +
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
"<testng-results failed=\"0\" passed=\"0\" skipped=\"0\" total=\"0\">\n" +
"<suite name=\"Cucumber\" duration-ms=\"20000\">\n" +
"<test name=\"Cucumber\" duration-ms=\"20000\">\n" +
"</test>\n" +
"</suite>\n" +
"</testng-results>\n"
assertThat(html).isEqualTo("""
<?xml version="1.0" encoding="UTF-8"?>
<testng-results failed="0" passed="0" skipped="0" total="0">
<suite name="Cucumber" duration-ms="20000">
<test name="Cucumber" duration-ms="20000">
</test>
</suite>
</testng-results>
"""
);
}

@Test
void it_writes_no_message_to_xml() throws IOException {
String html = renderAsJunitXml();
assertThat(html).isEqualTo("" +
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
"<testng-results failed=\"0\" passed=\"0\" skipped=\"0\" total=\"0\">\n" +
"<suite name=\"Cucumber\" duration-ms=\"0\">\n" +
"<test name=\"Cucumber\" duration-ms=\"0\">\n" +
"</test>\n" +
"</suite>\n" +
"</testng-results>\n"
assertThat(html).isEqualTo("""
<?xml version="1.0" encoding="UTF-8"?>
<testng-results failed="0" passed="0" skipped="0" total="0">
<suite name="Cucumber" duration-ms="0">
<test name="Cucumber" duration-ms="0">
</test>
</suite>
</testng-results>
"""
);
}

Expand All @@ -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
Expand Down Expand Up @@ -92,6 +97,6 @@ private static String renderAsJunitXml(Envelope... messages) throws IOException
}
}

return new String(bytes.toByteArray(), UTF_8);
return bytes.toString(UTF_8);
}
}
Loading