Skip to content

Commit 44660aa

Browse files
committed
Add Scenario.source_tag_names to work with Capybara. Closes #504.
1 parent 3be4969 commit 44660aa

File tree

10 files changed

+56
-24
lines changed

10 files changed

+56
-24
lines changed

History.md

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

3+
* [Core] Added `Scenario.getSourceTagNames()`, which is needed to make Capybara work with Cucumber-JRuby ([#504](https://github.com/cucumber/cucumber-jvm/issues/504) Aslak Hellesøy)
34
* [JRuby] Tagged hooks for JRuby ([#467](https://github.com/cucumber/cucumber-jvm/issues/467) Aslak Hellesøy)
45
* [Spring] Implementation based on SpringJunit4ClassRunner. ([#448](https://github.com/cucumber/cucumber-jvm/issues/448), [#489](https://github.com/cucumber/cucumber-jvm/pull/489) Pedro Antonio Souza Viegas)
56
* [Core] Bugfix: Generated regex for ? character is incorrect. ([#494](https://github.com/cucumber/cucumber-jvm/issues/494) Aslak Hellesøy)

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

+4
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
11
package cucumber.api;
22

3+
import java.util.Collection;
4+
35
/**
46
* Before or After Hooks that declare a parameter of this type will receive an instance of this class.
57
* It allows writing text and embedding media into reports, as well as inspecting results (in an After block).
68
*/
79
public interface Scenario {
10+
Collection<String> getSourceTagNames();
11+
812
/**
913
* @return the <em>most severe</em> status of the Scenario's Steps. One of "passed", "undefined", "pending", "skipped", "failed"
1014
*/

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

+2-2
Original file line numberDiff line numberDiff line change
@@ -110,14 +110,14 @@ private void printSummary() {
110110
new SummaryPrinter(System.out).print(this);
111111
}
112112

113-
public void buildBackendWorlds(Reporter reporter) {
113+
public void buildBackendWorlds(Reporter reporter, Set<Tag> tags) {
114114
for (Backend backend : backends) {
115115
backend.buildWorld();
116116
}
117117
undefinedStepsTracker.reset();
118118
//TODO: this is the initial state of the state machine, it should not go here, but into something else
119119
skipNextStep = false;
120-
scenarioResult = new ScenarioImpl(reporter);
120+
scenarioResult = new ScenarioImpl(reporter, tags);
121121
}
122122

123123
public void disposeBackendWorlds() {

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

+17-1
Original file line numberDiff line numberDiff line change
@@ -3,25 +3,41 @@
33
import cucumber.api.Scenario;
44
import gherkin.formatter.Reporter;
55
import gherkin.formatter.model.Result;
6+
import gherkin.formatter.model.Tag;
67

78
import java.util.ArrayList;
9+
import java.util.Collection;
10+
import java.util.HashSet;
811
import java.util.List;
12+
import java.util.Set;
913

1014
import static java.util.Arrays.asList;
1115

1216
public class ScenarioImpl implements Scenario {
1317
private static final List<String> SEVERITY = asList("passed", "undefined", "pending", "skipped", "failed");
1418
private final List<Result> stepResults = new ArrayList<Result>();
1519
private final Reporter reporter;
20+
private final Set<Tag> tags;
1621

17-
public ScenarioImpl(Reporter reporter) {
22+
public ScenarioImpl(Reporter reporter, Set<Tag> tags) {
1823
this.reporter = reporter;
24+
this.tags = tags;
1925
}
2026

2127
void add(Result result) {
2228
stepResults.add(result);
2329
}
2430

31+
@Override
32+
public Collection<String> getSourceTagNames() {
33+
Set<String> result = new HashSet<String>();
34+
for (Tag tag : tags) {
35+
result.add(tag.getName());
36+
}
37+
// Has to be a List in order for JRuby to convert to Ruby Array.
38+
return new ArrayList<String>(result);
39+
}
40+
2541
@Override
2642
public String getStatus() {
2743
int pos = 0;

core/src/main/java/cucumber/runtime/model/CucumberScenario.java

+7-3
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
import gherkin.formatter.Reporter;
66
import gherkin.formatter.model.Row;
77
import gherkin.formatter.model.Scenario;
8+
import gherkin.formatter.model.Tag;
9+
10+
import java.util.Set;
811

912
public class CucumberScenario extends CucumberTagStatement {
1013
private final CucumberBackground cucumberBackground;
@@ -28,14 +31,15 @@ public CucumberBackground getCucumberBackground() {
2831
*/
2932
@Override
3033
public void run(Formatter formatter, Reporter reporter, Runtime runtime) {
31-
runtime.buildBackendWorlds(reporter);
32-
runtime.runBeforeHooks(reporter, tagsAndInheritedTags());
34+
Set<Tag> tags = tagsAndInheritedTags();
35+
runtime.buildBackendWorlds(reporter, tags);
36+
runtime.runBeforeHooks(reporter, tags);
3337

3438
runBackground(formatter, reporter, runtime);
3539
format(formatter);
3640
runSteps(formatter, reporter, runtime);
3741

38-
runtime.runAfterHooks(reporter, tagsAndInheritedTags());
42+
runtime.runAfterHooks(reporter, tags);
3943
runtime.disposeBackendWorlds();
4044
}
4145

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

+2-1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import org.mockito.Matchers;
1111

1212
import java.util.ArrayList;
13+
import java.util.Collections;
1314
import java.util.HashSet;
1415
import java.util.List;
1516
import java.util.Properties;
@@ -31,7 +32,7 @@ public void buildMockWorld() {
3132
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
3233
RuntimeOptions runtimeOptions = new RuntimeOptions(new Properties());
3334
runtime = new Runtime(mock(ResourceLoader.class), classLoader, asList(mock(Backend.class)), runtimeOptions);
34-
runtime.buildBackendWorlds(null);
35+
runtime.buildBackendWorlds(null, Collections.<Tag>emptySet());
3536
glue = runtime.getGlue();
3637
}
3738

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

+16-13
Original file line numberDiff line numberDiff line change
@@ -2,53 +2,56 @@
22

33
import gherkin.formatter.Reporter;
44
import gherkin.formatter.model.Result;
5+
import gherkin.formatter.model.Tag;
56
import org.junit.Test;
67

8+
import java.util.Collections;
9+
710
import static org.junit.Assert.assertEquals;
811
import static org.mockito.Mockito.mock;
912
import static org.mockito.Mockito.verify;
1013

1114
public class ScenarioResultTest {
1215

1316
private Reporter reporter = mock(Reporter.class);
14-
private ScenarioImpl r = new ScenarioImpl(reporter);
17+
private ScenarioImpl s = new ScenarioImpl(reporter, Collections.<Tag>emptySet());
1518

1619
@Test
1720
public void no_steps_is_passed() throws Exception {
18-
assertEquals("passed", r.getStatus());
21+
assertEquals("passed", s.getStatus());
1922
}
2023

2124
@Test
2225
public void passed_and_failed_is_passed() throws Exception {
23-
r.add(new Result("passed", 0L, null, null));
24-
r.add(new Result("failed", 0L, null, null));
25-
assertEquals("failed", r.getStatus());
26+
s.add(new Result("passed", 0L, null, null));
27+
s.add(new Result("failed", 0L, null, null));
28+
assertEquals("failed", s.getStatus());
2629
}
2730

2831
@Test
2932
public void passed_and_skipped_is_skipped_although_we_cant_have_skipped_without_undefined_or_pending() throws Exception {
30-
r.add(new Result("passed", 0L, null, null));
31-
r.add(new Result("skipped", 0L, null, null));
32-
assertEquals("skipped", r.getStatus());
33+
s.add(new Result("passed", 0L, null, null));
34+
s.add(new Result("skipped", 0L, null, null));
35+
assertEquals("skipped", s.getStatus());
3336
}
3437

3538
@Test
3639
public void undefined_and_pending_is_pending() throws Exception {
37-
r.add(new Result("undefined", 0L, null, null));
38-
r.add(new Result("pending", 0L, null, null));
39-
assertEquals("pending", r.getStatus());
40+
s.add(new Result("undefined", 0L, null, null));
41+
s.add(new Result("pending", 0L, null, null));
42+
assertEquals("pending", s.getStatus());
4043
}
4144

4245
@Test
4346
public void embeds_data() {
4447
byte[] data = new byte[]{1, 2, 3};
45-
r.embed(data, "bytes/foo");
48+
s.embed(data, "bytes/foo");
4649
verify(reporter).embedding("bytes/foo", data);
4750
}
4851

4952
@Test
5053
public void prints_output() {
51-
r.write("Hi");
54+
s.write("Hi");
5255
verify(reporter).write("Hi");
5356
}
5457
}

java/src/test/java/cucumber/runtime/java/JavaStepDefinitionTest.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ public void throws_ambiguous_when_two_matches_are_found() throws Throwable {
7070
backend.addStepDefinition(THREE_BLIND_ANIMALS.getAnnotation(Given.class), THREE_BLIND_ANIMALS);
7171

7272
Reporter reporter = mock(Reporter.class);
73-
runtime.buildBackendWorlds(reporter);
73+
runtime.buildBackendWorlds(reporter, Collections.<Tag>emptySet());
7474
Tag tag = new Tag("@foo", 0);
7575
runtime.runBeforeHooks(reporter, asSet(tag));
7676
runtime.runStep("uri", new Step(NO_COMMENTS, "Given ", "three blind mice", 1, null, null), reporter, ENGLISH);
@@ -114,7 +114,7 @@ public void embedding(String mimeType, byte[] data) {
114114
public void write(String text) {
115115
}
116116
};
117-
runtime.buildBackendWorlds(reporter);
117+
runtime.buildBackendWorlds(reporter, Collections.<Tag>emptySet());
118118
Tag tag = new Tag("@foo", 0);
119119
Set<Tag> tags = asSet(tag);
120120
runtime.runBeforeHooks(reporter, tags);

jruby/src/test/resources/cucumber/runtime/jruby/test/hooks.rb

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
require 'cucumber/api/jruby/en'
22

3-
Before('@tag') do
3+
Before('@tag') do |scenario|
44
@tagged_hook_ran = true
5+
raise "Unexpected tags" unless scenario.source_tag_names == ['@tag']
56
end
67

78
Then /^tagged hook ran$/ do

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

+3-1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ import cucumber.api.Scenario
1010
class ScalaDslTest {
1111

1212
object StubScenario extends Scenario{
13+
def getSourceTagNames = null
14+
1315
def getStatus = ""
1416

1517
def isFailed = false
@@ -125,7 +127,7 @@ class ScalaDslTest {
125127

126128
assertEquals(1, Dummy.stepDefinitions.size)
127129
val step = Dummy.stepDefinitions.head
128-
assertEquals("ScalaDslTest.scala:121", step.getLocation(true)) // be careful with formatting or this test will break
130+
assertEquals("ScalaDslTest.scala:123", step.getLocation(true)) // be careful with formatting or this test will break
129131
assertEquals("x", step.getPattern)
130132
step.execute(new I18n("en"), Array())
131133
assertTrue(called)

0 commit comments

Comments
 (0)