Skip to content

Commit

Permalink
[Core] Provide a unique id of the current scenario to the hooks.
Browse files Browse the repository at this point in the history
Provide methods to access the pickle uri and the pickle lines, which
uniquely identify the current scenario. In addition also put back the
getId() method. Even though it is not possible to provide the same id
string as when using Gherkin v2.12.2, hooks using Scenario.getId()
will still compile and still get a unique id for the scenario through
that method.
  • Loading branch information
brasmusson committed Jul 2, 2017
1 parent 9a352dc commit 268c0ef
Show file tree
Hide file tree
Showing 7 changed files with 162 additions and 6 deletions.
17 changes: 17 additions & 0 deletions core/src/main/java/cucumber/api/Scenario.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package cucumber.api;

import java.util.Collection;
import java.util.List;

/**
* Before or After Hooks that declare a parameter of this type will receive an instance of this class.
Expand Down Expand Up @@ -51,4 +52,20 @@ public interface Scenario {
* @return the name of the Scenario
*/
String getName();

/**
* @return the id of the Scenario.
*/
String getId();

/**
* @return the uri of the feature file of the Scenario.
*/
String getUri();

/**
* @return the line(s) in the feature file of the Scenario. Scenarios form Scenario Outlines
* return both the line of the example row the the line of the scenario outline.
*/
List<Integer> getLines();
}
2 changes: 1 addition & 1 deletion core/src/main/java/cucumber/api/TestCase.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public void run(EventBus bus) {
boolean skipNextStep = false;
Long startTime = bus.getTime();
bus.send(new TestCaseStarted(startTime, this));
ScenarioImpl scenarioResult = new ScenarioImpl(bus, pickleEvent.pickle);
ScenarioImpl scenarioResult = new ScenarioImpl(bus, pickleEvent);
for (TestStep step : testSteps) {
Result stepResult = step.run(bus, pickleEvent.pickle.getLanguage(), scenarioResult, skipNextStep);
if (!stepResult.is(Result.Type.PASSED)) {
Expand Down
36 changes: 33 additions & 3 deletions core/src/main/java/cucumber/runtime/ScenarioImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,14 @@
import cucumber.api.event.EmbedEvent;
import cucumber.api.event.WriteEvent;
import cucumber.runner.EventBus;
import gherkin.events.PickleEvent;
import gherkin.pickles.Pickle;
import gherkin.pickles.PickleLocation;
import gherkin.pickles.PickleTag;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
Expand All @@ -20,13 +23,25 @@ public class ScenarioImpl implements Scenario {
private static final List<Result.Type> SEVERITY = asList(Result.Type.PASSED, Result.Type.SKIPPED, Result.Type.PENDING, Result.Type.UNDEFINED, Result.Type.FAILED);
private final List<Result> stepResults = new ArrayList<Result>();
private final List<PickleTag> tags;
private final String uri;
private final String scenarioName;
private final String scenarioId;
private final List<Integer> scenarioLines;
private final EventBus bus;

public ScenarioImpl(EventBus bus, Pickle gherkinScenario) {
public ScenarioImpl(EventBus bus, PickleEvent pickleEvent) {
this.bus = bus;
this.tags = gherkinScenario.getTags();
this.scenarioName = gherkinScenario.getName();
Pickle pickle = pickleEvent.pickle;
this.tags = pickle.getTags();
this.uri = pickleEvent.uri;
this.scenarioName = pickle.getName();
List<PickleLocation> locations = pickle.getLocations();
this.scenarioId = pickleEvent.uri + ":" + Integer.toString(locations.get(0).getLine());
ArrayList<Integer> lines = new ArrayList<Integer>();
for (PickleLocation location : locations) {
lines.add(location.getLine());
}
this.scenarioLines = Collections.unmodifiableList(lines);
}

public void add(Result result) {
Expand Down Expand Up @@ -76,6 +91,21 @@ public String getName() {
return scenarioName;
}

@Override
public String getId() {
return scenarioId;
}

@Override
public String getUri() {
return uri;
}

@Override
public List<Integer> getLines() {
return scenarioLines;
}

public Throwable getError() {
Throwable error = null;
int maxPos = 0;
Expand Down
91 changes: 91 additions & 0 deletions core/src/test/java/cucumber/api/ScenarioTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
package cucumber.api;

import cucumber.runner.EventBus;
import cucumber.runtime.ScenarioImpl;
import gherkin.events.PickleEvent;
import gherkin.pickles.Pickle;
import gherkin.pickles.PickleLocation;
import org.junit.Test;

import java.util.List;

import static java.util.Arrays.asList;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

public class ScenarioTest {

@Test
public void provides_the_uri_of_the_feature_file() {
Scenario scenario = createScenarioWithFeatureFileUri(uri("path/file.feature"));

assertEquals("path/file.feature", scenario.getUri());
}

@Test
public void provides_the_scenario_line() {
List<PickleLocation> scenarioLocation = asList(new PickleLocation(line(3), column(2)));
Scenario scenario = createScenarioWithScenarioLocations(scenarioLocation);

assertEquals(asList(3), scenario.getLines());
}

@Test
public void provides_both_the_example_row_line_and_scenario_outline_line_for_scenarios_from_scenario_outlines() {
List<PickleLocation> scenarioLocation = asList(new PickleLocation(line(8), column(4)), new PickleLocation(line(3), column(2)));
Scenario scenario = createScenarioWithScenarioLocations(scenarioLocation);

assertEquals(asList(8, 3), scenario.getLines());
}

@Test
public void provides_the_uri_and_scenario_line_as_unique_id() {
List<PickleLocation> scenarioLocation = asList(new PickleLocation(line(3), column(2)));
Scenario scenario = createScenarioWithFeatureFileUriAndScenarioLocations(uri("path/file.feature"), scenarioLocation);

assertEquals("path/file.feature:3", scenario.getId());
}

@Test
public void provides_the_uri_and_example_row_line_as_unique_id_for_scenarios_from_scenario_outlines() {
List<PickleLocation> scenarioLocation = asList(new PickleLocation(line(8), column(4)), new PickleLocation(line(3), column(2)));
Scenario scenario = createScenarioWithFeatureFileUriAndScenarioLocations(uri("path/file.feature"), scenarioLocation);

assertEquals("path/file.feature:8", scenario.getId());
}

private Scenario createScenarioWithFeatureFileUri(String uri) {
return new ScenarioImpl(mock(EventBus.class), new PickleEvent(uri, mockPickle()));
}

private Scenario createScenarioWithFeatureFileUriAndScenarioLocations(String uri, List<PickleLocation> locations) {
return new ScenarioImpl(mock(EventBus.class), new PickleEvent(uri, mockPickle(locations)));
}

private Scenario createScenarioWithScenarioLocations(List<PickleLocation> locations) {
return new ScenarioImpl(mock(EventBus.class), new PickleEvent("uri", mockPickle(locations)));
}

private Pickle mockPickle() {
return mockPickle(asList(new PickleLocation(1, 1)));
}

private Pickle mockPickle(List<PickleLocation> locations) {
Pickle pickle = mock(Pickle.class);
when(pickle.getLocations()).thenReturn(locations);
return pickle;
}

private String uri(String uri) {
return uri;
}

private int line(int line) {
return line;
}

private int column(int column) {
return column;
}
}
2 changes: 2 additions & 0 deletions core/src/test/java/cucumber/api/TestCaseTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import cucumber.runner.EventBus;
import gherkin.events.PickleEvent;
import gherkin.pickles.Pickle;
import gherkin.pickles.PickleLocation;
import org.junit.Test;
import org.mockito.InOrder;

Expand Down Expand Up @@ -77,6 +78,7 @@ public void skip_steps_after_the_first_non_passed_result() throws Throwable {
private PickleEvent pickleEvent() {
Pickle pickle = mock(Pickle.class);
when(pickle.getLanguage()).thenReturn(ENGLISH);
when(pickle.getLocations()).thenReturn(Arrays.asList(new PickleLocation(1, 1)));
return new PickleEvent("uri", pickle);
}

Expand Down
13 changes: 12 additions & 1 deletion core/src/test/java/cucumber/runtime/ScenarioResultTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,25 @@
import cucumber.api.event.EmbedEvent;
import cucumber.api.event.WriteEvent;
import cucumber.runner.EventBus;
import gherkin.events.PickleEvent;
import gherkin.pickles.Pickle;
import gherkin.pickles.PickleLocation;
import org.junit.Test;
import org.mockito.ArgumentMatcher;

import static java.util.Arrays.asList;
import static org.hamcrest.CoreMatchers.sameInstance;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.mockito.Matchers.argThat;

public class ScenarioResultTest {

private EventBus bus = mock(EventBus.class);
private ScenarioImpl s = new ScenarioImpl(bus, mock(Pickle.class));
private ScenarioImpl s = new ScenarioImpl(bus, pickleEvent());

@Test
public void no_steps_is_passed() throws Exception {
Expand Down Expand Up @@ -93,6 +97,13 @@ public void pending_followed_by_failed_yields_failed_error() {

assertThat(s.getError(), sameInstance(failedError));
}

private PickleEvent pickleEvent() {
Pickle pickle = mock(Pickle.class);
when(pickle.getLocations()).thenReturn(asList(new PickleLocation(1, 1)));
PickleEvent pickleEvent = new PickleEvent("uri", pickle);
return pickleEvent;
}
}

class EmbedEventMatcher extends ArgumentMatcher<WriteEvent> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ class ScalaDslTest {
def getName = ""

def getId = ""

def getUri = ""

def getLines = null

}

@Test
Expand Down Expand Up @@ -128,7 +133,7 @@ class ScalaDslTest {

assertEquals(1, Dummy.stepDefinitions.size)
val step = Dummy.stepDefinitions.head
assertEquals("ScalaDslTest.scala:126", step.getLocation(true)) // be careful with formatting or this test will break
assertEquals("ScalaDslTest.scala:131", step.getLocation(true)) // be careful with formatting or this test will break
assertEquals("x", step.getPattern)
step.execute("en", Array())
assertTrue(called)
Expand Down

0 comments on commit 268c0ef

Please sign in to comment.