diff --git a/CHANGELOG.md b/CHANGELOG.md
index 93d4cbf664..31e9c4fbaa 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -18,8 +18,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Changed
- [JUnit Platform Engine] Use JUnit's `EngineDiscoveryRequestResolver` to resolve classpath based resources. ([#2835](https://github.com/cucumber/cucumber-jvm/pull/2835) M.P. Korstanje)
- [JUnit Platform Engine] Use JUnit Platform 1.13.3 (JUnit Jupiter 5.13.3)
+- [Core] Use a message based [Pretty Formatter](https://github.com/cucumber/pretty-formatter) ([#2835](https://github.com/cucumber/cucumber-jvm/pull/3012) M.P. Korstanje)
- [Core] Update dependency io.cucumber:gherkin to v33.0.0
-- [Core] Update dependency io.cucumber:messages to v28.0.0
+- [Core] Update dependency io.cucumber:messages to v28.2.0
+- [Core] Update dependency io.cucumber:html-formatter to v21.13.0
+- [Core] Update dependency io.cucumber:junit-xml-formatter to v0.8.0
+- [Core] Update dependency io.cucumber:query to v13.4.0
+- [Core] Update dependency io.cucumber:testng-xml-formatter to v0.4.1
### Fixed
- [JUnit Platform Engine] Log discovery issues for feature files with parse errors. ([#2835](https://github.com/cucumber/cucumber-jvm/pull/2835) M.P. Korstanje)
diff --git a/cucumber-bom/pom.xml b/cucumber-bom/pom.xml
index 9c74967fac..eeec57fe24 100644
--- a/cucumber-bom/pom.xml
+++ b/cucumber-bom/pom.xml
@@ -16,12 +16,13 @@
10.0.1
18.0.1
33.0.0
- 21.12.0
- 0.7.1
+ 21.13.0
+ 0.8.0
28.0.0
- 13.3.0
+ 0.2.0
+ 13.4.0
6.1.2
- 0.3.1
+ 0.4.0
@@ -57,6 +58,11 @@
messages
${messages.version}
+
+ io.cucumber
+ pretty-formatter
+ ${pretty-formatter.version}
+
io.cucumber
query
diff --git a/cucumber-core/pom.xml b/cucumber-core/pom.xml
index 73e2106aab..039ced8d81 100644
--- a/cucumber-core/pom.xml
+++ b/cucumber-core/pom.xml
@@ -64,6 +64,10 @@
io.cucumber
messages
+
+ io.cucumber
+ pretty-formatter
+
io.cucumber
testng-xml-formatter
diff --git a/cucumber-core/src/main/java/io/cucumber/core/plugin/AnsiEscapes.java b/cucumber-core/src/main/java/io/cucumber/core/plugin/AnsiEscapes.java
index 61ef287bb3..6fbba67caa 100644
--- a/cucumber-core/src/main/java/io/cucumber/core/plugin/AnsiEscapes.java
+++ b/cucumber-core/src/main/java/io/cucumber/core/plugin/AnsiEscapes.java
@@ -13,6 +13,7 @@ final class AnsiEscapes {
static final AnsiEscapes DEFAULT = color(9);
static final AnsiEscapes GREY = color(90);
static final AnsiEscapes INTENSITY_BOLD = color(1);
+ static final AnsiEscapes INTENSITY_BOLD_OFF = color(22);
static final AnsiEscapes UNDERLINE = color(4);
private static final char ESC = 27;
private static final char BRACKET = '[';
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 d6e731cd15..699e046f12 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
@@ -1,44 +1,19 @@
package io.cucumber.core.plugin;
-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.docstring.DocString;
-import io.cucumber.docstring.DocStringFormatter;
+import io.cucumber.messages.types.Envelope;
import io.cucumber.plugin.ColorAware;
import io.cucumber.plugin.ConcurrentEventListener;
-import io.cucumber.plugin.event.Argument;
-import io.cucumber.plugin.event.EmbedEvent;
import io.cucumber.plugin.event.EventPublisher;
-import io.cucumber.plugin.event.PickleStepTestStep;
-import io.cucumber.plugin.event.Result;
-import io.cucumber.plugin.event.StepArgument;
-import io.cucumber.plugin.event.TestCase;
-import io.cucumber.plugin.event.TestCaseStarted;
-import io.cucumber.plugin.event.TestRunFinished;
-import io.cucumber.plugin.event.TestStepFinished;
-import io.cucumber.plugin.event.WriteEvent;
+import io.cucumber.prettyformatter.MessagesToPrettyWriter;
-import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
-import java.io.StringReader;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.UUID;
-import static io.cucumber.core.exception.ExceptionUtils.printStackTrace;
-import static io.cucumber.core.plugin.Formats.ansi;
-import static io.cucumber.core.plugin.Formats.monochrome;
-import static java.lang.Math.max;
-import static java.util.Locale.ROOT;
+import static io.cucumber.prettyformatter.MessagesToPrettyWriter.PrettyFeature.INCLUDE_FEATURE_LINE;
+import static io.cucumber.prettyformatter.MessagesToPrettyWriter.PrettyFeature.INCLUDE_RULE_LINE;
+import static io.cucumber.prettyformatter.Theme.cucumber;
+import static io.cucumber.prettyformatter.Theme.none;
/**
* Prints a pretty report of the scenario execution as it happens.
@@ -48,269 +23,47 @@
*/
public final class PrettyFormatter implements ConcurrentEventListener, ColorAware {
- private static final String SCENARIO_INDENT = "";
- private static final String STEP_INDENT = SCENARIO_INDENT + " ";
- private static final String STEP_SCENARIO_INDENT = STEP_INDENT + " ";
- private static final String STACK_TRACE_INDENT = STEP_SCENARIO_INDENT + " ";
-
- private final Map commentStartIndex = new HashMap<>();
-
- private final UTF8PrintWriter out;
- private Formats formats = ansi();
+ private final OutputStream out;
+ private MessagesToPrettyWriter writer;
public PrettyFormatter(OutputStream out) {
- this.out = new UTF8PrintWriter(out);
- }
-
- @Override
- public void setEventPublisher(EventPublisher publisher) {
- publisher.registerHandlerFor(TestCaseStarted.class, this::handleTestCaseStarted);
- publisher.registerHandlerFor(TestStepFinished.class, this::handleTestStepFinished);
- publisher.registerHandlerFor(WriteEvent.class, this::handleWrite);
- publisher.registerHandlerFor(EmbedEvent.class, this::handleEmbed);
- publisher.registerHandlerFor(TestRunFinished.class, this::handleTestRunFinished);
- }
-
- private void handleTestCaseStarted(TestCaseStarted event) {
- out.println();
- preCalculateLocationIndent(event);
- printTags(event);
- printScenarioDefinition(event);
- out.flush();
- }
-
- private void handleTestStepFinished(TestStepFinished event) {
- printStep(event);
- printError(event);
- out.flush();
- }
-
- private void handleWrite(WriteEvent event) {
- out.println();
- printText(event);
- out.println();
- out.flush();
- }
-
- private void handleEmbed(EmbedEvent event) {
- out.println();
- printEmbedding(event);
- out.println();
- out.flush();
- }
-
- private void handleTestRunFinished(TestRunFinished event) {
- printError(event);
- out.close();
- }
-
- private void preCalculateLocationIndent(TestCaseStarted event) {
- TestCase testCase = event.getTestCase();
- Integer longestStep = testCase.getTestSteps().stream()
- .filter(PickleStepTestStep.class::isInstance)
- .map(PickleStepTestStep.class::cast)
- .map(PickleStepTestStep::getStep)
- .map(step -> formatPlainStep(step.getKeyword(), step.getText()).length())
- .max(Comparator.naturalOrder())
- .orElse(0);
-
- int scenarioLength = formatScenarioDefinition(testCase).length();
- commentStartIndex.put(testCase.getId(), max(longestStep, scenarioLength) + 1);
- }
-
- private void printTags(TestCaseStarted event) {
- List tags = event.getTestCase().getTags();
- if (!tags.isEmpty()) {
- out.println(SCENARIO_INDENT + String.join(" ", tags));
- }
- }
-
- private void printScenarioDefinition(TestCaseStarted event) {
- TestCase testCase = event.getTestCase();
- String definitionText = formatScenarioDefinition(testCase);
- String path = relativize(testCase.getUri()).getSchemeSpecificPart();
- String locationIndent = calculateLocationIndent(event.getTestCase(), SCENARIO_INDENT + definitionText);
- out.println(SCENARIO_INDENT + definitionText + locationIndent
- + formatLocation(path + ":" + testCase.getLocation().getLine()));
- }
-
- private void printStep(TestStepFinished event) {
- if (event.getTestStep() instanceof PickleStepTestStep) {
- PickleStepTestStep testStep = (PickleStepTestStep) event.getTestStep();
- String keyword = testStep.getStep().getKeyword();
- String stepText = testStep.getStep().getText();
- String status = event.getResult().getStatus().name().toLowerCase(ROOT);
- String formattedStepText = formatStepText(keyword, stepText, formats.get(status),
- formats.get(status + "_arg"), testStep.getDefinitionArgument());
- String locationComment = formatLocationComment(event, testStep, keyword, stepText);
- out.println(STEP_INDENT + formattedStepText + locationComment);
- StepArgument stepArgument = testStep.getStep().getArgument();
- if (stepArgument instanceof DataTableArgument) {
- DataTableFormatter tableFormatter = DataTableFormatter
- .builder()
- .prefixRow(STEP_SCENARIO_INDENT)
- .escapeDelimiters(false)
- .build();
- DataTableArgument dataTableArgument = (DataTableArgument) stepArgument;
- DataTable table = DataTable.create(dataTableArgument.cells());
- try {
- tableFormatter.formatTo(table, out);
- } catch (IOException e) {
- throw new CucumberException(e);
- }
- } else if (stepArgument instanceof DocStringArgument) {
- DocStringFormatter docStringFormatter = DocStringFormatter
- .builder()
- .indentation(STEP_SCENARIO_INDENT)
- .build();
- DocStringArgument docStringArgument = (DocStringArgument) stepArgument;
- DocString docString = DocString.create(docStringArgument.getContent(),
- docStringArgument.getContentType());
- try {
- docStringFormatter.formatTo(docString, out);
- } catch (IOException e) {
- throw new CucumberException(e);
- }
- }
- }
- }
-
- private String formatLocationComment(
- TestStepFinished event, PickleStepTestStep testStep, String keyword, String stepText
- ) {
- String codeLocation = testStep.getCodeLocation();
- if (codeLocation == null) {
- return "";
- }
- String locationIndent = calculateLocationIndent(event.getTestCase(), formatPlainStep(keyword, stepText));
- return locationIndent + formatLocation(codeLocation);
+ this.out = out;
+ this.writer = createBuilder().build(out);
}
- private void printError(TestStepFinished event) {
- Result result = event.getResult();
- printError(STACK_TRACE_INDENT, result);
+ private static MessagesToPrettyWriter.Builder createBuilder() {
+ String cwdUri = new File("").toURI().toString();
+ return MessagesToPrettyWriter.builder()
+ .feature(INCLUDE_FEATURE_LINE, false)
+ .feature(INCLUDE_RULE_LINE, false)
+ .theme(cucumber())
+ .removeUriPrefix(cwdUri);
}
- private void printError(TestRunFinished event) {
- Result result = event.getResult();
- printError(SCENARIO_INDENT, result);
- }
-
- private void printError(String prefix, Result result) {
- Throwable error = result.getError();
- if (error != null) {
- String name = result.getStatus().name().toLowerCase(ROOT);
- Format format = formats.get(name);
- String text = printStackTrace(error);
- // TODO: Java 12+ use String.indent
- String indented = text.replaceAll("(\r\n|\r|\n)", "$1" + prefix).trim();
- out.println(prefix + format.text(indented));
- }
- }
-
- private void printText(WriteEvent event) {
- // Prevent interleaving when multiple threads write to System.out
- StringBuilder builder = new StringBuilder();
- try (BufferedReader lines = new BufferedReader(new StringReader(event.getText()))) {
- String line;
- while ((line = lines.readLine()) != null) {
- builder.append(STEP_SCENARIO_INDENT)
- .append(line)
- // Add system line separator - \n won't do it!
- .append(System.lineSeparator());
- }
- } catch (IOException e) {
- throw new CucumberException(e);
- }
- out.append(builder);
- }
-
- private void printEmbedding(EmbedEvent event) {
- String line = "Embedding " + event.getName() + " [" + event.getMediaType() + " " + event.getData().length
- + " bytes]";
- out.println(STEP_SCENARIO_INDENT + line);
- }
-
- private String formatPlainStep(String keyword, String stepText) {
- return STEP_INDENT + keyword + stepText;
- }
-
- private String formatScenarioDefinition(TestCase testCase) {
- return testCase.getKeyword() + ": " + testCase.getName();
+ @Override
+ public void setEventPublisher(EventPublisher publisher) {
+ publisher.registerHandlerFor(Envelope.class, this::write);
}
- static URI relativize(URI uri) {
- if (!"file".equals(uri.getScheme())) {
- return uri;
- }
- if (!uri.isAbsolute()) {
- return uri;
- }
-
+ private void write(Envelope event) {
try {
- URI root = new File("").toURI();
- URI relative = root.relativize(uri);
- // Scheme is lost by relativize
- return new URI("file", relative.getSchemeSpecificPart(), relative.getFragment());
- } catch (URISyntaxException e) {
- throw new IllegalArgumentException(e.getMessage(), e);
- }
- }
-
- private String calculateLocationIndent(TestCase testStep, String prefix) {
- Integer commentStartAt = commentStartIndex.getOrDefault(testStep.getId(), 0);
- int padding = commentStartAt - prefix.length();
-
- if (padding < 0) {
- return " ";
- }
- StringBuilder builder = new StringBuilder(padding);
- for (int i = 0; i < padding; i++) {
- builder.append(" ");
+ writer.write(event);
+ } catch (IOException e) {
+ throw new IllegalStateException(e);
}
- return builder.toString();
- }
- private String formatLocation(String location) {
- return formats.get("comment").text("# " + location);
- }
-
- String formatStepText(
- String keyword, String stepText, Format textFormat, Format argFormat, List arguments
- ) {
- int beginIndex = 0;
- StringBuilder result = new StringBuilder(textFormat.text(keyword));
- for (Argument argument : arguments) {
- // can be null if the argument is missing.
- if (argument.getValue() != null) {
- int argumentOffset = argument.getStart();
- // a nested argument starts before the enclosing argument ends;
- // ignore it when formatting
- if (argumentOffset < beginIndex) {
- continue;
- }
- String text = stepText.substring(beginIndex, argumentOffset);
- result.append(textFormat.text(text));
- }
- // val can be null if the argument isn't there, for example
- // @And("(it )?has something")
- if (argument.getValue() != null) {
- String text = stepText.substring(argument.getStart(), argument.getEnd());
- result.append(argFormat.text(text));
- // set beginIndex to end of argument
- beginIndex = argument.getEnd();
- }
- }
- if (beginIndex != stepText.length()) {
- String text = stepText.substring(beginIndex);
- result.append(textFormat.text(text));
+ // TODO: Plugins should implement the closable interface
+ // and be closed by Cucumber
+ if (event.getTestRunFinished().isPresent()) {
+ writer.close();
}
- return result.toString();
}
@Override
public void setMonochrome(boolean monochrome) {
- formats = monochrome ? monochrome() : ansi();
+ if (monochrome) {
+ writer = createBuilder().theme(none()).build(out);
+ }
}
}
diff --git a/cucumber-core/src/main/java/io/cucumber/core/plugin/RerunFormatter.java b/cucumber-core/src/main/java/io/cucumber/core/plugin/RerunFormatter.java
index bc23a6168c..e3063116f3 100644
--- a/cucumber-core/src/main/java/io/cucumber/core/plugin/RerunFormatter.java
+++ b/cucumber-core/src/main/java/io/cucumber/core/plugin/RerunFormatter.java
@@ -7,15 +7,16 @@
import io.cucumber.plugin.event.TestCaseFinished;
import io.cucumber.plugin.event.TestRunFinished;
+import java.io.File;
import java.io.OutputStream;
import java.net.URI;
+import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.Map;
import static io.cucumber.core.feature.FeatureWithLines.create;
-import static io.cucumber.core.plugin.PrettyFormatter.relativize;
/**
* Formatter for reporting all failed test cases and print their locations
@@ -61,4 +62,21 @@ private Collection getFailedTestCaseLines(URI uri) {
return featureAndFailedLinesMapping.computeIfAbsent(uri, k -> new ArrayList<>());
}
+ static URI relativize(URI uri) {
+ if (!"file".equals(uri.getScheme())) {
+ return uri;
+ }
+ if (!uri.isAbsolute()) {
+ return uri;
+ }
+
+ try {
+ URI root = new File("").toURI();
+ URI relative = root.relativize(uri);
+ // Scheme is lost by relativize
+ return new URI("file", relative.getSchemeSpecificPart(), relative.getFragment());
+ } catch (URISyntaxException e) {
+ throw new IllegalArgumentException(e.getMessage(), e);
+ }
+ }
}
diff --git a/cucumber-core/src/test/java/io/cucumber/core/backend/StubStepDefinition.java b/cucumber-core/src/test/java/io/cucumber/core/backend/StubStepDefinition.java
index c09c631296..d47e8d06a1 100644
--- a/cucumber-core/src/test/java/io/cucumber/core/backend/StubStepDefinition.java
+++ b/cucumber-core/src/test/java/io/cucumber/core/backend/StubStepDefinition.java
@@ -3,6 +3,7 @@
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Type;
import java.util.List;
+import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@@ -15,6 +16,7 @@ public class StubStepDefinition implements StepDefinition {
private final String expression;
private final Throwable exception;
private final Located location;
+ private SourceReference sourceReference;
public StubStepDefinition(String pattern, String location, Type... types) {
this(pattern, location, null, types);
@@ -35,6 +37,18 @@ public StubStepDefinition(String pattern, String location, Throwable exception,
this.exception = exception;
}
+ public StubStepDefinition(String pattern, SourceReference sourceReference, Type... types) {
+ this(pattern, sourceReference, null, types);
+ }
+
+ public StubStepDefinition(String pattern, SourceReference sourceReference, Throwable exception, Type... types) {
+ this.parameterInfos = Stream.of(types).map(StubParameterInfo::new).collect(Collectors.toList());
+ this.expression = pattern;
+ this.location = new StubLocation("");
+ this.sourceReference = sourceReference;
+ this.exception = exception;
+ }
+
@Override
public boolean isDefinedAt(StackTraceElement stackTraceElement) {
return false;
@@ -70,6 +84,11 @@ public String getPattern() {
return expression;
}
+ @Override
+ public Optional getSourceReference() {
+ return Optional.ofNullable(sourceReference);
+ }
+
private static final class StubParameterInfo implements ParameterInfo {
private final Type type;
diff --git a/cucumber-core/src/test/java/io/cucumber/core/plugin/PrettyFormatterStepDefinition.java b/cucumber-core/src/test/java/io/cucumber/core/plugin/PrettyFormatterStepDefinition.java
new file mode 100644
index 0000000000..09259f4e90
--- /dev/null
+++ b/cucumber-core/src/test/java/io/cucumber/core/plugin/PrettyFormatterStepDefinition.java
@@ -0,0 +1,66 @@
+package io.cucumber.core.plugin;
+
+import io.cucumber.core.backend.SourceReference;
+
+import java.lang.reflect.Method;
+
+class PrettyFormatterStepDefinition {
+ SourceReference source;
+
+ PrettyFormatterStepDefinition() {
+ source = SourceReference.fromStackTraceElement(new Exception().getStackTrace()[0]);
+ }
+
+ public void one() {
+
+ }
+
+ public void two() {
+
+ }
+
+ public void three() {
+
+ }
+
+ public void oneArgument(String a) {
+
+ }
+
+ public void twoArguments(Integer a, Integer b) {
+
+ }
+
+ static SourceReference oneReference() {
+ return getSourceReference("one");
+ }
+
+ static SourceReference twoReference() {
+ return getSourceReference("two");
+ }
+
+ static SourceReference threeReference() {
+ return getSourceReference("three");
+ }
+
+ static SourceReference twoArgumentsReference() {
+ return getSourceReference("twoArguments", Integer.class, Integer.class);
+ }
+
+ static SourceReference oneArgumentsReference() {
+ return getSourceReference("oneArgument", String.class);
+ }
+
+ private static SourceReference getSourceReference(String methodName, Class>... p) {
+ try {
+ Method method = PrettyFormatterStepDefinition.class.getMethod(methodName, p);
+ return SourceReference.fromMethod(method);
+ } catch (NoSuchMethodException e) {
+ throw new IllegalStateException(e);
+ }
+ }
+
+ static SourceReference getStackSourceReference() {
+ return new PrettyFormatterStepDefinition().source;
+ }
+}
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 c64d8549c9..dba69af43e 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
@@ -1,82 +1,27 @@
package io.cucumber.core.plugin;
-import io.cucumber.core.backend.StepDefinition;
-import io.cucumber.core.backend.StubHookDefinition;
-import io.cucumber.core.backend.StubStaticHookDefinition;
import io.cucumber.core.backend.StubStepDefinition;
-import io.cucumber.core.eventbus.EventBus;
import io.cucumber.core.feature.TestFeatureParser;
import io.cucumber.core.gherkin.Feature;
import io.cucumber.core.options.RuntimeOptionsBuilder;
import io.cucumber.core.runtime.Runtime;
import io.cucumber.core.runtime.StubBackendSupplier;
import io.cucumber.core.runtime.StubFeatureSupplier;
-import io.cucumber.core.runtime.TimeServiceEventBus;
-import io.cucumber.core.stepexpression.StepExpression;
-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;
-import java.time.Clock;
-import java.util.Locale;
-import java.util.UUID;
-import static io.cucumber.core.plugin.AnsiEscapes.GREEN;
-import static io.cucumber.core.plugin.AnsiEscapes.GREY;
-import static io.cucumber.core.plugin.AnsiEscapes.INTENSITY_BOLD;
-import static io.cucumber.core.plugin.AnsiEscapes.RED;
-import static io.cucumber.core.plugin.AnsiEscapes.RESET;
-import static io.cucumber.core.plugin.AnsiEscapes.YELLOW;
import static io.cucumber.core.plugin.Bytes.bytes;
-import static io.cucumber.core.plugin.Formats.ansi;
import static io.cucumber.core.plugin.IsEqualCompressingLineSeparators.equalCompressingLineSeparators;
-import static io.cucumber.core.runner.TestDefinitionArgument.createArguments;
-import static java.util.Arrays.asList;
-import static java.util.Collections.emptyList;
-import static java.util.Collections.singletonList;
-import static org.hamcrest.CoreMatchers.containsString;
+import static io.cucumber.core.plugin.PrettyFormatterStepDefinition.oneReference;
+import static io.cucumber.core.plugin.PrettyFormatterStepDefinition.threeReference;
+import static io.cucumber.core.plugin.PrettyFormatterStepDefinition.twoReference;
import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.core.IsEqual.equalTo;
-import static org.junit.jupiter.api.Assertions.assertThrows;
class PrettyFormatterTest {
- private final EventBus bus = new TimeServiceEventBus(Clock.systemUTC(), UUID::randomUUID);
-
- @Test
- void should_align_the_indentation_of_location_strings() {
- Feature feature = TestFeatureParser.parse("path/test.feature", "" +
- "Feature: feature name\n" +
- " Scenario: scenario name\n" +
- " Given first step\n" +
- " When second step\n" +
- " Then third step\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:3"),
- new StubStepDefinition("second step", "path/step_definitions.java:7"),
- new StubStepDefinition("third step", "path/step_definitions.java:11")))
- .build()
- .run();
-
- assertThat(out, bytes(equalCompressingLineSeparators("" +
- "\n" +
- "Scenario: scenario name # path/test.feature:2\n" +
- " Given first step # path/step_definitions.java:3\n" +
- " When second step # path/step_definitions.java:7\n" +
- " Then third step # path/step_definitions.java:11\n")));
- }
-
@Test
- void should_skip_missing_location_strings() {
+ void writes_pretty_report() {
Feature feature = TestFeatureParser.parse("path/test.feature", "" +
"Feature: feature name\n" +
" Scenario: scenario name\n" +
@@ -90,619 +35,17 @@ void should_skip_missing_location_strings() {
.withAdditionalPlugins(new PrettyFormatter(out))
.withRuntimeOptions(new RuntimeOptionsBuilder().setMonochrome().build())
.withBackendSupplier(new StubBackendSupplier(
- new StubStepDefinition("first step", "path/step_definitions.java:3"),
- new StubStepDefinition("second step", (String) null),
- new StubStepDefinition("third step", "path/step_definitions.java:11")))
- .build()
- .run();
-
- assertThat(out, bytes(equalCompressingLineSeparators("" +
- "\n" +
- "Scenario: scenario name # path/test.feature:2\n" +
- " Given first step # path/step_definitions.java:3\n" +
- " When second step\n" +
- " Then third step # path/step_definitions.java:11\n")));
- }
-
- @Test
- void should_handle_background() {
- Feature feature = TestFeatureParser.parse("path/test.feature", "" +
- "Feature: feature name\n" +
- " Background: background name\n" +
- " Given first step\n" +
- " Scenario: s1\n" +
- " Then second step\n" +
- " Scenario: s2\n" +
- " Then third step\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:3"),
- new StubStepDefinition("second step", "path/step_definitions.java:7"),
- new StubStepDefinition("third step", "path/step_definitions.java:11")))
- .build()
- .run();
-
- assertThat(out, bytes(equalCompressingLineSeparators("" +
- "\n" +
- "Scenario: s1 # path/test.feature:4\n" +
- " Given first step # path/step_definitions.java:3\n" +
- " Then second step # path/step_definitions.java:7\n" +
- "\n" +
- "Scenario: s2 # path/test.feature:6\n" +
- " Given first step # path/step_definitions.java:3\n" +
- " Then third step # path/step_definitions.java:11\n")));
- }
-
- @Test
- void should_handle_scenario_outline() {
- Feature feature = TestFeatureParser.parse("path/test.feature", "" +
- "Feature: feature name\n" +
- " Scenario Outline: \n" +
- " Given first step\n" +
- " Then step\n" +
- " Examples: examples name\n" +
- " | name | arg |\n" +
- " | name 1 | second |\n" +
- " | name 2 | third |\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:3"),
- new StubStepDefinition("second step", "path/step_definitions.java:7"),
- new StubStepDefinition("third step", "path/step_definitions.java:11")))
- .build()
- .run();
-
- assertThat(out, bytes(equalCompressingLineSeparators("" +
- "\n" +
- "Scenario Outline: name 1 # path/test.feature:7\n" +
- " Given first step # path/step_definitions.java:3\n" +
- " Then second step # path/step_definitions.java:7\n" +
- "\n" +
- "Scenario Outline: name 2 # path/test.feature:8\n" +
- " Given first step # path/step_definitions.java:3\n" +
- " Then third step # path/step_definitions.java:11\n")));
- }
-
- @Test
- void should_print_encoded_characters() {
-
- Feature feature = TestFeatureParser.parse("path/test.feature", "" +
- "Feature: Test feature\n" +
- " Scenario: Test Characters\n" +
- " Given first step\n" +
- " | URLEncoded | %71s%22i%22%3A%7B%22D |\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", DataTable.class)))
- .build()
- .run();
-
- assertThat(out, bytes(equalCompressingLineSeparators("" +
-
- "\n" +
- "Scenario: Test Characters # path/test.feature:2\n" +
- " Given first step # path/step_definitions.java:7\n" +
- " | URLEncoded | %71s%22i%22%3A%7B%22D |\n")));
- }
-
- @Test
- void should_print_tags() {
- Feature feature = TestFeatureParser.parse("path/test.feature", "" +
- "@feature_tag\n" +
- "Feature: feature name\n" +
- " @scenario_tag\n" +
- " Scenario: scenario name\n" +
- " Then first step\n" +
- " @scenario_outline_tag\n" +
- " Scenario Outline: scenario outline name\n" +
- " Then step\n" +
- " @examples_tag\n" +
- " Examples: examples name\n" +
- " | arg |\n" +
- " | second |\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"),
- new StubStepDefinition("second step", "path/step_definitions.java:11")))
- .build()
- .run();
-
- assertThat(out, bytes(equalCompressingLineSeparators("" +
-
- "\n" +
- "@feature_tag @scenario_tag\n" +
- "Scenario: scenario name # path/test.feature:4\n" +
- " Then first step # path/step_definitions.java:7\n" +
- "\n" +
- "@feature_tag @scenario_outline_tag @examples_tag\n" +
- "Scenario Outline: scenario outline name # path/test.feature:12\n" +
- " Then second step # path/step_definitions.java:11\n")));
- }
-
- @Test
- void should_print_table() {
- Feature feature = TestFeatureParser.parse("path/test.feature", "" +
- "Feature: Test feature\n" +
- " Scenario: Test Scenario\n" +
- " Given first step\n" +
- " | key1 | key2 |\n" +
- " | value1 | value2 |\n" +
- " | another1 | another2 |\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", DataTable.class)))
- .build()
- .run();
-
- assertThat(out, bytes(equalCompressingLineSeparators("" +
-
- "\n" +
- "Scenario: Test Scenario # path/test.feature:2\n" +
- " Given first step # path/step_definitions.java:7\n" +
- " | key1 | key2 |\n" +
- " | value1 | value2 |\n" +
- " | another1 | another2 |\n")));
- }
-
- @Test
- void should_print_multiple_tables() {
- Feature feature = TestFeatureParser.parse("path/test.feature", "" +
- "Feature: Test feature\n" +
- " Scenario: Test Scenario\n" +
- " Given first step\n" +
- " | key1 | key2 |\n" +
- " | value1 | value2 |\n" +
- " | another1 | another2 |\n" +
- " Given second step\n" +
- " | key3 | key4 |\n" +
- " | value3 | value4 |\n" +
- " | another3 | another4 |\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", DataTable.class),
- new StubStepDefinition("second step", "path/step_definitions.java:15", DataTable.class)))
- .build()
- .run();
-
- assertThat(out, bytes(equalCompressingLineSeparators("" +
-
- "\n" +
- "Scenario: Test Scenario # path/test.feature:2\n" +
- " Given first step # path/step_definitions.java:7\n" +
- " | key1 | key2 |\n" +
- " | value1 | value2 |\n" +
- " | another1 | another2 |\n" +
- " Given second step # path/step_definitions.java:15\n" +
- " | key3 | key4 |\n" +
- " | value3 | value4 |\n" +
- " | another3 | another4 |\n")));
- }
-
- @Test
- void should_print_error_message_for_failed_steps() {
- Feature feature = TestFeatureParser.parse("path/test.feature", "" +
- "Feature: feature name\n" +
- " Scenario: scenario name\n" +
- " Given first step\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:3",
- new StubException("the exception message")
- .withClassName()
- .withStacktrace("the stack trace"))))
- .build()
- .run();
-
- assertThat(out, bytes(equalCompressingLineSeparators("" +
- "Scenario: scenario name # path/test.feature:2\n" +
- " Given first step # path/step_definitions.java:3\n" +
- " io.cucumber.core.plugin.StubException\n" +
- " the exception message\n" +
- " \tthe stack trace\n")));
- }
-
- @Test
- void should_indent_stacktrace() {
- Feature feature = TestFeatureParser.parse("path/test.feature", "" +
- "Feature: feature name\n" +
- " Scenario: scenario name\n" +
- " Given first step\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:3",
- new StubException("the exception message")
- .withClassName()
- .withStacktrace("the stack trace"))))
- .build()
- .run();
-
- assertThat(out, bytes(equalCompressingLineSeparators("" +
- "Scenario: scenario name # path/test.feature:2\n" +
- " Given first step # path/step_definitions.java:3\n" +
- " io.cucumber.core.plugin.StubException\n" +
- " the exception message\n" +
- " \tthe stack trace\n")));
- }
-
- @Test
- void should_print_error_message_for_before_hooks() {
- Feature feature = TestFeatureParser.parse("path/test.feature", "" +
- "Feature: feature name\n" +
- " Scenario: scenario name\n" +
- " Given first step\n");
-
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- Runtime.builder()
- .withFeatureSupplier(new StubFeatureSupplier(feature))
- .withAdditionalPlugins(new PrettyFormatter(out))
- .withRuntimeOptions(new RuntimeOptionsBuilder().setMonochrome().build())
- .withBackendSupplier(new StubBackendSupplier(
- singletonList(new StubHookDefinition(new StubException("the exception message")
- .withClassName()
- .withStacktrace("the stack trace"))),
- singletonList(new StubStepDefinition("first step", "path/step_definitions.java:3")),
- emptyList()))
- .build()
- .run();
-
- assertThat(out, bytes(equalCompressingLineSeparators("" +
- "Scenario: scenario name # path/test.feature:2\n" +
- " io.cucumber.core.plugin.StubException\n" +
- " the exception message\n" +
- " \tthe stack trace\n" +
- " Given first step # path/step_definitions.java:3")));
- }
-
- @Test
- void should_print_error_message_for_after_hooks() {
- Feature feature = TestFeatureParser.parse("path/test.feature", "" +
- "Feature: feature name\n" +
- " Scenario: scenario name\n" +
- " Given first step\n");
-
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- Runtime.builder()
- .withFeatureSupplier(new StubFeatureSupplier(feature))
- .withAdditionalPlugins(new PrettyFormatter(out))
- .withRuntimeOptions(new RuntimeOptionsBuilder().setMonochrome().build())
- .withBackendSupplier(new StubBackendSupplier(
- emptyList(),
- singletonList(new StubStepDefinition("first step", "path/step_definitions.java:3")),
- singletonList(new StubHookDefinition(new StubException("the exception message")
- .withClassName()
- .withStacktrace("the stack trace")))))
- .build()
- .run();
-
- assertThat(out, bytes(equalCompressingLineSeparators("" +
- "Scenario: scenario name # path/test.feature:2\n" +
- " Given first step # path/step_definitions.java:3\n" +
- " io.cucumber.core.plugin.StubException\n" +
- " the exception message\n" +
- " \tthe stack trace\n")));
- }
-
- @Test
- void should_print_output_from_before_hooks() {
- Feature feature = TestFeatureParser.parse("path/test.feature", "" +
- "Feature: feature name\n" +
- " Scenario: scenario name\n" +
- " Given first step\n");
-
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- Runtime.builder()
- .withFeatureSupplier(new StubFeatureSupplier(feature))
- .withAdditionalPlugins(new PrettyFormatter(out))
- .withRuntimeOptions(new RuntimeOptionsBuilder().setMonochrome().build())
- .withBackendSupplier(new StubBackendSupplier(
- singletonList(new StubHookDefinition(testCaseState -> testCaseState.log("printed from hook"))),
- singletonList(new StubStepDefinition("first step", "path/step_definitions.java:3")),
- emptyList()))
+ new StubStepDefinition("first step", oneReference()),
+ new StubStepDefinition("second step", twoReference()),
+ new StubStepDefinition("third step", threeReference())))
.build()
.run();
assertThat(out, bytes(equalCompressingLineSeparators("" +
- "Scenario: scenario name # path/test.feature:2\n" +
- "\n" +
- " printed from hook\n" +
"\n" +
- " Given first step # path/step_definitions.java:3\n")));
- }
-
- @Test
- void should_print_output_from_after_hooks() {
- Feature feature = TestFeatureParser.parse("path/test.feature", "" +
- "Feature: feature name\n" +
- " Scenario: scenario name\n" +
- " Given first step\n");
-
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- Runtime.builder()
- .withFeatureSupplier(new StubFeatureSupplier(feature))
- .withAdditionalPlugins(new PrettyFormatter(out))
- .withRuntimeOptions(new RuntimeOptionsBuilder().setMonochrome().build())
- .withBackendSupplier(new StubBackendSupplier(
- emptyList(),
- singletonList(new StubStepDefinition("first step", "path/step_definitions.java:3")),
- singletonList(new StubHookDefinition(testCaseState -> testCaseState.log("printed from hook")))))
- .build()
- .run();
-
- assertThat(out, bytes(equalCompressingLineSeparators("" +
"Scenario: scenario name # path/test.feature:2\n" +
- " Given first step # path/step_definitions.java:3\n" +
- "\n" +
- " printed from hook\n")));
- }
-
- @Test
- void should_print_output_from_afterStep_hooks() {
- Feature feature = TestFeatureParser.parse("path/test.feature", "" +
- "Feature: feature name\n" +
- " Scenario: scenario name\n" +
- " Given first step\n" +
- " When second step\n");
-
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- Runtime.builder()
- .withFeatureSupplier(new StubFeatureSupplier(feature))
- .withAdditionalPlugins(new PrettyFormatter(out))
- .withRuntimeOptions(new RuntimeOptionsBuilder().setMonochrome().build())
- .withBackendSupplier(new StubBackendSupplier(
- emptyList(),
- emptyList(),
- asList(
- new StubStepDefinition("first step", "path/step_definitions.java:3"),
- new StubStepDefinition("second step", "path/step_definitions.java:4")),
- singletonList(
- new StubHookDefinition(testCaseState -> testCaseState.log("printed from afterstep hook"))),
- emptyList()))
- .build()
- .run();
-
- assertThat(out, bytes(equalCompressingLineSeparators("" +
- "Scenario: scenario name # path/test.feature:2\n" +
- " Given first step # path/step_definitions.java:3\n" +
- "\n" +
- " printed from afterstep hook\n" +
- "\n" +
- " When second step # path/step_definitions.java:4\n" +
- "\n" +
- " printed from afterstep hook" +
- "\n")));
- }
-
- @Test
- void should_color_code_steps_according_to_the_result() {
- Feature feature = TestFeatureParser.parse("path/test.feature", "" +
- "Feature: feature name\n" +
- " Scenario: scenario name\n" +
- " Given first step\n");
-
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- Runtime.builder()
- .withFeatureSupplier(new StubFeatureSupplier(feature))
- .withAdditionalPlugins(new PrettyFormatter(out))
- .withBackendSupplier(new StubBackendSupplier(
- new StubStepDefinition("first step", "path/step_definitions.java:3")))
- .build()
- .run();
-
- assertThat(out, bytes(containsString("" +
- " " + GREEN + "Given " + RESET + GREEN + "first step"
- + RESET)));
- }
-
- @Test
- void should_color_code_locations_as_comments() {
- Feature feature = TestFeatureParser.parse("path/test.feature", "" +
- "Feature: feature name\n" +
- " Scenario: scenario name\n" +
- " Given first step\n");
-
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- Runtime.builder()
- .withFeatureSupplier(new StubFeatureSupplier(feature))
- .withAdditionalPlugins(new PrettyFormatter(out))
- .withBackendSupplier(new StubBackendSupplier(
- new StubStepDefinition("first step", "path/step_definitions.java:3")))
- .build()
- .run();
-
- assertThat(out, bytes(containsString("" +
- GREY + "# path/step_definitions.java:3" + RESET)));
- }
-
- @Test
- void should_color_code_error_message_according_to_the_result() {
- Feature feature = TestFeatureParser.parse("path/test.feature", "" +
- "Feature: feature name\n" +
- " Scenario: scenario name\n" +
- " Given first step\n");
-
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- Runtime.builder()
- .withFeatureSupplier(new StubFeatureSupplier(feature))
- .withAdditionalPlugins(new PrettyFormatter(out))
- .withBackendSupplier(new StubBackendSupplier(
- new StubStepDefinition("first step", "path/step_definitions.java:3",
- new StubException("the exception message")
- .withClassName()
- .withStacktrace("the stack trace"))))
- .build()
- .run();
-
- assertThat(out, bytes(equalCompressingLineSeparators("" +
- "Scenario: scenario name " + GREY + "# path/test.feature:2" + RESET + "\n" +
- " " + RED + "Given " + RESET + RED + "first step" + RESET + " " + GREY
- + "# path/step_definitions.java:3" + RESET + "\n" +
- " " + RED + "io.cucumber.core.plugin.StubException\n" +
- " the exception message\n" +
- " \tthe stack trace" + RESET + "\n")));
- }
-
- @Test
- void should_mark_subsequent_arguments_in_steps() {
- Formats formats = ansi();
-
- StepTypeRegistry registry = new StepTypeRegistry(Locale.ENGLISH);
- StepExpressionFactory stepExpressionFactory = new StepExpressionFactory(registry, bus);
- StepDefinition stepDefinition = new StubStepDefinition("text {string} text {string}", String.class);
- StepExpression expression = stepExpressionFactory.createExpression(stepDefinition);
-
- PrettyFormatter prettyFormatter = new PrettyFormatter(new ByteArrayOutputStream());
- String stepText = "text 'arg1' text 'arg2'";
- String formattedText = prettyFormatter.formatStepText("Given ", stepText, formats.get("passed"),
- formats.get("passed_arg"), createArguments(expression.match(stepText)));
-
- assertThat(formattedText, equalTo(GREEN + "Given " + RESET +
- GREEN + "text " + RESET +
- GREEN + INTENSITY_BOLD + "'arg1'" + RESET +
- GREEN + " text " + RESET +
- GREEN + INTENSITY_BOLD + "'arg2'" + RESET));
- }
-
- @Test
- void should_mark_nested_argument_as_part_of_full_argument() {
- Formats formats = ansi();
-
- StepTypeRegistry registry = new StepTypeRegistry(Locale.ENGLISH);
- StepExpressionFactory stepExpressionFactory = new StepExpressionFactory(registry, bus);
- StepDefinition stepDefinition = new StubStepDefinition("^the order is placed( and (not yet )?confirmed)?$",
- String.class);
- StepExpression expression = stepExpressionFactory.createExpression(stepDefinition);
-
- PrettyFormatter prettyFormatter = new PrettyFormatter(new ByteArrayOutputStream());
- String stepText = "the order is placed and not yet confirmed";
-
- String formattedText = prettyFormatter.formatStepText("Given ", stepText, formats.get("passed"),
- formats.get("passed_arg"), createArguments(expression.match(stepText)));
-
- assertThat(formattedText, equalTo(GREEN + "Given " + RESET +
- GREEN + "the order is placed" + RESET +
- GREEN + INTENSITY_BOLD + " and not yet confirmed" + RESET));
- }
-
- @Test
- void should_mark_nested_arguments_as_part_of_enclosing_argument() {
- Formats formats = ansi();
- PrettyFormatter prettyFormatter = new PrettyFormatter(new ByteArrayOutputStream());
- StepTypeRegistry registry = new StepTypeRegistry(Locale.ENGLISH);
- StepExpressionFactory stepExpressionFactory = new StepExpressionFactory(registry, bus);
- StepDefinition stepDefinition = new StubStepDefinition("^the order is placed( and (not( yet)? )?confirmed)?$",
- String.class);
- StepExpression expression = stepExpressionFactory.createExpression(stepDefinition);
- String stepText = "the order is placed and not yet confirmed";
- String formattedText = prettyFormatter.formatStepText("Given ", stepText, formats.get("passed"),
- formats.get("passed_arg"), createArguments(expression.match(stepText)));
-
- assertThat(formattedText, equalTo(GREEN + "Given " + RESET +
- GREEN + "the order is placed" + RESET +
- GREEN + INTENSITY_BOLD + " and not yet confirmed" + RESET));
- }
-
- @Test
- void should_print_system_failure_for_failed_hooks() {
- Feature feature = TestFeatureParser.parse("path/test.feature", "" +
- "Feature: feature name\n" +
- " Scenario: scenario name\n" +
- " Given first step\n");
-
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- assertThrows(StubException.class, () -> Runtime.builder()
- .withFeatureSupplier(new StubFeatureSupplier(feature))
- .withAdditionalPlugins(new PrettyFormatter(out))
- .withBackendSupplier(new StubBackendSupplier(
- emptyList(),
- emptyList(),
- emptyList(),
- emptyList(),
- emptyList(),
- emptyList(),
- singletonList(new StubStaticHookDefinition(new StubException("Hook failed")
- .withClassName()
- .withStacktrace("the stack trace")))))
- .build()
- .run());
-
- assertThat(out, bytes(equalCompressingLineSeparators("" +
- "Scenario: scenario name " + GREY + "# path/test.feature:2" + RESET + "\n" +
- " " + YELLOW + "Given " + RESET + YELLOW + "first step" + RESET + "\n" +
- RED + "io.cucumber.core.plugin.StubException\n" +
- "Hook failed\n" +
- "\tthe stack trace" + RESET + "\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(equalCompressingLineSeparators("" +
- "\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")));
+ " Given first step # io.cucumber.core.plugin.PrettyFormatterStepDefinition.one()\n" +
+ " When second step # io.cucumber.core.plugin.PrettyFormatterStepDefinition.two()\n" +
+ " Then third step # io.cucumber.core.plugin.PrettyFormatterStepDefinition.three()\n")));
}
}