Skip to content

Commit 5ad094b

Browse files
authored
Emit Suggestion message (#3073)
Contributes to: cucumber/common#2272
1 parent 5076dc0 commit 5ad094b

File tree

6 files changed

+66
-20
lines changed

6 files changed

+66
-20
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
1010
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
1111

1212
## [Unreleased]
13+
### Added
14+
- [Core] Emit Suggestion message ([#3073](https://github.com/cucumber/cucumber-jvm/pull/3073) M.P. Korstanje)
15+
1316
### Fixed
1417
- [Core] Emit StepMatchArgumentsList for ambiguous steps ([#3066](https://github.com/cucumber/cucumber-jvm/pull/3066) M.P. Korstanje)
1518

cucumber-core/src/main/java/io/cucumber/core/backend/Snippet.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,21 @@
55
import java.lang.reflect.Type;
66
import java.text.MessageFormat;
77
import java.util.Map;
8+
import java.util.Optional;
89

910
@API(status = API.Status.STABLE)
1011
public interface Snippet {
1112

13+
/**
14+
* The language of the generated snippet.
15+
*
16+
* @see io.cucumber.messages.types.Snippet#getLanguage()
17+
* @return the language of the generated snippet.
18+
*/
19+
default Optional<String> language() {
20+
return Optional.empty();
21+
}
22+
1223
/**
1324
* @return a {@link java.text.MessageFormat} template used to generate a
1425
* snippet. The template can access the following variables:

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

Lines changed: 35 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,9 @@
1313
import io.cucumber.core.logging.LoggerFactory;
1414
import io.cucumber.core.snippets.SnippetGenerator;
1515
import io.cucumber.core.stepexpression.StepTypeRegistry;
16+
import io.cucumber.messages.types.Envelope;
17+
import io.cucumber.messages.types.Snippet;
1618
import io.cucumber.plugin.event.HookType;
17-
import io.cucumber.plugin.event.Location;
1819
import io.cucumber.plugin.event.SnippetsSuggestedEvent;
1920
import io.cucumber.plugin.event.SnippetsSuggestedEvent.Suggestion;
2021

@@ -26,11 +27,11 @@
2627
import java.util.Locale;
2728
import java.util.Map;
2829
import java.util.Objects;
29-
import java.util.stream.Collectors;
3030

3131
import static io.cucumber.core.exception.ExceptionUtils.throwAsUncheckedException;
3232
import static io.cucumber.core.runner.StackManipulation.removeFrameworkFrames;
3333
import static java.util.Collections.emptyList;
34+
import static java.util.stream.Collectors.toList;
3435

3536
public final class Runner {
3637

@@ -128,7 +129,7 @@ private List<SnippetGenerator> createSnippetGeneratorsForPickle(StepTypeRegistry
128129
.map(Backend::getSnippet)
129130
.filter(Objects::nonNull)
130131
.map(s -> new SnippetGenerator(s, stepTypeRegistry.parameterTypeRegistry()))
131-
.collect(Collectors.toList());
132+
.collect(toList());
132133
}
133134

134135
private void buildBackendWorlds() {
@@ -193,16 +194,28 @@ private PickleStepDefinitionMatch matchStepToStepDefinition(Pickle pickle, Step
193194
}
194195

195196
private void emitSnippetSuggestedEvent(Pickle pickle, Step step) {
196-
List<String> snippets = generateSnippetsForStep(step);
197+
List<Snippet> snippets = generateSnippetsForStep(step);
197198
if (snippets.isEmpty()) {
198199
return;
199200
}
200-
Suggestion suggestion = new Suggestion(step.getText(), snippets);
201-
Location scenarioLocation = pickle.getLocation();
202-
Location stepLocation = step.getLocation();
203-
SnippetsSuggestedEvent event = new SnippetsSuggestedEvent(bus.getInstant(), pickle.getUri(), scenarioLocation,
204-
stepLocation, suggestion);
205-
bus.send(event);
201+
202+
bus.send(new SnippetsSuggestedEvent(
203+
bus.getInstant(),
204+
pickle.getUri(),
205+
pickle.getLocation(),
206+
step.getLocation(),
207+
new Suggestion(
208+
step.getText(),
209+
snippets.stream()
210+
.map(Snippet::getCode)
211+
.collect(toList()))));
212+
213+
bus.send(
214+
Envelope.of(
215+
new io.cucumber.messages.types.Suggestion(
216+
bus.generateId().toString(),
217+
step.getId(),
218+
snippets)));
206219
}
207220

208221
private List<HookTestStep> createAfterStepHooks(List<String> tags) {
@@ -219,16 +232,18 @@ private List<HookTestStep> createTestStepsForHooks(
219232
return hooks.stream()
220233
.filter(hook -> hook.matches(tags))
221234
.map(hook -> new HookTestStep(bus.generateId(), hookType, new HookDefinitionMatch(hook)))
222-
.collect(Collectors.toList());
223-
}
224-
225-
private List<String> generateSnippetsForStep(Step step) {
226-
List<String> snippets = new ArrayList<>();
227-
for (SnippetGenerator snippetGenerator : snippetGenerators) {
228-
List<String> snippet = snippetGenerator.getSnippet(step, runnerOptions.getSnippetType());
229-
snippets.addAll(snippet);
230-
}
231-
return snippets;
235+
.collect(toList());
236+
}
237+
238+
private List<Snippet> generateSnippetsForStep(Step step) {
239+
return snippetGenerators.stream()
240+
.flatMap(generator -> {
241+
String language = generator.getLanguage().orElse("unknown");
242+
return generator.getSnippet(step, runnerOptions.getSnippetType())
243+
.stream()
244+
.map(code -> new Snippet(language, code));
245+
})
246+
.collect(toList());
232247
}
233248

234249
}

cucumber-core/src/main/java/io/cucumber/core/snippets/SnippetGenerator.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import java.util.LinkedHashMap;
1616
import java.util.List;
1717
import java.util.Map;
18+
import java.util.Optional;
1819
import java.util.regex.Pattern;
1920
import java.util.stream.Collectors;
2021
import java.util.stream.Stream;
@@ -37,6 +38,10 @@ public SnippetGenerator(Snippet snippet, ParameterTypeRegistry parameterTypeRegi
3738
this.generator = new CucumberExpressionGenerator(parameterTypeRegistry);
3839
}
3940

41+
public Optional<String> getLanguage() {
42+
return snippet.language();
43+
}
44+
4045
public List<String> getSnippet(Step step, SnippetType snippetType) {
4146
List<GeneratedExpression> generatedExpressions = generator.generateExpressions(step.getText());
4247
IdentifierGenerator functionNameGenerator = new IdentifierGenerator(snippetType.joiner());

cucumber-core/src/test/java/io/cucumber/core/snippets/TestSnippet.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,15 @@
55
import java.lang.reflect.Type;
66
import java.text.MessageFormat;
77
import java.util.Map;
8+
import java.util.Optional;
89

910
public class TestSnippet implements Snippet {
1011

12+
@Override
13+
public Optional<String> language() {
14+
return Optional.of("test");
15+
}
16+
1117
private int i;
1218

1319
@Override

cucumber-java/src/main/java/io/cucumber/java/AbstractJavaSnippet.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,17 @@
55

66
import java.lang.reflect.Type;
77
import java.util.Map;
8+
import java.util.Optional;
89

910
import static java.util.stream.Collectors.joining;
1011

1112
abstract class AbstractJavaSnippet implements Snippet {
1213

14+
@Override
15+
public Optional<String> language() {
16+
return Optional.of("java");
17+
}
18+
1319
@Override
1420
public final String tableHint() {
1521
return "" +

0 commit comments

Comments
 (0)