Skip to content

Commit

Permalink
Make the Rerun formatter consistent with the exit code
Browse files Browse the repository at this point in the history
The exit code is zero => the Rerun formatter output is empty
The exit code is non-zero => the Rerun formatter output is not empty
  • Loading branch information
brasmusson committed May 31, 2015
1 parent 68fcd5e commit f059eb5
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 20 deletions.
22 changes: 14 additions & 8 deletions core/src/main/java/cucumber/runtime/formatter/RerunFormatter.java
Expand Up @@ -12,8 +12,8 @@
import gherkin.formatter.model.ScenarioOutline;
import gherkin.formatter.model.Step;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
Expand All @@ -23,12 +23,13 @@
* Formatter for reporting all failed features and print their locations
* Failed means: (failed, undefined, pending) test result
*/
class RerunFormatter implements Formatter, Reporter {
class RerunFormatter implements Formatter, Reporter, StrictAware {
private final NiceAppendable out;
private String featureLocation;
private Scenario scenario;
private boolean isTestFailed = false;
private Map<String, LinkedHashSet<Integer>> featureAndFailedLinesMapping = new HashMap<String, LinkedHashSet<Integer>>();
private Map<String, ArrayList<Integer>> featureAndFailedLinesMapping = new HashMap<String, ArrayList<Integer>>();
private boolean isStrict = false;

public RerunFormatter(Appendable out) {
this.out = new NiceAppendable(out);
Expand Down Expand Up @@ -78,9 +79,9 @@ public void done() {
}

private void reportFailedScenarios() {
Set<Map.Entry<String, LinkedHashSet<Integer>>> entries = featureAndFailedLinesMapping.entrySet();
Set<Map.Entry<String, ArrayList<Integer>>> entries = featureAndFailedLinesMapping.entrySet();
boolean firstFeature = true;
for (Map.Entry<String, LinkedHashSet<Integer>> entry : entries) {
for (Map.Entry<String, ArrayList<Integer>> entry : entries) {
if (entry.getValue().size() > 0) {
if (!firstFeature) {
out.append(" ");
Expand Down Expand Up @@ -127,13 +128,13 @@ public void result(Result result) {

private boolean isTestFailed(Result result) {
String status = result.getStatus();
return Result.FAILED.equals(status) || Result.UNDEFINED.getStatus().equals(status) || "pending".equals(status);
return Result.FAILED.equals(status) || isStrict && (Result.UNDEFINED.getStatus().equals(status) || "pending".equals(status));
}

private void recordTestFailed() {
LinkedHashSet<Integer> failedScenarios = this.featureAndFailedLinesMapping.get(featureLocation);
ArrayList<Integer> failedScenarios = this.featureAndFailedLinesMapping.get(featureLocation);
if (failedScenarios == null) {
failedScenarios = new LinkedHashSet<Integer>();
failedScenarios = new ArrayList<Integer>();
this.featureAndFailedLinesMapping.put(featureLocation, failedScenarios);
}

Expand All @@ -158,4 +159,9 @@ public void embedding(String mimeType, byte[] data) {
@Override
public void write(String text) {
}

@Override
public void setStrict(boolean strict) {
isStrict = strict;
}
}
Expand Up @@ -19,23 +19,45 @@
public class RerunFormatterTest {

@Test
public void should_leave_report_empty_when_no_scenario_fails() throws Throwable {
public void should_leave_report_empty_when_exit_code_is_zero() throws Throwable {
CucumberFeature feature = TestHelper.feature("path/test.feature", "" +
"Feature: feature name\n" +
" Scenario: scenario name\n" +
" Given first step\n" +
" When second step\n" +
" Then third step\n");
" Scenario: passed scenario\n" +
" Given passed step\n" +
" Scenario: pending scenario\n" +
" Given pending step\n" +
" Scenario: undefined scenario\n" +
" Given undefined step\n");
Map<String, Result> stepsToResult = new HashMap<String, Result>();
stepsToResult.put("first step", result("passed"));
stepsToResult.put("second step", result("passed"));
stepsToResult.put("third step", result("passed"));
stepsToResult.put("passed step", result("passed"));
stepsToResult.put("pending step", result("pending"));
stepsToResult.put("undefined step", result("undefined"));

String formatterOutput = runFeatureWithRerunFormatter(feature, stepsToResult);

assertEquals("", formatterOutput);
}

@Test
public void should_put_data_in_report_when_exit_code_is_non_zero() throws Throwable {
CucumberFeature feature = TestHelper.feature("path/test.feature", "" +
"Feature: feature name\n" +
" Scenario: failed scenario\n" +
" Given failed step\n" +
" Scenario: pending scenario\n" +
" Given pending step\n" +
" Scenario: undefined scenario\n" +
" Given undefined step\n");
Map<String, Result> stepsToResult = new HashMap<String, Result>();
stepsToResult.put("failed step", result("failed"));
stepsToResult.put("pending step", result("pending"));
stepsToResult.put("undefined step", result("undefined"));

String formatterOutput = runFeatureWithRerunFormatter(feature, stepsToResult, strict(true));

assertEquals("path/test.feature:2:4:6", formatterOutput);
}

@Test
public void should_use_scenario_location_when_scenario_step_fails() throws Throwable {
CucumberFeature feature = TestHelper.feature("path/test.feature", "" +
Expand Down Expand Up @@ -180,26 +202,42 @@ public void should_one_entry_for_each_failing_feature() throws Throwable {

private String runFeatureWithRerunFormatter(final CucumberFeature feature, final Map<String, Result> stepsToResult)
throws Throwable {
return runFeatureWithRerunFormatter(feature, stepsToResult, Collections.<SimpleEntry<String, Result>>emptyList());
return runFeatureWithRerunFormatter(feature, stepsToResult, Collections.<SimpleEntry<String, Result>>emptyList(), false);
}

private String runFeatureWithRerunFormatter(final CucumberFeature feature, final Map<String, Result> stepsToResult, boolean isStrict)
throws Throwable {
return runFeatureWithRerunFormatter(feature, stepsToResult, Collections.<SimpleEntry<String, Result>>emptyList(), isStrict);
}

private String runFeatureWithRerunFormatter(final CucumberFeature feature, final Map<String, Result> stepsToResult,
final List<SimpleEntry<String, Result>> hooks) throws Throwable {
return runFeaturesWithRerunFormatter(Arrays.asList(feature), stepsToResult, hooks);
return runFeaturesWithRerunFormatter(Arrays.asList(feature), stepsToResult, hooks, strict(false));
}

private String runFeatureWithRerunFormatter(final CucumberFeature feature, final Map<String, Result> stepsToResult,
final List<SimpleEntry<String, Result>> hooks, boolean isStrict) throws Throwable {
return runFeaturesWithRerunFormatter(Arrays.asList(feature), stepsToResult, hooks, isStrict);
}

private String runFeaturesWithRerunFormatter(final List<CucumberFeature> features, final Map<String, Result> stepsToResult)
throws Throwable {
return runFeaturesWithRerunFormatter(features, stepsToResult, Collections.<SimpleEntry<String, Result>>emptyList());
return runFeaturesWithRerunFormatter(features, stepsToResult, Collections.<SimpleEntry<String, Result>>emptyList(), strict(false));
}

private String runFeaturesWithRerunFormatter(final List<CucumberFeature> features, final Map<String, Result> stepsToResult,
final List<SimpleEntry<String, Result>> hooks) throws Throwable {
final List<SimpleEntry<String, Result>> hooks, boolean isStrict) throws Throwable {
final StringBuffer buffer = new StringBuffer();
final RerunFormatter rerunFormatter = new RerunFormatter(buffer);
if (isStrict) {
rerunFormatter.setStrict(isStrict);
}
final long stepHookDuration = 0;
TestHelper.runFeaturesWithFormatter(features, stepsToResult, hooks, stepHookDuration, rerunFormatter, rerunFormatter);
return buffer.toString();
}

private boolean strict(boolean value) {
return value;
}
}

0 comments on commit f059eb5

Please sign in to comment.