Skip to content

Commit 4fba53c

Browse files
committed
Merge branch 'json-format-fix' of git://github.com/agattiker/cucumber-jvm into agattiker-json-format-fix
2 parents b8c6f41 + cf7ed05 commit 4fba53c

File tree

7 files changed

+510
-14
lines changed

7 files changed

+510
-14
lines changed

core/src/main/java/cucumber/runtime/formatter/JUnitFormatter.java

+24-9
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import gherkin.formatter.model.Step;
1616
import org.w3c.dom.Document;
1717
import org.w3c.dom.Element;
18+
import org.w3c.dom.Node;
1819

1920
import javax.xml.parsers.DocumentBuilderFactory;
2021
import javax.xml.parsers.ParserConfigurationException;
@@ -41,6 +42,7 @@ class JUnitFormatter implements Formatter, Reporter {
4142
private final Element rootElement;
4243

4344
private TestCase testCase;
45+
private Element root;
4446

4547
public JUnitFormatter(URL out) throws IOException {
4648
this.out = new UTF8OutputStreamWriter(new URLOutputStream(out));
@@ -61,15 +63,19 @@ public void feature(Feature feature) {
6163
@Override
6264
public void background(Background background) {
6365
testCase = new TestCase();
66+
root = testCase.createElement(doc);
6467
}
6568

6669
@Override
6770
public void scenario(Scenario scenario) {
68-
if (testCase != null) {
71+
if (testCase != null && testCase.scenario == null) {
6972
testCase.scenario = scenario;
7073
} else {
7174
testCase = new TestCase(scenario);
75+
root = testCase.createElement(doc);
7276
}
77+
testCase.writeElement(doc, root);
78+
rootElement.appendChild(root);
7379

7480
increaseAttributeValue(rootElement, "tests");
7581
}
@@ -99,10 +105,7 @@ public void done() {
99105
public void result(Result result) {
100106
testCase.results.add(result);
101107

102-
if (testCase.scenario != null && testCase.results.size() == testCase.steps.size()) {
103-
rootElement.appendChild(testCase.writeTo(doc));
104-
testCase = null;
105-
}
108+
testCase.updateElement(doc, root);
106109
}
107110

108111
@Override
@@ -187,10 +190,16 @@ private TestCase() {
187190
final List<Step> steps = new ArrayList<Step>();
188191
final List<Result> results = new ArrayList<Result>();
189192

190-
private Element writeTo(Document doc) {
191-
Element tc = doc.createElement("testcase");
193+
private Element createElement(Document doc) {
194+
return doc.createElement("testcase");
195+
}
196+
197+
private void writeElement(Document doc, Element tc) {
192198
tc.setAttribute("classname", feature.getName());
193199
tc.setAttribute("name", examples > 0 ? scenario.getName() + "_" + examples-- : scenario.getName());
200+
}
201+
202+
public void updateElement(Document doc, Element tc) {
194203
long totalDurationNanos = 0;
195204
for (Result r : results) {
196205
totalDurationNanos += r.getDuration() == null ? 0 : r.getDuration();
@@ -229,9 +238,15 @@ private Element writeTo(Document doc) {
229238
child = doc.createElement("system-out");
230239
child.appendChild(doc.createCDATASection(sb.toString()));
231240
}
232-
tc.appendChild(child);
233-
return tc;
241+
242+
Node existingChild = tc.getFirstChild();
243+
if (existingChild == null) {
244+
tc.appendChild(child);
245+
} else {
246+
tc.replaceChild(child, existingChild);
247+
}
234248
}
249+
235250
}
236251

237252
}

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

+2-2
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ public void run(Formatter formatter, Reporter reporter, Runtime runtime) {
3333

3434
runBackground(formatter, reporter, runtime);
3535
format(formatter);
36-
runSteps(reporter, runtime);
36+
runSteps(formatter, reporter, runtime);
3737

3838
runtime.runAfterHooks(reporter, tagsAndInheritedTags());
3939
runtime.disposeBackendWorlds();
@@ -42,7 +42,7 @@ public void run(Formatter formatter, Reporter reporter, Runtime runtime) {
4242
private void runBackground(Formatter formatter, Reporter reporter, Runtime runtime) {
4343
if (cucumberBackground != null) {
4444
cucumberBackground.format(formatter);
45-
cucumberBackground.runSteps(reporter, runtime);
45+
cucumberBackground.runSteps(formatter, reporter, runtime);
4646
}
4747
}
4848
}

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

+1
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ public List<CucumberExamples> getCucumberExamplesList() {
3838
@Override
3939
public void run(Formatter formatter, Reporter reporter, Runtime runtime) {
4040
format(formatter);
41+
formatSteps(formatter);
4142
for (CucumberExamples cucumberExamples : cucumberExamplesList) {
4243
cucumberExamples.format(formatter);
4344
List<CucumberScenario> exampleScenarios = cucumberExamples.createExampleScenarios();

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

+7-3
Original file line numberDiff line numberDiff line change
@@ -30,18 +30,22 @@ public void step(Step step) {
3030

3131
void format(Formatter formatter) {
3232
statement.replay(formatter);
33+
}
34+
35+
void formatSteps(Formatter formatter) {
3336
for (Step step : getSteps()) {
3437
formatter.step(step);
3538
}
3639
}
3740

38-
void runSteps(Reporter reporter, Runtime runtime) {
41+
void runSteps(Formatter formatter, Reporter reporter, Runtime runtime) {
3942
for (Step step : getSteps()) {
40-
runStep(step, reporter, runtime);
43+
runStep(step, formatter, reporter, runtime);
4144
}
4245
}
4346

44-
void runStep(Step step, Reporter reporter, Runtime runtime) {
47+
void runStep(Step step, Formatter formatter, Reporter reporter, Runtime runtime) {
48+
formatter.step(step);
4549
runtime.runStep(cucumberFeature.getUri(), step, reporter, cucumberFeature.getI18n());
4650
}
4751
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
package cucumber.runtime.formatter;
2+
3+
import static java.util.Arrays.asList;
4+
import static org.junit.Assert.assertEquals;
5+
import static org.mockito.Matchers.any;
6+
import static org.mockito.Mockito.mock;
7+
import static org.mockito.Mockito.when;
8+
import gherkin.formatter.model.Step;
9+
10+
import java.io.File;
11+
import java.io.IOException;
12+
import java.util.ArrayList;
13+
import java.util.List;
14+
import java.util.Properties;
15+
import java.util.Scanner;
16+
17+
import org.junit.Test;
18+
19+
import cucumber.runtime.Backend;
20+
import cucumber.runtime.Runtime;
21+
import cucumber.runtime.RuntimeOptions;
22+
import cucumber.runtime.io.ClasspathResourceLoader;
23+
24+
public class JSONPrettyFormatterTest {
25+
26+
@Test
27+
public void featureWithOutlineTest() throws Exception {
28+
File report = runFeaturesWithJSONPrettyFormatter(asList("cucumber/runtime/formatter/JSONPrettyFormatterTest.feature"));
29+
String expected = new Scanner(getClass().getResourceAsStream("JSONPrettyFormatterTest.json"), "UTF-8").useDelimiter("\\A").next();
30+
expected = expected.replace("cucumber/runtime/formatter/JSONPrettyFormatterTest.feature", "cucumber" + File.separator + "runtime"
31+
+ File.separator + "formatter" + File.separator + "JSONPrettyFormatterTest.feature");
32+
String actual = new Scanner(report, "UTF-8").useDelimiter("\\A").next();
33+
assertEquals(expected, actual);
34+
}
35+
36+
private File runFeaturesWithJSONPrettyFormatter(final List<String> featurePaths) throws IOException {
37+
File report = File.createTempFile("cucumber-jvm-junit", ".json");
38+
final ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
39+
final ClasspathResourceLoader resourceLoader = new ClasspathResourceLoader(classLoader);
40+
41+
List<String> args = new ArrayList<String>();
42+
args.add("--format");
43+
args.add("json-pretty:" + report.getAbsolutePath());
44+
args.addAll(featurePaths);
45+
46+
RuntimeOptions runtimeOptions = new RuntimeOptions(new Properties(), args.toArray(new String[args.size()]));
47+
Backend backend = mock(Backend.class);
48+
when(backend.getSnippet(any(Step.class))).thenReturn("TEST SNIPPET");
49+
final cucumber.runtime.Runtime runtime = new Runtime(resourceLoader, classLoader, asList(backend), runtimeOptions);
50+
runtime.run();
51+
return report;
52+
}
53+
54+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
Feature: Feature_3
2+
3+
Background:
4+
Given bg_1
5+
When bg_2
6+
Then bg_3
7+
8+
Scenario: Scenario_1
9+
Given step_1
10+
When step_2
11+
Then step_3
12+
Then cliché
13+
14+
Scenario Outline: ScenarioOutline_1
15+
Given so_1 <a>
16+
When so_2 <c> cucumbers
17+
Then <b> so_3
18+
19+
Examples:
20+
| a | b | c |
21+
| 12 | 5 | 7 |
22+
| 20 | 5 | 15 |
23+
24+
Scenario: Scenario_2
25+
Given a
26+
Then b
27+
When c
28+

0 commit comments

Comments
 (0)