/
ExecutionUnitRunner.java
161 lines (139 loc) · 5.41 KB
/
ExecutionUnitRunner.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
package cucumber.runtime.junit;
import cucumber.runner.Runner;
import gherkin.events.PickleEvent;
import gherkin.pickles.PickleStep;
import org.junit.runner.Description;
import org.junit.runner.notification.RunNotifier;
import org.junit.runners.ParentRunner;
import org.junit.runners.model.InitializationError;
import java.io.Serializable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Runs a scenario, or a "synthetic" scenario derived from an Examples row.
*/
class ExecutionUnitRunner extends ParentRunner<PickleStep> {
private final Runner runner;
private final PickleEvent pickleEvent;
private final JUnitReporter jUnitReporter;
private final Map<PickleStep, Description> stepDescriptions = new HashMap<PickleStep, Description>();
private Description description;
ExecutionUnitRunner(Runner runner, PickleEvent pickleEvent, JUnitReporter jUnitReporter) throws InitializationError {
super(null);
this.runner = runner;
this.pickleEvent = pickleEvent;
this.jUnitReporter = jUnitReporter;
}
@Override
protected List<PickleStep> getChildren() {
return pickleEvent.pickle.getSteps();
}
@Override
public String getName() {
String name = pickleEvent.pickle.getName();
if (jUnitReporter.useFilenameCompatibleNames()) {
return makeNameFilenameCompatible(name);
} else {
return name;
}
}
@Override
public Description getDescription() {
if (description == null) {
String nameForDescription = getName().isEmpty() ? "EMPTY_NAME" : getName();
description = Description.createSuiteDescription(nameForDescription, new PickleId(pickleEvent));
for (PickleStep step : getChildren()) {
description.addChild(describeChild(step));
}
}
return description;
}
@Override
protected Description describeChild(PickleStep step) {
Description description = stepDescriptions.get(step);
if (description == null) {
String testName;
if (jUnitReporter.useFilenameCompatibleNames()) {
testName = makeNameFilenameCompatible(step.getText());
} else {
testName = step.getText();
}
description = Description.createTestDescription(getName(), testName, new PickleStepId(pickleEvent, step));
stepDescriptions.put(step, description);
}
return description;
}
@Override
public void run(final RunNotifier notifier) {
jUnitReporter.startExecutionUnit(this, notifier);
// This causes runChild to never be called, which seems OK.
runner.runPickle(pickleEvent);
jUnitReporter.finishExecutionUnit();
}
@Override
protected void runChild(PickleStep step, RunNotifier notifier) {
// The way we override run(RunNotifier) causes this method to never be called.
// Instead it happens via cucumberScenario.run(jUnitReporter, jUnitReporter, runtime);
throw new UnsupportedOperationException();
// cucumberScenario.runStep(step, jUnitReporter, runtime);
}
private String makeNameFilenameCompatible(String name) {
return name.replaceAll("[^A-Za-z0-9_]", "_");
}
private static final class PickleId implements Serializable {
private static final long serialVersionUID = 1L;
private final String uri;
private int pickleLine;
PickleId(PickleEvent pickleEvent) {
this.uri = pickleEvent.uri;
this.pickleLine = pickleEvent.pickle.getLocations().get(0).getLine();
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
PickleId that = (PickleId) o;
return pickleLine == that.pickleLine && uri.equals(that.uri);
}
@Override
public int hashCode() {
int result = uri.hashCode();
result = 31 * result + pickleLine;
return result;
}
@Override
public String toString() {
return uri + ":" + pickleLine;
}
}
private static final class PickleStepId implements Serializable {
private static final long serialVersionUID = 1L;
private final String uri;
private final int pickleLine;
private final int pickleStepLine;
PickleStepId(PickleEvent pickleEvent, PickleStep pickleStep) {
this.uri = pickleEvent.uri;
this.pickleLine = pickleEvent.pickle.getLocations().get(0).getLine();
this.pickleStepLine = pickleStep.getLocations().get(0).getLine();
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
PickleStepId that = (PickleStepId) o;
return pickleLine == that.pickleLine && pickleStepLine == that.pickleStepLine && uri.equals(that.uri);
}
@Override
public int hashCode() {
int result = pickleLine;
result = 31 * result + uri.hashCode();
result = 31 * result + pickleStepLine;
return result;
}
@Override
public String toString() {
return uri + ":" + pickleLine + ":" + pickleStepLine;
}
}
}