Skip to content

Commit 5df2263

Browse files
committed
[JUnit] Updated junit for the use of Gherkin v4.0.0.
1 parent aca512d commit 5df2263

15 files changed

+312
-806
lines changed

junit/src/main/java/cucumber/api/junit/Cucumber.java

+13-6
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package cucumber.api.junit;
22

33
import cucumber.api.CucumberOptions;
4+
import cucumber.api.event.TestRunFinished;
5+
import cucumber.api.formatter.Formatter;
46
import cucumber.runtime.ClassFinder;
57
import cucumber.runtime.Runtime;
68
import cucumber.runtime.RuntimeOptions;
@@ -21,6 +23,8 @@
2123
import java.io.IOException;
2224
import java.util.ArrayList;
2325
import java.util.List;
26+
import java.util.Map;
27+
import java.util.regex.Pattern;
2428

2529
/**
2630
* <p>
@@ -39,6 +43,7 @@ public class Cucumber extends ParentRunner<FeatureRunner> {
3943
private final JUnitReporter jUnitReporter;
4044
private final List<FeatureRunner> children = new ArrayList<FeatureRunner>();
4145
private final Runtime runtime;
46+
private final Formatter formatter;
4247

4348
/**
4449
* Constructor called by JUnit.
@@ -57,10 +62,10 @@ public Cucumber(Class clazz) throws InitializationError, IOException {
5762

5863
ResourceLoader resourceLoader = new MultiLoader(classLoader);
5964
runtime = createRuntime(resourceLoader, classLoader, runtimeOptions);
60-
65+
formatter = runtimeOptions.formatter(classLoader);
6166
final JUnitOptions junitOptions = new JUnitOptions(runtimeOptions.getJunitOptions());
62-
final List<CucumberFeature> cucumberFeatures = runtimeOptions.cucumberFeatures(resourceLoader);
63-
jUnitReporter = new JUnitReporter(runtimeOptions.reporter(classLoader), runtimeOptions.formatter(classLoader), runtimeOptions.isStrict(), junitOptions);
67+
final List<CucumberFeature> cucumberFeatures = runtimeOptions.cucumberFeatures(resourceLoader, runtime.getEventBus());
68+
jUnitReporter = new JUnitReporter(runtime.getEventBus(), runtimeOptions.isStrict(), junitOptions);
6469
addChildren(cucumberFeatures);
6570
}
6671

@@ -98,14 +103,16 @@ protected void runChild(FeatureRunner child, RunNotifier notifier) {
98103
@Override
99104
public void run(RunNotifier notifier) {
100105
super.run(notifier);
101-
jUnitReporter.done();
102-
jUnitReporter.close();
106+
runtime.getEventBus().send(new TestRunFinished());
103107
runtime.printSummary();
104108
}
105109

106110
private void addChildren(List<CucumberFeature> cucumberFeatures) throws InitializationError {
107111
for (CucumberFeature cucumberFeature : cucumberFeatures) {
108-
children.add(new FeatureRunner(cucumberFeature, runtime, jUnitReporter));
112+
FeatureRunner featureRunner = new FeatureRunner(cucumberFeature, runtime, jUnitReporter);
113+
if (!featureRunner.isEmpty()) {
114+
children.add(featureRunner);
115+
}
109116
}
110117
}
111118
}

junit/src/main/java/cucumber/runtime/junit/ExamplesRunner.java

-61
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,45 @@
11
package cucumber.runtime.junit;
22

3-
import cucumber.runtime.Runtime;
4-
import cucumber.runtime.model.CucumberScenario;
5-
import gherkin.formatter.model.Step;
3+
import cucumber.runner.Runner;
4+
import gherkin.pickles.Pickle;
5+
import gherkin.pickles.PickleStep;
66
import org.junit.runner.Description;
77
import org.junit.runner.notification.RunNotifier;
88
import org.junit.runners.ParentRunner;
99
import org.junit.runners.model.InitializationError;
1010

11-
import java.util.ArrayList;
11+
import java.io.Serializable;
1212
import java.util.HashMap;
1313
import java.util.List;
1414
import java.util.Map;
1515

1616
/**
1717
* Runs a scenario, or a "synthetic" scenario derived from an Examples row.
1818
*/
19-
public class ExecutionUnitRunner extends ParentRunner<Step> {
20-
private final Runtime runtime;
21-
private final CucumberScenario cucumberScenario;
19+
public class ExecutionUnitRunner extends ParentRunner<PickleStep> {
20+
private final Runner runner;
21+
private final Pickle pickle;
22+
private final String language;
2223
private final JUnitReporter jUnitReporter;
24+
private final Map<PickleStep, Description> stepDescriptions = new HashMap<PickleStep, Description>();
2325
private Description description;
24-
private final Map<Step, Description> stepDescriptions = new HashMap<Step, Description>();
25-
private final List<Step> runnerSteps = new ArrayList<Step>();
2626

27-
public ExecutionUnitRunner(Runtime runtime, CucumberScenario cucumberScenario, JUnitReporter jUnitReporter) throws InitializationError {
27+
public ExecutionUnitRunner(Runner runner, Pickle pickle, String language, JUnitReporter jUnitReporter) throws InitializationError {
2828
super(ExecutionUnitRunner.class);
29-
this.runtime = runtime;
30-
this.cucumberScenario = cucumberScenario;
29+
this.runner = runner;
30+
this.pickle = pickle;
31+
this.language = language;
3132
this.jUnitReporter = jUnitReporter;
3233
}
3334

34-
public List<Step> getRunnerSteps() {
35-
return runnerSteps;
36-
}
37-
3835
@Override
39-
protected List<Step> getChildren() {
40-
return cucumberScenario.getSteps();
36+
protected List<PickleStep> getChildren() {
37+
return pickle.getSteps();
4138
}
4239

4340
@Override
4441
public String getName() {
45-
String name = cucumberScenario.getVisualName();
42+
String name = pickle.getName();
4643
if (jUnitReporter.useFilenameCompatibleNames()) {
4744
return makeNameFilenameCompatible(name);
4845
} else {
@@ -53,43 +50,27 @@ public String getName() {
5350
@Override
5451
public Description getDescription() {
5552
if (description == null) {
56-
description = Description.createSuiteDescription(getName(), cucumberScenario.getGherkinModel());
57-
58-
if (cucumberScenario.getCucumberBackground() != null) {
59-
for (Step backgroundStep : cucumberScenario.getCucumberBackground().getSteps()) {
60-
// We need to make a copy of that step, so we have a unique one per scenario
61-
Step copy = new Step(
62-
backgroundStep.getComments(),
63-
backgroundStep.getKeyword(),
64-
backgroundStep.getName(),
65-
backgroundStep.getLine(),
66-
backgroundStep.getRows(),
67-
backgroundStep.getDocString()
68-
);
69-
description.addChild(describeChild(copy));
70-
runnerSteps.add(copy);
71-
}
72-
}
53+
String nameForDescription = getName().isEmpty() ? "EMPTY_NAME" : getName();
54+
description = Description.createSuiteDescription(nameForDescription, new PickleWrapper(pickle));
7355

74-
for (Step step : getChildren()) {
56+
for (PickleStep step : getChildren()) {
7557
description.addChild(describeChild(step));
76-
runnerSteps.add(step);
7758
}
7859
}
7960
return description;
8061
}
8162

8263
@Override
83-
protected Description describeChild(Step step) {
64+
protected Description describeChild(PickleStep step) {
8465
Description description = stepDescriptions.get(step);
8566
if (description == null) {
8667
String testName;
8768
if (jUnitReporter.useFilenameCompatibleNames()) {
88-
testName = makeNameFilenameCompatible(step.getKeyword() + step.getName());
69+
testName = makeNameFilenameCompatible(step.getText());
8970
} else {
90-
testName = step.getKeyword() + step.getName();
71+
testName = step.getText();
9172
}
92-
description = Description.createTestDescription(getName(), testName, step);
73+
description = Description.createTestDescription(getName(), testName, new PickleStepWrapper(step));
9374
stepDescriptions.put(step, description);
9475
}
9576
return description;
@@ -99,12 +80,12 @@ protected Description describeChild(Step step) {
9980
public void run(final RunNotifier notifier) {
10081
jUnitReporter.startExecutionUnit(this, notifier);
10182
// This causes runChild to never be called, which seems OK.
102-
cucumberScenario.run(jUnitReporter, jUnitReporter, runtime);
83+
runner.runPickle(pickle, language);
10384
jUnitReporter.finishExecutionUnit();
10485
}
10586

10687
@Override
107-
protected void runChild(Step step, RunNotifier notifier) {
88+
protected void runChild(PickleStep step, RunNotifier notifier) {
10889
// The way we override run(RunNotifier) causes this method to never be called.
10990
// Instead it happens via cucumberScenario.run(jUnitReporter, jUnitReporter, runtime);
11091
throw new UnsupportedOperationException();
@@ -115,3 +96,21 @@ private String makeNameFilenameCompatible(String name) {
11596
return name.replaceAll("[^A-Za-z0-9_]", "_");
11697
}
11798
}
99+
100+
class PickleWrapper implements Serializable {
101+
private static final long serialVersionUID = 1L;
102+
private Pickle pickle;
103+
104+
public PickleWrapper(Pickle pickle) {
105+
this.pickle = pickle;
106+
}
107+
}
108+
109+
class PickleStepWrapper implements Serializable {
110+
private static final long serialVersionUID = 1L;
111+
private PickleStep step;
112+
113+
public PickleStepWrapper(PickleStep step) {
114+
this.step = step;
115+
}
116+
}

junit/src/main/java/cucumber/runtime/junit/FeatureRunner.java

+21-25
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,9 @@
33
import cucumber.runtime.CucumberException;
44
import cucumber.runtime.Runtime;
55
import cucumber.runtime.model.CucumberFeature;
6-
import cucumber.runtime.model.CucumberScenario;
7-
import cucumber.runtime.model.CucumberScenarioOutline;
8-
import cucumber.runtime.model.CucumberTagStatement;
9-
import gherkin.formatter.model.Feature;
6+
import gherkin.ast.Feature;
7+
import gherkin.pickles.Compiler;
8+
import gherkin.pickles.Pickle;
109
import org.junit.runner.Description;
1110
import org.junit.runner.notification.RunNotifier;
1211
import org.junit.runners.ParentRunner;
@@ -19,35 +18,35 @@ public class FeatureRunner extends ParentRunner<ParentRunner> {
1918
private final List<ParentRunner> children = new ArrayList<ParentRunner>();
2019

2120
private final CucumberFeature cucumberFeature;
22-
private final Runtime runtime;
23-
private final JUnitReporter jUnitReporter;
2421
private Description description;
2522

2623
public FeatureRunner(CucumberFeature cucumberFeature, Runtime runtime, JUnitReporter jUnitReporter) throws InitializationError {
2724
super(null);
2825
this.cucumberFeature = cucumberFeature;
29-
this.runtime = runtime;
30-
this.jUnitReporter = jUnitReporter;
31-
buildFeatureElementRunners();
26+
buildFeatureElementRunners(runtime, jUnitReporter);
3227
}
3328

3429
@Override
3530
public String getName() {
36-
Feature feature = cucumberFeature.getGherkinFeature();
31+
Feature feature = cucumberFeature.getGherkinFeature().getFeature();
3732
return feature.getKeyword() + ": " + feature.getName();
3833
}
3934

4035
@Override
4136
public Description getDescription() {
4237
if (description == null) {
43-
description = Description.createSuiteDescription(getName(), cucumberFeature.getGherkinFeature());
38+
description = Description.createSuiteDescription(getName(), cucumberFeature);
4439
for (ParentRunner child : getChildren()) {
4540
description.addChild(describeChild(child));
4641
}
4742
}
4843
return description;
4944
}
5045

46+
public boolean isEmpty() {
47+
return children.isEmpty();
48+
}
49+
5150
@Override
5251
protected List<ParentRunner> getChildren() {
5352
return children;
@@ -65,24 +64,21 @@ protected void runChild(ParentRunner child, RunNotifier notifier) {
6564

6665
@Override
6766
public void run(RunNotifier notifier) {
68-
jUnitReporter.uri(cucumberFeature.getPath());
69-
jUnitReporter.feature(cucumberFeature.getGherkinFeature());
7067
super.run(notifier);
71-
jUnitReporter.eof();
7268
}
7369

74-
private void buildFeatureElementRunners() {
75-
for (CucumberTagStatement cucumberTagStatement : cucumberFeature.getFeatureElements()) {
76-
try {
77-
ParentRunner featureElementRunner;
78-
if (cucumberTagStatement instanceof CucumberScenario) {
79-
featureElementRunner = new ExecutionUnitRunner(runtime, (CucumberScenario) cucumberTagStatement, jUnitReporter);
80-
} else {
81-
featureElementRunner = new ScenarioOutlineRunner(runtime, (CucumberScenarioOutline) cucumberTagStatement, jUnitReporter);
70+
private void buildFeatureElementRunners(Runtime runtime, JUnitReporter jUnitReporter) {
71+
Compiler compiler = new Compiler();
72+
List<Pickle> pickles = compiler.compile(cucumberFeature.getGherkinFeature(), cucumberFeature.getPath());
73+
for (Pickle pickle : pickles) {
74+
if (runtime.matchesFilters(pickle)) {
75+
try {
76+
ParentRunner pickleRunner;
77+
pickleRunner = new ExecutionUnitRunner(runtime.getRunner(), pickle, cucumberFeature.getLanguage(), jUnitReporter);
78+
children.add(pickleRunner);
79+
} catch (InitializationError e) {
80+
throw new CucumberException("Failed to create scenario runner", e);
8281
}
83-
children.add(featureElementRunner);
84-
} catch (InitializationError e) {
85-
throw new CucumberException("Failed to create scenario runner", e);
8682
}
8783
}
8884
}

junit/src/main/java/cucumber/runtime/junit/JUnitOptions.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package cucumber.runtime.junit;
22

33
import cucumber.runtime.CucumberException;
4-
import gherkin.util.FixJava;
4+
import cucumber.util.FixJava;
55

66
import java.io.InputStreamReader;
77
import java.io.Reader;

0 commit comments

Comments
 (0)