Skip to content

Commit 55b1f10

Browse files
committed
Merge #1160 'Provide a unique id of the current scenario to the hooks'
Aslo update History.md.
2 parents 9a352dc + 268c0ef commit 55b1f10

File tree

8 files changed

+163
-6
lines changed

8 files changed

+163
-6
lines changed

History.md

+1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
## [2.0.0-SNAPSHOT](https://github.com/cucumber/cucumber-jvm/compare/v1.2.5...master) (In Git)
22

3+
* [Core] Provide a unique id of the current scenario to the hooks. ([#1160](https://github.com/cucumber/cucumber-jvm/pull/1160) Björn Rasmusson)
34
* [Gosu] Fix and re-enable Gosu for 2.0.0 ([#1155](https://github.com/cucumber/cucumber-jvm/pull/1155), [#1086](https://github.com/cucumber/cucumber-jvm/pull/1086), [#874](https://github.com/cucumber/cucumber-jvm/pull/874) Kyle Moore, M.P. Korstanje)
45
* [Core] Fix issue where ComplexTypeWriter would create unbalanced tables. ([#1042](https://github.com/cucumber/cucumber-jvm/pull/1042) Roy Jacobs, M.P. Korstanje)
56
* [Guice] Use the ContextClassLoader when loading InjectorSource. ([#1036](https://github.com/cucumber/cucumber-jvm/pull/1036), [#1037](https://github.com/cucumber/cucumber-jvm/pull/1037) Kyle Moore)

core/src/main/java/cucumber/api/Scenario.java

+17
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package cucumber.api;
22

33
import java.util.Collection;
4+
import java.util.List;
45

56
/**
67
* Before or After Hooks that declare a parameter of this type will receive an instance of this class.
@@ -51,4 +52,20 @@ public interface Scenario {
5152
* @return the name of the Scenario
5253
*/
5354
String getName();
55+
56+
/**
57+
* @return the id of the Scenario.
58+
*/
59+
String getId();
60+
61+
/**
62+
* @return the uri of the feature file of the Scenario.
63+
*/
64+
String getUri();
65+
66+
/**
67+
* @return the line(s) in the feature file of the Scenario. Scenarios form Scenario Outlines
68+
* return both the line of the example row the the line of the scenario outline.
69+
*/
70+
List<Integer> getLines();
5471
}

core/src/main/java/cucumber/api/TestCase.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ public void run(EventBus bus) {
2323
boolean skipNextStep = false;
2424
Long startTime = bus.getTime();
2525
bus.send(new TestCaseStarted(startTime, this));
26-
ScenarioImpl scenarioResult = new ScenarioImpl(bus, pickleEvent.pickle);
26+
ScenarioImpl scenarioResult = new ScenarioImpl(bus, pickleEvent);
2727
for (TestStep step : testSteps) {
2828
Result stepResult = step.run(bus, pickleEvent.pickle.getLanguage(), scenarioResult, skipNextStep);
2929
if (!stepResult.is(Result.Type.PASSED)) {

core/src/main/java/cucumber/runtime/ScenarioImpl.java

+33-3
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,14 @@
55
import cucumber.api.event.EmbedEvent;
66
import cucumber.api.event.WriteEvent;
77
import cucumber.runner.EventBus;
8+
import gherkin.events.PickleEvent;
89
import gherkin.pickles.Pickle;
10+
import gherkin.pickles.PickleLocation;
911
import gherkin.pickles.PickleTag;
1012

1113
import java.util.ArrayList;
1214
import java.util.Collection;
15+
import java.util.Collections;
1316
import java.util.HashSet;
1417
import java.util.List;
1518
import java.util.Set;
@@ -20,13 +23,25 @@ public class ScenarioImpl implements Scenario {
2023
private static final List<Result.Type> SEVERITY = asList(Result.Type.PASSED, Result.Type.SKIPPED, Result.Type.PENDING, Result.Type.UNDEFINED, Result.Type.FAILED);
2124
private final List<Result> stepResults = new ArrayList<Result>();
2225
private final List<PickleTag> tags;
26+
private final String uri;
2327
private final String scenarioName;
28+
private final String scenarioId;
29+
private final List<Integer> scenarioLines;
2430
private final EventBus bus;
2531

26-
public ScenarioImpl(EventBus bus, Pickle gherkinScenario) {
32+
public ScenarioImpl(EventBus bus, PickleEvent pickleEvent) {
2733
this.bus = bus;
28-
this.tags = gherkinScenario.getTags();
29-
this.scenarioName = gherkinScenario.getName();
34+
Pickle pickle = pickleEvent.pickle;
35+
this.tags = pickle.getTags();
36+
this.uri = pickleEvent.uri;
37+
this.scenarioName = pickle.getName();
38+
List<PickleLocation> locations = pickle.getLocations();
39+
this.scenarioId = pickleEvent.uri + ":" + Integer.toString(locations.get(0).getLine());
40+
ArrayList<Integer> lines = new ArrayList<Integer>();
41+
for (PickleLocation location : locations) {
42+
lines.add(location.getLine());
43+
}
44+
this.scenarioLines = Collections.unmodifiableList(lines);
3045
}
3146

3247
public void add(Result result) {
@@ -76,6 +91,21 @@ public String getName() {
7691
return scenarioName;
7792
}
7893

94+
@Override
95+
public String getId() {
96+
return scenarioId;
97+
}
98+
99+
@Override
100+
public String getUri() {
101+
return uri;
102+
}
103+
104+
@Override
105+
public List<Integer> getLines() {
106+
return scenarioLines;
107+
}
108+
79109
public Throwable getError() {
80110
Throwable error = null;
81111
int maxPos = 0;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
package cucumber.api;
2+
3+
import cucumber.runner.EventBus;
4+
import cucumber.runtime.ScenarioImpl;
5+
import gherkin.events.PickleEvent;
6+
import gherkin.pickles.Pickle;
7+
import gherkin.pickles.PickleLocation;
8+
import org.junit.Test;
9+
10+
import java.util.List;
11+
12+
import static java.util.Arrays.asList;
13+
import static org.junit.Assert.assertEquals;
14+
import static org.mockito.Mockito.mock;
15+
import static org.mockito.Mockito.when;
16+
17+
public class ScenarioTest {
18+
19+
@Test
20+
public void provides_the_uri_of_the_feature_file() {
21+
Scenario scenario = createScenarioWithFeatureFileUri(uri("path/file.feature"));
22+
23+
assertEquals("path/file.feature", scenario.getUri());
24+
}
25+
26+
@Test
27+
public void provides_the_scenario_line() {
28+
List<PickleLocation> scenarioLocation = asList(new PickleLocation(line(3), column(2)));
29+
Scenario scenario = createScenarioWithScenarioLocations(scenarioLocation);
30+
31+
assertEquals(asList(3), scenario.getLines());
32+
}
33+
34+
@Test
35+
public void provides_both_the_example_row_line_and_scenario_outline_line_for_scenarios_from_scenario_outlines() {
36+
List<PickleLocation> scenarioLocation = asList(new PickleLocation(line(8), column(4)), new PickleLocation(line(3), column(2)));
37+
Scenario scenario = createScenarioWithScenarioLocations(scenarioLocation);
38+
39+
assertEquals(asList(8, 3), scenario.getLines());
40+
}
41+
42+
@Test
43+
public void provides_the_uri_and_scenario_line_as_unique_id() {
44+
List<PickleLocation> scenarioLocation = asList(new PickleLocation(line(3), column(2)));
45+
Scenario scenario = createScenarioWithFeatureFileUriAndScenarioLocations(uri("path/file.feature"), scenarioLocation);
46+
47+
assertEquals("path/file.feature:3", scenario.getId());
48+
}
49+
50+
@Test
51+
public void provides_the_uri_and_example_row_line_as_unique_id_for_scenarios_from_scenario_outlines() {
52+
List<PickleLocation> scenarioLocation = asList(new PickleLocation(line(8), column(4)), new PickleLocation(line(3), column(2)));
53+
Scenario scenario = createScenarioWithFeatureFileUriAndScenarioLocations(uri("path/file.feature"), scenarioLocation);
54+
55+
assertEquals("path/file.feature:8", scenario.getId());
56+
}
57+
58+
private Scenario createScenarioWithFeatureFileUri(String uri) {
59+
return new ScenarioImpl(mock(EventBus.class), new PickleEvent(uri, mockPickle()));
60+
}
61+
62+
private Scenario createScenarioWithFeatureFileUriAndScenarioLocations(String uri, List<PickleLocation> locations) {
63+
return new ScenarioImpl(mock(EventBus.class), new PickleEvent(uri, mockPickle(locations)));
64+
}
65+
66+
private Scenario createScenarioWithScenarioLocations(List<PickleLocation> locations) {
67+
return new ScenarioImpl(mock(EventBus.class), new PickleEvent("uri", mockPickle(locations)));
68+
}
69+
70+
private Pickle mockPickle() {
71+
return mockPickle(asList(new PickleLocation(1, 1)));
72+
}
73+
74+
private Pickle mockPickle(List<PickleLocation> locations) {
75+
Pickle pickle = mock(Pickle.class);
76+
when(pickle.getLocations()).thenReturn(locations);
77+
return pickle;
78+
}
79+
80+
private String uri(String uri) {
81+
return uri;
82+
}
83+
84+
private int line(int line) {
85+
return line;
86+
}
87+
88+
private int column(int column) {
89+
return column;
90+
}
91+
}

core/src/test/java/cucumber/api/TestCaseTest.java

+2
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import cucumber.runner.EventBus;
1010
import gherkin.events.PickleEvent;
1111
import gherkin.pickles.Pickle;
12+
import gherkin.pickles.PickleLocation;
1213
import org.junit.Test;
1314
import org.mockito.InOrder;
1415

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

core/src/test/java/cucumber/runtime/ScenarioResultTest.java

+12-1
Original file line numberDiff line numberDiff line change
@@ -4,21 +4,25 @@
44
import cucumber.api.event.EmbedEvent;
55
import cucumber.api.event.WriteEvent;
66
import cucumber.runner.EventBus;
7+
import gherkin.events.PickleEvent;
78
import gherkin.pickles.Pickle;
9+
import gherkin.pickles.PickleLocation;
810
import org.junit.Test;
911
import org.mockito.ArgumentMatcher;
1012

13+
import static java.util.Arrays.asList;
1114
import static org.hamcrest.CoreMatchers.sameInstance;
1215
import static org.junit.Assert.assertEquals;
1316
import static org.junit.Assert.assertThat;
1417
import static org.mockito.Mockito.mock;
1518
import static org.mockito.Mockito.verify;
19+
import static org.mockito.Mockito.when;
1620
import static org.mockito.Matchers.argThat;
1721

1822
public class ScenarioResultTest {
1923

2024
private EventBus bus = mock(EventBus.class);
21-
private ScenarioImpl s = new ScenarioImpl(bus, mock(Pickle.class));
25+
private ScenarioImpl s = new ScenarioImpl(bus, pickleEvent());
2226

2327
@Test
2428
public void no_steps_is_passed() throws Exception {
@@ -93,6 +97,13 @@ public void pending_followed_by_failed_yields_failed_error() {
9397

9498
assertThat(s.getError(), sameInstance(failedError));
9599
}
100+
101+
private PickleEvent pickleEvent() {
102+
Pickle pickle = mock(Pickle.class);
103+
when(pickle.getLocations()).thenReturn(asList(new PickleLocation(1, 1)));
104+
PickleEvent pickleEvent = new PickleEvent("uri", pickle);
105+
return pickleEvent;
106+
}
96107
}
97108

98109
class EmbedEventMatcher extends ArgumentMatcher<WriteEvent> {

scala/sources/src/test/scala/cucumber/api/scala/ScalaDslTest.scala

+6-1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,11 @@ class ScalaDslTest {
2222
def getName = ""
2323

2424
def getId = ""
25+
26+
def getUri = ""
27+
28+
def getLines = null
29+
2530
}
2631

2732
@Test
@@ -128,7 +133,7 @@ class ScalaDslTest {
128133

129134
assertEquals(1, Dummy.stepDefinitions.size)
130135
val step = Dummy.stepDefinitions.head
131-
assertEquals("ScalaDslTest.scala:126", step.getLocation(true)) // be careful with formatting or this test will break
136+
assertEquals("ScalaDslTest.scala:131", step.getLocation(true)) // be careful with formatting or this test will break
132137
assertEquals("x", step.getPattern)
133138
step.execute("en", Array())
134139
assertTrue(called)

0 commit comments

Comments
 (0)