From 7f436c9c3e84487ea236dc5fe7307248c8e4f7f9 Mon Sep 17 00:00:00 2001 From: Daniel Miladinov Date: Thu, 5 Dec 2024 08:27:18 -0500 Subject: [PATCH 1/2] Pretty-Print DocStringArgument Step Arguments Signed-off-by: Daniel Miladinov --- .../cucumber/core/plugin/PrettyFormatter.java | 21 ++++-- .../core/plugin/PrettyFormatterTest.java | 66 +++++++++++++++++++ 2 files changed, 82 insertions(+), 5 deletions(-) diff --git a/cucumber-core/src/main/java/io/cucumber/core/plugin/PrettyFormatter.java b/cucumber-core/src/main/java/io/cucumber/core/plugin/PrettyFormatter.java index a37c03513f..029b61e4c9 100644 --- a/cucumber-core/src/main/java/io/cucumber/core/plugin/PrettyFormatter.java +++ b/cucumber-core/src/main/java/io/cucumber/core/plugin/PrettyFormatter.java @@ -2,6 +2,7 @@ import io.cucumber.core.exception.CucumberException; import io.cucumber.core.gherkin.DataTableArgument; +import io.cucumber.core.gherkin.DocStringArgument; import io.cucumber.datatable.DataTable; import io.cucumber.datatable.DataTableFormatter; import io.cucumber.plugin.ColorAware; @@ -141,18 +142,28 @@ private void printStep(TestStepFinished event) { String locationComment = formatLocationComment(event, testStep, keyword, stepText); out.println(STEP_INDENT + formattedStepText + locationComment); StepArgument stepArgument = testStep.getStep().getArgument(); - if (DataTableArgument.class.isInstance(stepArgument)) { + if (stepArgument instanceof DataTableArgument) { DataTableFormatter tableFormatter = DataTableFormatter - .builder() - .prefixRow(STEP_SCENARIO_INDENT) - .escapeDelimiters(false) - .build(); + .builder() + .prefixRow(STEP_SCENARIO_INDENT) + .escapeDelimiters(false) + .build(); DataTableArgument dataTableArgument = (DataTableArgument) stepArgument; try { tableFormatter.formatTo(DataTable.create(dataTableArgument.cells()), out); } catch (IOException e) { throw new CucumberException(e); } + } else if (stepArgument instanceof DocStringArgument) { + DocStringArgument docStringArgument = (DocStringArgument) stepArgument; + String contentType = docStringArgument.getContentType(); + String printableContentType = contentType == null ? "" : contentType; + out.println(STEP_INDENT + "\"\"\"" + printableContentType); + for (String l : docStringArgument.getContent().split("\\r?\\n|\\r")) { + String s = STEP_INDENT + l; + out.println(s); + } + out.println(STEP_INDENT + "\"\"\""); } } } diff --git a/cucumber-core/src/test/java/io/cucumber/core/plugin/PrettyFormatterTest.java b/cucumber-core/src/test/java/io/cucumber/core/plugin/PrettyFormatterTest.java index f274c2dc70..828c0bbe09 100755 --- a/cucumber-core/src/test/java/io/cucumber/core/plugin/PrettyFormatterTest.java +++ b/cucumber-core/src/test/java/io/cucumber/core/plugin/PrettyFormatterTest.java @@ -16,6 +16,7 @@ import io.cucumber.core.stepexpression.StepExpressionFactory; import io.cucumber.core.stepexpression.StepTypeRegistry; import io.cucumber.datatable.DataTable; +import io.cucumber.docstring.DocString; import org.junit.jupiter.api.Test; import java.io.ByteArrayOutputStream; @@ -611,4 +612,69 @@ void should_print_system_failure_for_failed_hooks() { " " + AnsiEscapes.RED + "the stack trace" + AnsiEscapes.RESET))); } + @Test + void should_print_docstring_without_content_type() { + Feature feature = TestFeatureParser.parse("path/test.feature", "" + + "Feature: Test feature\n" + + " Scenario: Test Scenario\n" + + " Given first step\n" + + " \"\"\"\n" + + " {\"key1\": \"value1\",\n" + + " \"key2\": \"value2\",\n" + + " \"another1\": \"another2\"}\n" + + " \"\"\"\n"); + + ByteArrayOutputStream out = new ByteArrayOutputStream(); + Runtime.builder() + .withFeatureSupplier(new StubFeatureSupplier(feature)) + .withAdditionalPlugins(new PrettyFormatter(out)) + .withRuntimeOptions(new RuntimeOptionsBuilder().setMonochrome().build()) + .withBackendSupplier(new StubBackendSupplier( + new StubStepDefinition("first step", "path/step_definitions.java:7", DocString.class))) + .build() + .run(); + + assertThat(out, bytes(equalToCompressingWhiteSpace("" + + "\n" + + "Scenario: Test Scenario # path/test.feature:2\n" + + " Given first step # path/step_definitions.java:7\n" + + " \"\"\"\n" + + " {\"key1\": \"value1\",\n" + + " \"key2\": \"value2\",\n" + + " \"another1\": \"another2\"}\n" + + " \"\"\"\n"))); + } + + @Test + void should_print_docstring_including_content_type() { + Feature feature = TestFeatureParser.parse("path/test.feature", "" + + "Feature: Test feature\n" + + " Scenario: Test Scenario\n" + + " Given first step\n" + + " \"\"\"json\n" + + " {\"key1\": \"value1\",\n" + + " \"key2\": \"value2\",\n" + + " \"another1\": \"another2\"}\n" + + " \"\"\"\n"); + + ByteArrayOutputStream out = new ByteArrayOutputStream(); + Runtime.builder() + .withFeatureSupplier(new StubFeatureSupplier(feature)) + .withAdditionalPlugins(new PrettyFormatter(out)) + .withRuntimeOptions(new RuntimeOptionsBuilder().setMonochrome().build()) + .withBackendSupplier(new StubBackendSupplier( + new StubStepDefinition("first step", "path/step_definitions.java:7", DocString.class))) + .build() + .run(); + + assertThat(out, bytes(equalToCompressingWhiteSpace("" + + "\n" + + "Scenario: Test Scenario # path/test.feature:2\n" + + " Given first step # path/step_definitions.java:7\n" + + " \"\"\"json\n" + + " {\"key1\": \"value1\",\n" + + " \"key2\": \"value2\",\n" + + " \"another1\": \"another2\"}\n" + + " \"\"\"\n"))); + } } From bd39829a303ac2b175416483b6f4786d4b2feab9 Mon Sep 17 00:00:00 2001 From: Daniel Miladinov Date: Sun, 8 Dec 2024 19:38:28 -0500 Subject: [PATCH 2/2] Apply Code Review Feedback Thanks, @mpkorstanje! Signed-off-by: Daniel Miladinov --- CHANGELOG.md | 2 + .../cucumber/core/plugin/PrettyFormatter.java | 8 +- .../core/plugin/PrettyFormatterTest.java | 92 +++++++++---------- 3 files changed, 52 insertions(+), 50 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a453ff5562..d6adf89359 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed - [JUnit Platform Engine] Use JUnit Platform 1.11.3 (JUnit Jupiter 5.11.3) +### Fixed +- [Core] Pretty-Print DocStringArgument Step Arguments([#2953](https://github.com/cucumber/cucumber-jvm/pull/2953) Daniel Miladinov) ## [7.20.1] - 2024-10-09 ### Fixed diff --git a/cucumber-core/src/main/java/io/cucumber/core/plugin/PrettyFormatter.java b/cucumber-core/src/main/java/io/cucumber/core/plugin/PrettyFormatter.java index 029b61e4c9..973254bb35 100644 --- a/cucumber-core/src/main/java/io/cucumber/core/plugin/PrettyFormatter.java +++ b/cucumber-core/src/main/java/io/cucumber/core/plugin/PrettyFormatter.java @@ -144,10 +144,10 @@ private void printStep(TestStepFinished event) { StepArgument stepArgument = testStep.getStep().getArgument(); if (stepArgument instanceof DataTableArgument) { DataTableFormatter tableFormatter = DataTableFormatter - .builder() - .prefixRow(STEP_SCENARIO_INDENT) - .escapeDelimiters(false) - .build(); + .builder() + .prefixRow(STEP_SCENARIO_INDENT) + .escapeDelimiters(false) + .build(); DataTableArgument dataTableArgument = (DataTableArgument) stepArgument; try { tableFormatter.formatTo(DataTable.create(dataTableArgument.cells()), out); diff --git a/cucumber-core/src/test/java/io/cucumber/core/plugin/PrettyFormatterTest.java b/cucumber-core/src/test/java/io/cucumber/core/plugin/PrettyFormatterTest.java index 828c0bbe09..3ef77eedd7 100755 --- a/cucumber-core/src/test/java/io/cucumber/core/plugin/PrettyFormatterTest.java +++ b/cucumber-core/src/test/java/io/cucumber/core/plugin/PrettyFormatterTest.java @@ -615,66 +615,66 @@ void should_print_system_failure_for_failed_hooks() { @Test void should_print_docstring_without_content_type() { Feature feature = TestFeatureParser.parse("path/test.feature", "" + - "Feature: Test feature\n" + - " Scenario: Test Scenario\n" + - " Given first step\n" + - " \"\"\"\n" + - " {\"key1\": \"value1\",\n" + - " \"key2\": \"value2\",\n" + - " \"another1\": \"another2\"}\n" + - " \"\"\"\n"); + "Feature: Test feature\n" + + " Scenario: Test Scenario\n" + + " Given first step\n" + + " \"\"\"\n" + + " {\"key1\": \"value1\",\n" + + " \"key2\": \"value2\",\n" + + " \"another1\": \"another2\"}\n" + + " \"\"\"\n"); ByteArrayOutputStream out = new ByteArrayOutputStream(); Runtime.builder() - .withFeatureSupplier(new StubFeatureSupplier(feature)) - .withAdditionalPlugins(new PrettyFormatter(out)) - .withRuntimeOptions(new RuntimeOptionsBuilder().setMonochrome().build()) - .withBackendSupplier(new StubBackendSupplier( - new StubStepDefinition("first step", "path/step_definitions.java:7", DocString.class))) - .build() - .run(); + .withFeatureSupplier(new StubFeatureSupplier(feature)) + .withAdditionalPlugins(new PrettyFormatter(out)) + .withRuntimeOptions(new RuntimeOptionsBuilder().setMonochrome().build()) + .withBackendSupplier(new StubBackendSupplier( + new StubStepDefinition("first step", "path/step_definitions.java:7", DocString.class))) + .build() + .run(); assertThat(out, bytes(equalToCompressingWhiteSpace("" + - "\n" + - "Scenario: Test Scenario # path/test.feature:2\n" + - " Given first step # path/step_definitions.java:7\n" + - " \"\"\"\n" + - " {\"key1\": \"value1\",\n" + - " \"key2\": \"value2\",\n" + - " \"another1\": \"another2\"}\n" + - " \"\"\"\n"))); + "\n" + + "Scenario: Test Scenario # path/test.feature:2\n" + + " Given first step # path/step_definitions.java:7\n" + + " \"\"\"\n" + + " {\"key1\": \"value1\",\n" + + " \"key2\": \"value2\",\n" + + " \"another1\": \"another2\"}\n" + + " \"\"\"\n"))); } @Test void should_print_docstring_including_content_type() { Feature feature = TestFeatureParser.parse("path/test.feature", "" + - "Feature: Test feature\n" + - " Scenario: Test Scenario\n" + - " Given first step\n" + - " \"\"\"json\n" + - " {\"key1\": \"value1\",\n" + - " \"key2\": \"value2\",\n" + - " \"another1\": \"another2\"}\n" + - " \"\"\"\n"); + "Feature: Test feature\n" + + " Scenario: Test Scenario\n" + + " Given first step\n" + + " \"\"\"json\n" + + " {\"key1\": \"value1\",\n" + + " \"key2\": \"value2\",\n" + + " \"another1\": \"another2\"}\n" + + " \"\"\"\n"); ByteArrayOutputStream out = new ByteArrayOutputStream(); Runtime.builder() - .withFeatureSupplier(new StubFeatureSupplier(feature)) - .withAdditionalPlugins(new PrettyFormatter(out)) - .withRuntimeOptions(new RuntimeOptionsBuilder().setMonochrome().build()) - .withBackendSupplier(new StubBackendSupplier( - new StubStepDefinition("first step", "path/step_definitions.java:7", DocString.class))) - .build() - .run(); + .withFeatureSupplier(new StubFeatureSupplier(feature)) + .withAdditionalPlugins(new PrettyFormatter(out)) + .withRuntimeOptions(new RuntimeOptionsBuilder().setMonochrome().build()) + .withBackendSupplier(new StubBackendSupplier( + new StubStepDefinition("first step", "path/step_definitions.java:7", DocString.class))) + .build() + .run(); assertThat(out, bytes(equalToCompressingWhiteSpace("" + - "\n" + - "Scenario: Test Scenario # path/test.feature:2\n" + - " Given first step # path/step_definitions.java:7\n" + - " \"\"\"json\n" + - " {\"key1\": \"value1\",\n" + - " \"key2\": \"value2\",\n" + - " \"another1\": \"another2\"}\n" + - " \"\"\"\n"))); + "\n" + + "Scenario: Test Scenario # path/test.feature:2\n" + + " Given first step # path/step_definitions.java:7\n" + + " \"\"\"json\n" + + " {\"key1\": \"value1\",\n" + + " \"key2\": \"value2\",\n" + + " \"another1\": \"another2\"}\n" + + " \"\"\"\n"))); } }