Skip to content

Commit ffc91b0

Browse files
committed
[JUnit] Deduplicate suggest snippets
Multiple undefined steps may generate the same suggested snippet. Deduplicating these makes copy paste development a little bit easier.
1 parent ef0a13a commit ffc91b0

File tree

4 files changed

+94
-15
lines changed

4 files changed

+94
-15
lines changed

junit/src/main/java/io/cucumber/junit/JUnitReporter.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
import java.net.URI;
2020
import java.util.ArrayList;
21+
import java.util.Collection;
2122
import java.util.List;
2223
import java.util.Map;
2324
import java.util.TreeMap;
@@ -29,7 +30,7 @@ final class JUnitReporter {
2930

3031
private final JUnitOptions junitOptions;
3132
private final EventBus bus;
32-
private final Map<StepLocation, List<String>> snippetsPerStep = new TreeMap<>();
33+
private final Map<StepLocation, Collection<String>> snippetsPerStep = new TreeMap<>();
3334
private final EventHandler<SnippetsSuggestedEvent> snippetsSuggestedEventEventHandler = this::handleSnippetSuggested;
3435
private List<Throwable> stepErrors;
3536
private TestNotifier stepNotifier;
@@ -125,7 +126,7 @@ private void handleStepResult(PickleStepTestStep testStep, Result result) {
125126
);
126127
break;
127128
case UNDEFINED:
128-
List<String> snippets = snippetsPerStep.remove(
129+
Collection<String> snippets = snippetsPerStep.remove(
129130
new StepLocation(testStep.getUri(), testStep.getStepLine())
130131
);
131132
stepErrors.add(new UndefinedStepException(
Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,62 @@
11
package io.cucumber.junit;
22

33
import java.util.Collection;
4-
import java.util.List;
4+
import java.util.LinkedHashSet;
5+
import java.util.Set;
6+
import java.util.stream.Collectors;
57

68
final class UndefinedStepException extends RuntimeException {
79
private static final long serialVersionUID = 1L;
810

9-
UndefinedStepException(List<String> snippets) {
11+
UndefinedStepException(Collection<String> snippets) {
1012
super(createMessage(snippets), null, false, false);
1113
}
1214

13-
private static String createMessage(List<String> snippets) {
15+
private static String createMessage(Collection<String> snippets) {
1416
StringBuilder sb = new StringBuilder("This step is undefined");
1517
appendSnippets(snippets, sb);
1618
return sb.toString();
1719
}
1820

19-
UndefinedStepException(String stepText, List<String> snippets, Collection<List<String>> otherSnippets) {
21+
UndefinedStepException(String stepText, Collection<String> snippets, Collection<Collection<String>> otherSnippets) {
2022
super(createMessage(stepText, snippets, otherSnippets), null, false, false);
2123
}
2224

23-
private static String createMessage(String stepText, List<String> snippets, Collection<List<String>> otherSnippets) {
25+
private static String createMessage(String stepText, Collection<String> snippets, Collection<Collection<String>> otherSnippets) {
26+
Set<String> otherUniqueSnippets = otherSnippets.stream()
27+
.flatMap(Collection::stream)
28+
.collect(Collectors.toCollection(LinkedHashSet::new));
29+
30+
otherUniqueSnippets.removeAll(snippets);
31+
2432
StringBuilder sb = new StringBuilder("The step \"" + stepText + "\" is undefined");
2533
appendSnippets(snippets, sb);
26-
appendOtherSnippets(otherSnippets, sb);
34+
appendOtherSnippets(otherUniqueSnippets, sb);
2735
return sb.toString();
2836
}
2937

30-
private static void appendOtherSnippets(Collection<List<String>> otherSnippets, StringBuilder sb) {
38+
private static void appendOtherSnippets(Collection<String> otherSnippets, StringBuilder sb) {
3139
if (otherSnippets.isEmpty()) {
3240
return;
3341
}
34-
3542
sb.append("\n");
3643
sb.append("\n");
3744
sb.append("Some other steps were also undefined:\n\n");
3845
otherSnippets.forEach(snippet -> {
39-
sb.append(String.join("\n", snippet));
46+
sb.append(snippet);
4047
sb.append("\n");
4148
});
4249
}
4350

44-
private static void appendSnippets(List<String> snippets, StringBuilder sb) {
51+
private static void appendSnippets(Collection<String> snippets, StringBuilder sb) {
4552
if (snippets.isEmpty()) {
4653
return;
4754
}
4855
sb.append(". You can implement it using the snippet(s) below:\n\n");
49-
sb.append(String.join("\n", snippets));
56+
snippets.forEach(snippet -> {
57+
sb.append(snippet);
58+
sb.append("\n");
59+
});
5060
}
5161

5262
}

junit/src/test/java/io/cucumber/junit/JUnitReporterWithStepNotificationsTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,7 @@ void test_step_undefined_fires_assumption_failed_and_test_finished_for_undefined
252252
assertThat(pickleFailure.getException().getMessage(), is("" +
253253
"The step \"step name\" is undefined. You can implement it using the snippet(s) below:\n" +
254254
"\n" +
255-
"some snippet"
255+
"some snippet\n"
256256
));
257257
}
258258

@@ -290,7 +290,7 @@ void test_step_undefined_fires_test_failure_and_test_finished_for_undefined_step
290290
assertThat(pickleFailure.getException().getMessage(), is("" +
291291
"The step \"step name\" is undefined. You can implement it using the snippet(s) below:\n" +
292292
"\n" +
293-
"some snippet"
293+
"some snippet\n"
294294
));
295295
}
296296

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
package io.cucumber.junit;
2+
3+
import org.junit.jupiter.api.Test;
4+
5+
import static java.util.Collections.emptyList;
6+
import static java.util.Collections.singletonList;
7+
import static org.hamcrest.MatcherAssert.assertThat;
8+
import static org.hamcrest.Matchers.is;
9+
10+
class UndefinedStepExceptionTest {
11+
12+
@Test
13+
void should_generate_a_message_for_a_single_snippet() {
14+
UndefinedStepException exception = new UndefinedStepException(singletonList("snippet"));
15+
assertThat(exception.getMessage(), is("" +
16+
"This step is undefined. You can implement it using the snippet(s) below:\n" +
17+
"\n" +
18+
"snippet\n"
19+
));
20+
}
21+
22+
@Test
23+
void should_generate_a_message_for_step_without_additional_snippets() {
24+
UndefinedStepException exception = new UndefinedStepException(
25+
"step text",
26+
singletonList("snippet"),
27+
emptyList()
28+
);
29+
assertThat(exception.getMessage(), is("" +
30+
"The step \"step text\" is undefined. You can implement it using the snippet(s) below:\n" +
31+
"\n" +
32+
"snippet\n"
33+
));
34+
}
35+
36+
@Test
37+
void should_generate_a_message_for_step_with_additional_snippets() {
38+
UndefinedStepException exception = new UndefinedStepException(
39+
"step text",
40+
singletonList("snippet"),
41+
singletonList(singletonList("additional snippet"))
42+
);
43+
assertThat(exception.getMessage(), is("" +
44+
"The step \"step text\" is undefined. You can implement it using the snippet(s) below:\n" +
45+
"\n" +
46+
"snippet\n" +
47+
"\n" +
48+
"\n" +
49+
"Some other steps were also undefined:\n" +
50+
"\n" +
51+
"additional snippet\n"
52+
));
53+
}
54+
55+
@Test
56+
void should_generate_a_message_for_step_with_additional_duplicated_snippets() {
57+
UndefinedStepException exception = new UndefinedStepException(
58+
"step text",
59+
singletonList("snippet"),
60+
singletonList(singletonList("snippet"))
61+
);
62+
assertThat(exception.getMessage(), is("" +
63+
"The step \"step text\" is undefined. You can implement it using the snippet(s) below:\n" +
64+
"\n" +
65+
"snippet\n"
66+
));
67+
}
68+
}

0 commit comments

Comments
 (0)