Skip to content

Commit 6126dc4

Browse files
authored
[Core] Use all generated snippets (cucumber#1443)
Fixes cucumber#1433
1 parent 153ecb7 commit 6126dc4

File tree

13 files changed

+104
-46
lines changed

13 files changed

+104
-46
lines changed

core/src/main/java/cucumber/runner/Runner.java

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -65,10 +65,8 @@ private void addTestStepsForPickleSteps(List<PickleStepTestStep> testSteps, Pick
6565
if (match == null) {
6666
List<String> snippets = new ArrayList<>();
6767
for (Backend backend : backends) {
68-
String snippet = backend.getSnippet(step, "**KEYWORD**", runtimeOptions.getSnippetType().getFunctionNameGenerator());
69-
if (snippet != null) {
70-
snippets.add(snippet);
71-
}
68+
List<String> snippet = backend.getSnippet(step, "**KEYWORD**", runtimeOptions.getSnippetType().getFunctionNameGenerator());
69+
snippets.addAll(snippet);
7270
}
7371
if (!snippets.isEmpty()) {
7472
bus.send(new SnippetsSuggestedEvent(bus.getTime(), pickleEvent.uri, step.getLocations(), snippets));

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,5 +22,5 @@ public interface Backend {
2222
*/
2323
void disposeWorld();
2424

25-
String getSnippet(PickleStep step, String keyword, FunctionNameGenerator functionNameGenerator);
25+
List<String> getSnippet(PickleStep step, String keyword, FunctionNameGenerator functionNameGenerator);
2626
}

core/src/main/java/cucumber/runtime/snippets/SnippetGenerator.java

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,14 @@
1111
import io.cucumber.cucumberexpressions.ParameterTypeRegistry;
1212

1313
import java.lang.reflect.Type;
14-
import java.text.MessageFormat;
14+
import java.util.ArrayList;
1515
import java.util.LinkedHashMap;
1616
import java.util.List;
1717
import java.util.Map;
1818
import java.util.regex.Pattern;
1919

20+
import static java.text.MessageFormat.format;
21+
2022
public class SnippetGenerator {
2123
@SuppressWarnings("RegExpRedundantEscape") // Android can't parse unescaped braces.
2224
private static final ArgumentPattern[] DEFAULT_ARGUMENT_PATTERNS = new ArgumentPattern[]{
@@ -33,19 +35,23 @@ public SnippetGenerator(Snippet snippet, ParameterTypeRegistry parameterTypeRegi
3335
this.generator = new CucumberExpressionGenerator(parameterTypeRegistry);
3436
}
3537

36-
public String getSnippet(PickleStep step, String keyword, FunctionNameGenerator functionNameGenerator) {
37-
List<GeneratedExpression> expressions = generator.generateExpressions(step.getText());
38-
GeneratedExpression expression = expressions.get(0);
39-
40-
return MessageFormat.format(
41-
snippet.template(),
42-
keyword,
43-
snippet.escapePattern(expression.getSource()),
44-
functionName(expression.getSource(), functionNameGenerator),
45-
snippet.arguments(arguments(step, expression.getParameterNames(), expression.getParameterTypes())),
46-
REGEXP_HINT,
47-
!step.getArgument().isEmpty() && step.getArgument().get(0) instanceof PickleTable ? snippet.tableHint() : ""
48-
);
38+
public List<String> getSnippet(PickleStep step, String keyword, FunctionNameGenerator functionNameGenerator) {
39+
List<GeneratedExpression> generatedExpressions = generator.generateExpressions(step.getText());
40+
List<String> snippets = new ArrayList<>(generatedExpressions.size());
41+
42+
for (GeneratedExpression expression : generatedExpressions) {
43+
snippets.add(format(
44+
snippet.template(),
45+
keyword,
46+
snippet.escapePattern(expression.getSource()),
47+
functionName(expression.getSource(), functionNameGenerator),
48+
snippet.arguments(arguments(step, expression.getParameterNames(), expression.getParameterTypes())),
49+
REGEXP_HINT,
50+
!step.getArgument().isEmpty() && step.getArgument().get(0) instanceof PickleTable ? snippet.tableHint() : ""
51+
));
52+
}
53+
54+
return snippets;
4955
}
5056

5157
private String functionName(String sentence, FunctionNameGenerator functionNameGenerator) {

core/src/test/java/cucumber/runner/TestBackendSupplier.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@
77

88
import java.util.Collection;
99
import java.util.Collections;
10+
import java.util.List;
11+
12+
import static java.util.Collections.emptyList;
1013

1114
public abstract class TestBackendSupplier implements Backend, BackendSupplier {
1215

@@ -21,8 +24,8 @@ public void disposeWorld() {
2124
}
2225

2326
@Override
24-
public String getSnippet(PickleStep step, String keyword, FunctionNameGenerator functionNameGenerator) {
25-
return null;
27+
public List<String> getSnippet(PickleStep step, String keyword, FunctionNameGenerator functionNameGenerator) {
28+
return emptyList();
2629
}
2730

2831
@Override

core/src/test/java/cucumber/runner/TestRunnerSupplier.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package cucumber.runner;
22

3-
import cucumber.runner.EventBus;
43
import cucumber.runtime.Backend;
54
import cucumber.runtime.Glue;
65
import cucumber.runtime.RuntimeOptions;
@@ -10,6 +9,8 @@
109
import java.util.Collections;
1110
import java.util.List;
1211

12+
import static java.util.Collections.emptyList;
13+
1314
public class TestRunnerSupplier implements Backend, RunnerSupplier {
1415

1516
private final EventBus bus;
@@ -36,8 +37,8 @@ public void disposeWorld() {
3637
}
3738

3839
@Override
39-
public String getSnippet(PickleStep step, String keyword, FunctionNameGenerator functionNameGenerator) {
40-
return null;
40+
public List<String> getSnippet(PickleStep step, String keyword, FunctionNameGenerator functionNameGenerator) {
41+
return emptyList();
4142
}
4243

4344
@Override

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

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,11 @@
55
import gherkin.pickles.PickleStep;
66
import io.cucumber.stepexpression.TypeRegistry;
77

8+
import java.util.Collections;
89
import java.util.List;
910

11+
import static java.util.Collections.emptyList;
12+
1013
public class StubBackend implements Backend {
1114

1215
@SuppressWarnings("unused") // reflection to create backend
@@ -30,7 +33,7 @@ public void disposeWorld() {
3033
}
3134

3235
@Override
33-
public String getSnippet(PickleStep step, String keyword, FunctionNameGenerator functionNameGenerator) {
34-
return null;
36+
public List<String> getSnippet(PickleStep step, String keyword, FunctionNameGenerator functionNameGenerator) {
37+
return emptyList();
3538
}
3639
}

core/src/test/java/cucumber/runtime/formatter/JSONFormatterTest.java

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import java.io.IOException;
2222
import java.util.AbstractMap.SimpleEntry;
2323
import java.util.ArrayList;
24+
import java.util.Collections;
2425
import java.util.HashMap;
2526
import java.util.List;
2627
import java.util.Map;
@@ -30,8 +31,8 @@
3031
import static cucumber.runner.TestHelper.createWriteHookAction;
3132
import static cucumber.runner.TestHelper.result;
3233
import static java.util.Arrays.asList;
34+
import static java.util.Collections.singletonList;
3335
import static org.junit.Assert.assertThat;
34-
import static org.mockito.ArgumentMatchers.anyListOf;
3536
import static org.mockito.Mockito.mock;
3637
import static org.mockito.Mockito.when;
3738
import static uk.co.datumedge.hamcrest.json.SameJSONAs.sameJSONAs;
@@ -1148,8 +1149,8 @@ public void loadGlue(cucumber.runtime.Glue glue, List<String> gluePaths) {
11481149
}
11491150

11501151
@Override
1151-
public String getSnippet(PickleStep step, String keyword, FunctionNameGenerator functionNameGenerator) {
1152-
return "TEST SNIPPET";
1152+
public List<String> getSnippet(PickleStep step, String keyword, FunctionNameGenerator functionNameGenerator) {
1153+
return singletonList("TEST SNIPPET");
11531154
}
11541155
};
11551156
final EventBus bus = new TimeServiceEventBus(new TimeServiceStub(1234));
@@ -1184,8 +1185,8 @@ public void loadGlue(cucumber.runtime.Glue glue, List<String> gluePaths) {
11841185
}
11851186

11861187
@Override
1187-
public String getSnippet(PickleStep step, String keyword, FunctionNameGenerator functionNameGenerator) {
1188-
return "TEST SNIPPET";
1188+
public List<String> getSnippet(PickleStep step, String keyword, FunctionNameGenerator functionNameGenerator) {
1189+
return singletonList("TEST SNIPPET");
11891190
}
11901191
};
11911192
final EventBus bus = new TimeServiceEventBus(new TimeServiceStub(1234));

java/src/main/java/cucumber/runtime/java/JavaBackend.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ public void disposeWorld() {
132132
}
133133

134134
@Override
135-
public String getSnippet(PickleStep step, String keyword, FunctionNameGenerator functionNameGenerator) {
135+
public List<String> getSnippet(PickleStep step, String keyword, FunctionNameGenerator functionNameGenerator) {
136136
return snippetGenerator.getSnippet(step, keyword, functionNameGenerator);
137137
}
138138

java/src/test/java/cucumber/runtime/java/Java8SnippetTest.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import org.junit.Test;
99

1010
import java.util.Collections;
11+
import java.util.List;
1112
import java.util.Locale;
1213

1314
import static org.junit.Assert.assertEquals;
@@ -28,6 +29,7 @@ public void generatesPlainSnippet() {
2829

2930
private String snippetFor(String name) {
3031
PickleStep step = new PickleStep(name, Collections.<Argument>emptyList(), Collections.<PickleLocation>emptyList());
31-
return new SnippetGenerator(new Java8Snippet(), new ParameterTypeRegistry(Locale.ENGLISH)).getSnippet(step, GIVEN_KEYWORD, null);
32+
List<String> snippet = new SnippetGenerator(new Java8Snippet(), new ParameterTypeRegistry(Locale.ENGLISH)).getSnippet(step, GIVEN_KEYWORD, null);
33+
return StringJoiner.join("\n", snippet);
3234
}
3335
}

java/src/test/java/cucumber/runtime/java/JavaSnippetTest.java

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
import io.cucumber.cucumberexpressions.CaptureGroupTransformer;
1414
import io.cucumber.cucumberexpressions.ParameterType;
1515
import io.cucumber.cucumberexpressions.ParameterTypeRegistry;
16-
import io.cucumber.cucumberexpressions.Transformer;
1716
import io.cucumber.cucumberexpressions.TypeReference;
1817
import org.junit.Ignore;
1918
import org.junit.Test;
@@ -209,6 +208,12 @@ public String transform(String... strings) {
209208
"public void i_have_a(String docString, String docString1) {\n" +
210209
" // Write code here that turns the phrase above into concrete actions\n" +
211210
" throw new cucumber.api.PendingException();\n" +
211+
"}\n" +
212+
"\n" +
213+
"@Given(\"I have a {string}:\")\n" +
214+
"public void i_have_a(String string, String docString) {\n" +
215+
" // Write code here that turns the phrase above into concrete actions\n" +
216+
" throw new cucumber.api.PendingException();\n" +
212217
"}\n";
213218
assertEquals(expected, snippetForDocString("I have a \"Documentation String\":", new PickleString(null, "hello"), customParameterType));
214219
}
@@ -268,8 +273,18 @@ public String transform(String... strings) {
268273
" // Double, Byte, Short, Long, BigInteger or BigDecimal.\n" +
269274
" //\n" +
270275
" // For other transformations you can register a DataTableType.\n" +
271-
// " //\n" +
272-
// " // See: TODO URL\n" +
276+
" throw new cucumber.api.PendingException();\n" +
277+
"}\n" +
278+
"\n" +
279+
"@Given(\"I have in table {string}:\")\n" +
280+
"public void i_have_in_table(String string, DataTable dataTable) {\n" +
281+
" // Write code here that turns the phrase above into concrete actions\n" +
282+
" // For automatic transformation, change DataTable to one of\n" +
283+
" // E, List<E>, List<List<E>>, List<Map<K,V>>, Map<K,V> or\n" +
284+
" // Map<K, List<V>>. E,K,V must be a String, Integer, Float,\n" +
285+
" // Double, Byte, Short, Long, BigInteger or BigDecimal.\n" +
286+
" //\n" +
287+
" // For other transformations you can register a DataTableType.\n" +
273288
" throw new cucumber.api.PendingException();\n" +
274289
"}\n";
275290
PickleTable dataTable = new PickleTable(asList(new PickleRow(asList(new PickleCell(null, "col1")))));
@@ -290,42 +305,48 @@ public void generateSnippetWithOutlineParam() {
290305

291306
private String snippetFor(String name) {
292307
PickleStep step = new PickleStep(name, Collections.<Argument>emptyList(), Collections.<PickleLocation>emptyList());
293-
return new SnippetGenerator(new JavaSnippet(), new ParameterTypeRegistry(Locale.ENGLISH)).getSnippet(step, GIVEN_KEYWORD, functionNameGenerator);
308+
List<String> snippet = new SnippetGenerator(new JavaSnippet(), new ParameterTypeRegistry(Locale.ENGLISH)).getSnippet(step, GIVEN_KEYWORD, functionNameGenerator);
309+
return StringJoiner.join("\n", snippet);
294310
}
295311

296312

297313
private String snippetFor(String name, ParameterType<?> parameterType) {
298314
PickleStep step = new PickleStep(name, Collections.<Argument>emptyList(), Collections.<PickleLocation>emptyList());
299315
ParameterTypeRegistry parameterTypeRegistry = new ParameterTypeRegistry(Locale.ENGLISH);
300316
parameterTypeRegistry.defineParameterType(parameterType);
301-
return new SnippetGenerator(new JavaSnippet(), parameterTypeRegistry).getSnippet(step, GIVEN_KEYWORD, functionNameGenerator);
317+
List<String> snippet = new SnippetGenerator(new JavaSnippet(), parameterTypeRegistry).getSnippet(step, GIVEN_KEYWORD, functionNameGenerator);
318+
return StringJoiner.join("\n", snippet);
302319
}
303320

304321
private String snippetForDocString(String name, PickleString docString) {
305322
PickleStep step = new PickleStep(name, asList((Argument) docString), Collections.<PickleLocation>emptyList());
306-
return new SnippetGenerator(new JavaSnippet(), new ParameterTypeRegistry(Locale.ENGLISH)).getSnippet(step, GIVEN_KEYWORD, functionNameGenerator);
323+
List<String> snippet = new SnippetGenerator(new JavaSnippet(), new ParameterTypeRegistry(Locale.ENGLISH)).getSnippet(step, GIVEN_KEYWORD, functionNameGenerator);
324+
return StringJoiner.join("\n", snippet);
307325
}
308326

309327

310328
private String snippetForDocString(String name, PickleString docString, ParameterType<String> parameterType) {
311329
PickleStep step = new PickleStep(name, asList((Argument) docString), Collections.<PickleLocation>emptyList());
312330
ParameterTypeRegistry parameterTypeRegistry = new ParameterTypeRegistry(Locale.ENGLISH);
313331
parameterTypeRegistry.defineParameterType(parameterType);
314-
return new SnippetGenerator(new JavaSnippet(), parameterTypeRegistry).getSnippet(step, GIVEN_KEYWORD, functionNameGenerator);
332+
List<String> snippet = new SnippetGenerator(new JavaSnippet(), parameterTypeRegistry).getSnippet(step, GIVEN_KEYWORD, functionNameGenerator);
333+
return StringJoiner.join("\n", snippet);
315334
}
316335

317336

318337
private String snippetForDataTable(String name, PickleTable dataTable) {
319338
PickleStep step = new PickleStep(name, asList((Argument) dataTable), Collections.<PickleLocation>emptyList());
320-
return new SnippetGenerator(new JavaSnippet(), new ParameterTypeRegistry(Locale.ENGLISH)).getSnippet(step, GIVEN_KEYWORD, functionNameGenerator);
339+
List<String> snippet = new SnippetGenerator(new JavaSnippet(), new ParameterTypeRegistry(Locale.ENGLISH)).getSnippet(step, GIVEN_KEYWORD, functionNameGenerator);
340+
return StringJoiner.join("\n", snippet);
321341
}
322342

323343

324344
private String snippetForDataTable(String name, PickleTable dataTable, ParameterType<String> parameterType) {
325345
PickleStep step = new PickleStep(name, asList((Argument) dataTable), Collections.<PickleLocation>emptyList());
326346
ParameterTypeRegistry parameterTypeRegistry = new ParameterTypeRegistry(Locale.ENGLISH);
327347
parameterTypeRegistry.defineParameterType(parameterType);
328-
return new SnippetGenerator(new JavaSnippet(), parameterTypeRegistry).getSnippet(step, GIVEN_KEYWORD, functionNameGenerator);
348+
List<String> snippet = new SnippetGenerator(new JavaSnippet(), parameterTypeRegistry).getSnippet(step, GIVEN_KEYWORD, functionNameGenerator);
349+
return StringJoiner.join("\n", snippet);
329350
}
330351

331352
private static class Size {
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package cucumber.runtime.java;
2+
3+
public class StringJoiner {
4+
public static String join(String delimiter, Iterable<String> strings){
5+
//TODO: Java8 replace with StringJoiner.
6+
StringBuilder builder = new StringBuilder();
7+
boolean first = true;
8+
for (String string : strings) {
9+
if (first) {
10+
first = false;
11+
} else {
12+
builder.append(delimiter);
13+
}
14+
builder.append(string);
15+
}
16+
return builder.toString();
17+
}
18+
}

junit/src/test/java/cucumber/runtime/stub/StubBackend.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
import java.util.Collections;
1313
import java.util.List;
1414

15+
import static java.util.Collections.singletonList;
16+
1517
/**
1618
* We need an implementation of Backend to prevent Runtime from blowing up.
1719
*/
@@ -82,7 +84,7 @@ public void disposeWorld() {
8284
}
8385

8486
@Override
85-
public String getSnippet(PickleStep step, String keyword, FunctionNameGenerator functionNameGenerator) {
86-
return "STUB SNIPPET";
87+
public List<String> getSnippet(PickleStep step, String keyword, FunctionNameGenerator functionNameGenerator) {
88+
return singletonList("STUB SNIPPET");
8789
}
8890
}

testng/src/test/java/cucumber/runtime/stub/StubBackend.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,11 @@
77
import cucumber.runtime.snippets.FunctionNameGenerator;
88
import gherkin.pickles.PickleStep;
99

10+
import java.util.Collections;
1011
import java.util.List;
1112

13+
import static java.util.Collections.singletonList;
14+
1215
/**
1316
* We need an implementation of Backend to prevent Runtime from blowing up.
1417
*/
@@ -31,7 +34,7 @@ public void disposeWorld() {
3134
}
3235

3336
@Override
34-
public String getSnippet(PickleStep step, String keyword, FunctionNameGenerator functionNameGenerator) {
35-
return "STUB SNIPPET";
37+
public List<String> getSnippet(PickleStep step, String keyword, FunctionNameGenerator functionNameGenerator) {
38+
return singletonList("STUB SNIPPET");
3639
}
3740
}

0 commit comments

Comments
 (0)