Skip to content

Commit 82b3190

Browse files
authored
Deprecate lineage derived methods (#84)
In #76 Lineage became part of the public API. This removes the need for various queries that depend on the lineage or the lineage reducer. To ensure test coverage remains the `NamingStrategyAcceptanceTest` was added. Fixes: #82.
1 parent 46c7698 commit 82b3190

File tree

39 files changed

+243
-392
lines changed

39 files changed

+243
-392
lines changed

CHANGELOG.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,12 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
77

88
## [Unreleased]
99
### Added
10-
- Update dependency io.cucumber:messages to v29 ([#101](https://github.com/cucumber/query/pull/101))
10+
- Update dependency `io.cucumber:messages` up to v29 ([#101](https://github.com/cucumber/query/pull/101))
1111
- Added more queries to find messages by `TestCaseFinished` and `TestStepFinished` ([#77](https://github.com/cucumber/query/pull/77))
1212

13+
### Deprecated
14+
- Deprecated various lineage derived methods ([#84](https://github.com/cucumber/query/pull/84))
15+
1316
## [13.6.0] - 2025-08-11
1417
### Changed
1518
- [Java] Replace redundant concurrent hashmap with regular hashmap ([#89](https://github.com/cucumber/query/pull/89))

java/src/main/java/io/cucumber/query/Query.java

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,8 @@
4141
import java.util.List;
4242
import java.util.Map;
4343
import java.util.Map.Entry;
44-
import java.util.Objects;
4544
import java.util.Optional;
45+
import java.util.Objects;
4646
import java.util.function.BiFunction;
4747
import java.util.function.Supplier;
4848
import java.util.stream.Collectors;
@@ -128,6 +128,10 @@ public List<TestCaseFinished> findAllTestCaseFinished() {
128128
.collect(toList());
129129
}
130130

131+
/**
132+
* @deprecated {@link #findLineageBy} is public, this method can be inlined.
133+
*/
134+
@Deprecated
131135
public Map<Optional<Feature>, List<TestCaseStarted>> findAllTestCaseStartedGroupedByFeature() {
132136
return findAllTestCaseStarted()
133137
.stream()
@@ -176,6 +180,10 @@ public List<Attachment> findAttachmentsBy(TestStepFinished testStepFinished) {
176180
.collect(toList());
177181
}
178182

183+
/**
184+
* @deprecated {@link #findLineageBy} is public, this method can be inlined.
185+
*/
186+
@Deprecated
179187
public Optional<Feature> findFeatureBy(TestCaseStarted testCaseStarted) {
180188
return findLineageBy(testCaseStarted).flatMap(Lineage::feature);
181189
}
@@ -204,6 +212,10 @@ public Optional<TestStepResult> findMostSevereTestStepResultBy(TestCaseFinished
204212
.flatMap(this::findMostSevereTestStepResultBy);
205213
}
206214

215+
/**
216+
* @deprecated {@link #findLineageBy} is public, this method can be inlined.
217+
*/
218+
@Deprecated
207219
public String findNameOf(GherkinDocument element, NamingStrategy namingStrategy) {
208220
requireNonNull(element);
209221
requireNonNull(namingStrategy);
@@ -212,6 +224,10 @@ public String findNameOf(GherkinDocument element, NamingStrategy namingStrategy)
212224
.orElseThrow(createElementWasNotPartOfThisQueryObject());
213225
}
214226

227+
/**
228+
* @deprecated {@link #findLineageBy} is public, this method can be inlined.
229+
*/
230+
@Deprecated
215231
public String findNameOf(Feature element, NamingStrategy namingStrategy) {
216232
requireNonNull(element);
217233
requireNonNull(namingStrategy);
@@ -220,6 +236,10 @@ public String findNameOf(Feature element, NamingStrategy namingStrategy) {
220236
.orElseThrow(createElementWasNotPartOfThisQueryObject());
221237
}
222238

239+
/**
240+
* @deprecated {@link #findLineageBy} is public, this method can be inlined.
241+
*/
242+
@Deprecated
223243
public String findNameOf(Rule element, NamingStrategy namingStrategy) {
224244
requireNonNull(element);
225245
requireNonNull(namingStrategy);
@@ -228,6 +248,10 @@ public String findNameOf(Rule element, NamingStrategy namingStrategy) {
228248
.orElseThrow(createElementWasNotPartOfThisQueryObject());
229249
}
230250

251+
/**
252+
* @deprecated {@link #findLineageBy} is public, this method can be inlined.
253+
*/
254+
@Deprecated
231255
public String findNameOf(Scenario element, NamingStrategy namingStrategy) {
232256
requireNonNull(element);
233257
requireNonNull(namingStrategy);
@@ -236,6 +260,10 @@ public String findNameOf(Scenario element, NamingStrategy namingStrategy) {
236260
.orElseThrow(createElementWasNotPartOfThisQueryObject());
237261
}
238262

263+
/**
264+
* @deprecated {@link #findLineageBy} is public, this method can be inlined.
265+
*/
266+
@Deprecated
239267
public String findNameOf(Examples element, NamingStrategy namingStrategy) {
240268
requireNonNull(element);
241269
requireNonNull(namingStrategy);
@@ -244,6 +272,10 @@ public String findNameOf(Examples element, NamingStrategy namingStrategy) {
244272
.orElseThrow(createElementWasNotPartOfThisQueryObject());
245273
}
246274

275+
/**
276+
* @deprecated {@link #findLineageBy} is public, this method can be inlined.
277+
*/
278+
@Deprecated
247279
public String findNameOf(TableRow element, NamingStrategy namingStrategy) {
248280
requireNonNull(element);
249281
requireNonNull(namingStrategy);
@@ -252,6 +284,10 @@ public String findNameOf(TableRow element, NamingStrategy namingStrategy) {
252284
.orElseThrow(createElementWasNotPartOfThisQueryObject());
253285
}
254286

287+
/**
288+
* @deprecated {@link #findLineageBy} is public, this method can be inlined.
289+
*/
290+
@Deprecated
255291
public String findNameOf(Pickle element, NamingStrategy namingStrategy) {
256292
requireNonNull(element);
257293
requireNonNull(namingStrategy);
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
package io.cucumber.query;
2+
3+
import io.cucumber.messages.NdjsonToMessageIterable;
4+
import io.cucumber.messages.types.Envelope;
5+
import org.junit.jupiter.api.Disabled;
6+
import org.junit.jupiter.params.ParameterizedTest;
7+
import org.junit.jupiter.params.provider.MethodSource;
8+
9+
import java.io.BufferedWriter;
10+
import java.io.ByteArrayOutputStream;
11+
import java.io.IOException;
12+
import java.io.InputStream;
13+
import java.io.OutputStream;
14+
import java.io.OutputStreamWriter;
15+
import java.io.PrintWriter;
16+
import java.nio.file.Files;
17+
import java.nio.file.Path;
18+
import java.nio.file.Paths;
19+
import java.util.ArrayList;
20+
import java.util.Arrays;
21+
import java.util.LinkedHashMap;
22+
import java.util.List;
23+
import java.util.Map;
24+
import java.util.Objects;
25+
26+
import static io.cucumber.query.Jackson.OBJECT_MAPPER;
27+
import static io.cucumber.query.NamingStrategy.ExampleName.NUMBER_AND_PICKLE_IF_PARAMETERIZED;
28+
import static io.cucumber.query.NamingStrategy.ExampleName.PICKLE;
29+
import static io.cucumber.query.NamingStrategy.FeatureName.EXCLUDE;
30+
import static io.cucumber.query.NamingStrategy.Strategy.LONG;
31+
import static io.cucumber.query.NamingStrategy.Strategy.SHORT;
32+
import static java.nio.charset.StandardCharsets.UTF_8;
33+
import static java.nio.file.Files.newOutputStream;
34+
import static java.nio.file.Files.readAllBytes;
35+
import static org.assertj.core.api.Assertions.assertThat;
36+
37+
public class NamingStrategyAcceptanceTest {
38+
private static final NdjsonToMessageIterable.Deserializer deserializer = (json) -> OBJECT_MAPPER.readValue(json, Envelope.class);
39+
40+
static List<TestCase> acceptance() {
41+
Map<String, NamingStrategy> strategies = new LinkedHashMap<>();
42+
strategies.put("long", NamingStrategy.strategy(LONG).build());
43+
strategies.put("long-exclude-feature-name", NamingStrategy.strategy(LONG).featureName(EXCLUDE).build());
44+
strategies.put("long-with-pickle-name", NamingStrategy.strategy(LONG).exampleName(PICKLE).build());
45+
strategies.put("long-with-pickle-name-if-parameterized", NamingStrategy.strategy(LONG).exampleName(NUMBER_AND_PICKLE_IF_PARAMETERIZED).build());
46+
strategies.put("short", NamingStrategy.strategy(SHORT).build());
47+
48+
List<Path> sources = Arrays.asList(
49+
Paths.get("../testdata/src/minimal.ndjson"),
50+
Paths.get("../testdata/src/rules.ndjson"),
51+
Paths.get("../testdata/src/examples-tables.ndjson")
52+
);
53+
54+
List<TestCase> testCases = new ArrayList<>();
55+
sources.forEach(path ->
56+
strategies.forEach((strategyName, strategy) ->
57+
testCases.add(new TestCase(path, strategyName, strategy))));
58+
59+
return testCases;
60+
}
61+
62+
private static String writeResults(TestCase testCase, NamingStrategy strategy) throws IOException {
63+
ByteArrayOutputStream out = new ByteArrayOutputStream();
64+
writeResults(strategy, testCase, out);
65+
return new String(out.toByteArray(), UTF_8);
66+
}
67+
68+
private static void writeResults(NamingStrategy strategy, TestCase testCase, OutputStream out) throws IOException {
69+
try (InputStream in = Files.newInputStream(testCase.source)) {
70+
try (NdjsonToMessageIterable envelopes = new NdjsonToMessageIterable(in, deserializer)) {
71+
try (PrintWriter writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(out)))) {
72+
Query query = new Query();
73+
for (Envelope envelope : envelopes) {
74+
query.update(envelope);
75+
}
76+
query.findAllPickles().forEach(pickle -> {
77+
query.findLineageBy(pickle)
78+
.map(lineage -> strategy.reduce(lineage, pickle))
79+
.ifPresent(writer::println);
80+
});
81+
}
82+
83+
}
84+
}
85+
}
86+
87+
@ParameterizedTest
88+
@MethodSource("acceptance")
89+
void test(TestCase testCase) throws IOException {
90+
String actual = writeResults(testCase, testCase.strategy);
91+
String expected = new String(readAllBytes(testCase.expected), UTF_8);
92+
assertThat(actual).isEqualTo(expected);
93+
}
94+
95+
@ParameterizedTest
96+
@MethodSource("acceptance")
97+
@Disabled
98+
void updateExpectedQueryResultFiles(TestCase testCase) throws IOException {
99+
try (OutputStream out = newOutputStream(testCase.expected)) {
100+
writeResults(testCase.strategy, testCase, out);
101+
}
102+
}
103+
104+
static class TestCase {
105+
private final Path source;
106+
private final NamingStrategy strategy;
107+
private final Path expected;
108+
109+
private final String name;
110+
private final String strategyName;
111+
112+
TestCase(Path source, String strategyName, NamingStrategy strategy) {
113+
this.source = source;
114+
this.strategy = strategy;
115+
this.strategyName = strategyName;
116+
String fileName = source.getFileName().toString();
117+
this.name = fileName.substring(0, fileName.lastIndexOf(".ndjson"));
118+
this.expected = source.getParent().resolve(name + ".naming-strategy." + strategyName + ".txt");
119+
}
120+
121+
@Override
122+
public String toString() {
123+
return name + " -> " + strategyName;
124+
}
125+
126+
}
127+
128+
}

java/src/test/java/io/cucumber/query/QueryAcceptanceTest.java

Lines changed: 0 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
import io.cucumber.messages.Convertor;
55
import io.cucumber.messages.NdjsonToMessageIterable;
66
import io.cucumber.messages.types.Envelope;
7-
import io.cucumber.messages.types.Feature;
87
import io.cucumber.messages.types.Hook;
98
import io.cucumber.messages.types.Pickle;
109
import io.cucumber.messages.types.PickleStep;
@@ -38,10 +37,6 @@
3837

3938
import static com.fasterxml.jackson.core.util.DefaultIndenter.SYSTEM_LINEFEED_INSTANCE;
4039
import static io.cucumber.query.Jackson.OBJECT_MAPPER;
41-
import static io.cucumber.query.NamingStrategy.ExampleName.PICKLE;
42-
import static io.cucumber.query.NamingStrategy.FeatureName.EXCLUDE;
43-
import static io.cucumber.query.NamingStrategy.Strategy.LONG;
44-
import static io.cucumber.query.NamingStrategy.Strategy.SHORT;
4540
import static java.nio.charset.StandardCharsets.UTF_8;
4641
import static java.util.Arrays.asList;
4742
import static java.util.stream.Collectors.toList;
@@ -121,12 +116,6 @@ static Map<String, Function<Query, Object>> createQueries() {
121116
queries.put("findAllTestSteps", (query) -> query.findAllTestSteps().size());
122117
queries.put("findAllTestStepsStarted", (query) -> query.findAllTestStepsStarted().size());
123118
queries.put("findAllTestStepsFinished", (query) -> query.findAllTestStepsFinished().size());
124-
queries.put("findAllTestCaseStartedGroupedByFeature", (query) -> query.findAllTestCaseStartedGroupedByFeature()
125-
.entrySet()
126-
.stream()
127-
.map(entry -> Arrays.asList(entry.getKey().map(Feature::getName), entry.getValue().stream()
128-
.map(TestCaseStarted::getId)
129-
.collect(toList()))));
130119
queries.put("findAllTestCases", (query) -> query.findAllTestCases().size());
131120
queries.put("findAttachmentsBy", (query) -> query.findAllTestCaseStarted().stream()
132121
.map(query::findTestStepFinishedAndTestStepBy)
@@ -141,10 +130,6 @@ static Map<String, Function<Query, Object>> createQueries() {
141130
attachment.getContentEncoding()
142131
))
143132
.collect(toList()));
144-
queries.put("findFeatureBy", (query) -> query.findAllTestCaseStarted().stream()
145-
.map(query::findFeatureBy)
146-
.map(feature -> feature.map(Feature::getName))
147-
.collect(toList()));
148133
queries.put("findHookBy", (query) -> query.findAllTestSteps().stream()
149134
.map(query::findHookBy)
150135
.map(hook -> hook.map(Hook::getId))
@@ -173,27 +158,6 @@ static Map<String, Function<Query, Object>> createQueries() {
173158
return results;
174159
});
175160

176-
queries.put("findNameOf", (query) -> {
177-
Map<String, Object> results = new LinkedHashMap<>();
178-
results.put("long", query.findAllPickles().stream()
179-
.map(pickle -> query.findNameOf(pickle, NamingStrategy.strategy(LONG).build()))
180-
.collect(toList()));
181-
results.put("excludeFeatureName", query.findAllPickles().stream()
182-
.map(pickle -> query.findNameOf(pickle, NamingStrategy.strategy(LONG).featureName(EXCLUDE).build()))
183-
.collect(toList()));
184-
results.put("longPickleName", query.findAllPickles().stream()
185-
.map(pickle -> query.findNameOf(pickle, NamingStrategy.strategy(LONG).exampleName(PICKLE).build()))
186-
.collect(toList()));
187-
results.put("short", query.findAllPickles().stream()
188-
.map(pickle -> query.findNameOf(pickle, NamingStrategy.strategy(SHORT).build()))
189-
.collect(toList()));
190-
results.put("shortPickleName", query.findAllPickles().stream()
191-
.map(pickle -> query.findNameOf(pickle, NamingStrategy.strategy(SHORT).exampleName(PICKLE).build()))
192-
.collect(toList()));
193-
194-
return results;
195-
});
196-
197161
queries.put("findPickleBy", (query) -> {
198162
Map<String, Object> results = new LinkedHashMap<>();
199163
results.put("testCaseStarted", query.findAllTestCaseStarted().stream()

javascript/src/Query.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -464,6 +464,9 @@ export default class Query {
464464
)
465465
}
466466

467+
/**
468+
* @deprecated {@link #findLineageBy} is public, this method can be inlined.
469+
*/
467470
public findAllTestCaseStartedGroupedByFeature(): Map<
468471
Feature | undefined,
469472
ReadonlyArray<TestCaseStarted>
@@ -498,6 +501,9 @@ export default class Query {
498501
.filter((attachment) => attachment.testStepId === testStepFinished.testStepId)
499502
}
500503

504+
/**
505+
* @deprecated {@link #findLineageBy} is public, this method can be inlined.
506+
*/
501507
public findFeatureBy(testCaseStarted: TestCaseStarted): Feature | undefined {
502508
return this.findLineageBy(testCaseStarted)?.feature
503509
}
@@ -526,6 +532,9 @@ export default class Query {
526532
).at(-1)
527533
}
528534

535+
/**
536+
* @deprecated {@link #findLineageBy} is public, this method can be inlined.
537+
*/
529538
public findNameOf(pickle: Pickle, namingStrategy: NamingStrategy): string {
530539
const lineage = this.findLineageBy(pickle)
531540
return lineage ? namingStrategy.reduce(lineage, pickle) : pickle.name

0 commit comments

Comments
 (0)