diff --git a/java/.mvn/jvm.config b/java/.mvn/jvm.config new file mode 100644 index 00000000..32599cef --- /dev/null +++ b/java/.mvn/jvm.config @@ -0,0 +1,10 @@ +--add-exports jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED +--add-exports jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED +--add-exports jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED +--add-exports jdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED +--add-exports jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED +--add-exports jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED +--add-exports jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED +--add-exports jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED +--add-opens jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED +--add-opens jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED diff --git a/java/pom.xml b/java/pom.xml index 198ac544..26d3b9df 100644 --- a/java/pom.xml +++ b/java/pom.xml @@ -5,11 +5,11 @@ io.cucumber cucumber-parent - 4.5.0 + 5.0.0-SNAPSHOT query - 14.6.1-SNAPSHOT + 15.0.0-SNAPSHOT jar Cucumber Query Given one Cucumber Message, find another @@ -44,6 +44,14 @@ pom import + + + org.assertj + assertj-bom + 3.27.6 + pom + import + @@ -51,7 +59,7 @@ io.cucumber messages - [29.0.1,31.0.0) + [31.0.0-SNAPSHOT,32.0.0) @@ -75,7 +83,6 @@ org.assertj assertj-core - 3.27.6 test @@ -85,4 +92,22 @@ test + + + + + org.apache.maven.plugins + maven-checkstyle-plugin + + + validate + validate + + check + + + + + + diff --git a/java/src/main/java/io/cucumber/query/Lineage.java b/java/src/main/java/io/cucumber/query/Lineage.java index 37b1e8c3..08be5f07 100644 --- a/java/src/main/java/io/cucumber/query/Lineage.java +++ b/java/src/main/java/io/cucumber/query/Lineage.java @@ -6,6 +6,7 @@ import io.cucumber.messages.types.Rule; import io.cucumber.messages.types.Scenario; import io.cucumber.messages.types.TableRow; +import org.jspecify.annotations.Nullable; import java.util.Objects; import java.util.Optional; @@ -23,13 +24,13 @@ public final class Lineage { private final GherkinDocument document; - private final Feature feature; - private final Rule rule; - private final Scenario scenario; - private final Examples examples; - private final Integer examplesIndex; - private final TableRow example; - private final Integer exampleIndex; + private final @Nullable Feature feature; + private final @Nullable Rule rule; + private final @Nullable Scenario scenario; + private final @Nullable Examples examples; + private final @Nullable Integer examplesIndex; + private final @Nullable TableRow example; + private final @Nullable Integer exampleIndex; Lineage(GherkinDocument document) { this(document, null, null, null, null, null, null, null); @@ -55,7 +56,7 @@ public final class Lineage { this(parent.document, parent.feature, parent.rule, parent.scenario, parent.examples, parent.examplesIndex, example, exampleIndex); } - private Lineage(GherkinDocument document, Feature feature, Rule rule, Scenario scenario, Examples examples, Integer examplesIndex, TableRow example, Integer exampleIndex) { + private Lineage(GherkinDocument document, @Nullable Feature feature, @Nullable Rule rule, @Nullable Scenario scenario, @Nullable Examples examples, @Nullable Integer examplesIndex, @Nullable TableRow example, @Nullable Integer exampleIndex) { this.document = requireNonNull(document); this.feature = feature; this.rule = rule; @@ -103,7 +104,7 @@ public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Lineage that = (Lineage) o; - return document.equals(that.document) && feature.equals(that.feature) && Objects.equals(rule, that.rule) && scenario.equals(that.scenario) && Objects.equals(examples, that.examples) && Objects.equals(example, that.example) && Objects.equals(examplesIndex, that.examplesIndex) && Objects.equals(exampleIndex, that.exampleIndex); + return document.equals(that.document) && Objects.equals(feature, that.feature) && Objects.equals(rule, that.rule) && Objects.equals(scenario, that.scenario) && Objects.equals(examples, that.examples) && Objects.equals(example, that.example) && Objects.equals(examplesIndex, that.examplesIndex) && Objects.equals(exampleIndex, that.exampleIndex); } @Override diff --git a/java/src/main/java/io/cucumber/query/Lineages.java b/java/src/main/java/io/cucumber/query/Lineages.java index a82b0bc1..4c9a2c3f 100644 --- a/java/src/main/java/io/cucumber/query/Lineages.java +++ b/java/src/main/java/io/cucumber/query/Lineages.java @@ -12,12 +12,14 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.Optional; import java.util.function.BiConsumer; import java.util.function.Consumer; -import java.util.function.Supplier; -class Lineages { +final class Lineages { + + private Lineages(){ + // utility class + } /** * Create map of a {@link GherkinDocument} element to its {@link Lineage} in that document. diff --git a/java/src/main/java/io/cucumber/query/NamingCollector.java b/java/src/main/java/io/cucumber/query/NamingCollector.java index 1fc037f1..f1191524 100644 --- a/java/src/main/java/io/cucumber/query/NamingCollector.java +++ b/java/src/main/java/io/cucumber/query/NamingCollector.java @@ -10,6 +10,7 @@ import io.cucumber.query.NamingStrategy.ExampleName; import io.cucumber.query.NamingStrategy.FeatureName; import io.cucumber.query.NamingStrategy.Strategy; +import org.jspecify.annotations.Nullable; import java.util.ArrayDeque; import java.util.Deque; @@ -25,7 +26,7 @@ * * @see NamingStrategy */ -class NamingCollector implements Collector { +final class NamingCollector implements Collector { // There are at most 5 levels to a feature file. private final Deque parts = new ArrayDeque<>(5); @@ -34,7 +35,7 @@ class NamingCollector implements Collector { private final FeatureName featureName; private final ExampleName exampleName; - private String scenarioName; + private @Nullable String scenarioName; private boolean isExample; private int examplesIndex; @@ -48,36 +49,42 @@ private NamingCollector(Strategy strategy, FeatureName featureName, ExampleName this.exampleName = exampleName; } + @Override public void add(Feature feature) { if (featureName == INCLUDE || strategy == SHORT) { parts.add(feature.getName()); } } + @Override public void add(Rule rule) { parts.add(rule.getName()); } + @Override public void add(Scenario scenario) { scenarioName = scenario.getName(); parts.add(scenarioName); } + @Override public void add(Examples examples, int index) { parts.add(examples.getName()); this.examplesIndex = index; } + @Override public void add(TableRow example, int index) { isExample = true; parts.add("#" + (examplesIndex + 1) + "." + (index + 1)); } + @Override public void add(Pickle pickle) { String pickleName = pickle.getName(); // Case 0: Pickles with an empty a lineage - if (scenarioName == null){ + if (scenarioName == null) { parts.add(pickleName); return; } @@ -85,19 +92,19 @@ public void add(Pickle pickle) { // Case 1: Pickles from a scenario outline if (isExample) { switch (exampleName) { - case NUMBER: - break; - case NUMBER_AND_PICKLE_IF_PARAMETERIZED: + case NUMBER -> { } + case NUMBER_AND_PICKLE_IF_PARAMETERIZED -> { boolean parameterized = !scenarioName.equals(pickleName); if (parameterized) { String exampleNumber = parts.removeLast(); parts.add(exampleNumber + ": " + pickleName); } - break; - case PICKLE: - parts.removeLast(); // Remove example number + } + case PICKLE -> { + parts.removeLast(); + // Remove example number parts.add(pickleName); - break; + } } } // Case 2: Pickles from a scenario diff --git a/java/src/main/java/io/cucumber/query/NamingStrategy.java b/java/src/main/java/io/cucumber/query/NamingStrategy.java index fbd3c5c9..dea508ee 100644 --- a/java/src/main/java/io/cucumber/query/NamingStrategy.java +++ b/java/src/main/java/io/cucumber/query/NamingStrategy.java @@ -4,7 +4,6 @@ import io.cucumber.messages.types.Pickle; import static io.cucumber.query.LineageReducer.descending; -import static io.cucumber.query.NamingCollector.of; import static io.cucumber.query.NamingStrategy.ExampleName.NUMBER_AND_PICKLE_IF_PARAMETERIZED; import static io.cucumber.query.NamingStrategy.FeatureName.INCLUDE; import static java.util.Objects.requireNonNull; @@ -26,10 +25,10 @@ * *
{@code
  * Feature: Examples Tables
- *   Scenario Outline: Eating <eat> cucumbers
- *     Given there are <start> cucumbers
- *     When I eat <eat> cucumbers
- *     Then I should have <left> cucumbers
+ *   Scenario Outline: Eating  cucumbers
+ *     Given there are  cucumbers
+ *     When I eat  cucumbers
+ *     Then I should have  cucumbers
  *
  *     Examples: These are passing
  *       | start | eat | left |
@@ -45,10 +44,10 @@
  * With the long strategy, using example numbers and the pickle if
  * parameterized, the pickles in this example would be named:
  * 
    - *
  • Examples Tables - Eating <eat> cucumbers - These are passing - #1.1: Eating 5 cucumbers - *
  • Examples Tables - Eating <eat> cucumbers - These are passing - #1.2: Eating 6 cucumbers - *
  • Examples Tables - Eating <eat> cucumbers - These are failing - #2.1: Eating 20 cucumbers - *
  • Examples Tables - Eating <eat> cucumbers - These are failing - #2.2: Eating 1 cucumbers + *
  • Examples Tables - Eating cucumbers - These are passing - #1.1: Eating 5 cucumbers + *
  • Examples Tables - Eating cucumbers - These are passing - #1.2: Eating 6 cucumbers + *
  • Examples Tables - Eating cucumbers - These are failing - #2.1: Eating 20 cucumbers + *
  • Examples Tables - Eating cucumbers - These are failing - #2.2: Eating 1 cucumbers *
*

* And with the short strategy, using pickle names: @@ -112,7 +111,7 @@ private NamingStrategy() { // Could be made a public interface if GherkinDocumentElements had a better API } - public static class Builder { + public static final class Builder { private final Strategy strategy; private FeatureName featureName = INCLUDE; @@ -133,7 +132,7 @@ public Builder featureName(FeatureName featureName) { } public NamingStrategy build() { - return new Adaptor(descending(of(strategy, featureName, exampleName))); + return new Adaptor(descending(NamingCollector.of(strategy, featureName, exampleName))); } } diff --git a/java/src/main/java/io/cucumber/query/Query.java b/java/src/main/java/io/cucumber/query/Query.java index 9090e336..5cb7e9a3 100644 --- a/java/src/main/java/io/cucumber/query/Query.java +++ b/java/src/main/java/io/cucumber/query/Query.java @@ -82,6 +82,7 @@ public Map countMostSevereTestStepResultStatus() { .collect(groupingBy(identity(), LinkedHashMap::new, counting()))); return results; } + public int countTestCasesStarted() { return findAllTestCaseStarted().size(); } @@ -101,8 +102,8 @@ public List findAllTestCaseStarted() { .isPresent()) .collect(toList()); } - - public List findAllStepDefinitions(){ + + public List findAllStepDefinitions() { return new ArrayList<>(repository.stepDefinitionById.values()); } @@ -195,6 +196,10 @@ public Optional findMostSevereTestStepResultBy(TestCaseFinished } public Optional findLocationOf(Pickle pickle) { + Optional location = pickle.getLocation(); + if (location.isPresent()) { + return location; + } return findLineageBy(pickle).flatMap(lineage -> { if (lineage.example().isPresent()) { return lineage.example().map(TableRow::getLocation); diff --git a/java/src/main/java/io/cucumber/query/Repository.java b/java/src/main/java/io/cucumber/query/Repository.java index 18aa8983..3c8c9421 100644 --- a/java/src/main/java/io/cucumber/query/Repository.java +++ b/java/src/main/java/io/cucumber/query/Repository.java @@ -22,6 +22,7 @@ import io.cucumber.messages.types.TestStepFinished; import io.cucumber.messages.types.TestStepStarted; import io.cucumber.messages.types.UndefinedParameterType; +import org.jspecify.annotations.Nullable; import java.util.ArrayList; import java.util.EnumSet; @@ -32,7 +33,12 @@ import java.util.Set; import java.util.function.BiFunction; -import static io.cucumber.query.Repository.RepositoryFeature.*; +import static io.cucumber.query.Repository.RepositoryFeature.INCLUDE_ATTACHMENTS; +import static io.cucumber.query.Repository.RepositoryFeature.INCLUDE_GHERKIN_DOCUMENTS; +import static io.cucumber.query.Repository.RepositoryFeature.INCLUDE_HOOKS; +import static io.cucumber.query.Repository.RepositoryFeature.INCLUDE_STEP_DEFINITIONS; +import static io.cucumber.query.Repository.RepositoryFeature.INCLUDE_SUGGESTIONS; +import static io.cucumber.query.Repository.RepositoryFeature.INCLUDE_UNDEFINED_PARAMETER_TYPES; /** * A write only repository of Cucumber Messages. @@ -62,9 +68,9 @@ public final class Repository { final Map> suggestionsByPickleStepId = new LinkedHashMap<>(); final List undefinedParameterTypes = new ArrayList<>(); - Meta meta; - TestRunStarted testRunStarted; - TestRunFinished testRunFinished; + @Nullable Meta meta; + @Nullable TestRunStarted testRunStarted; + @Nullable TestRunFinished testRunFinished; private Repository(Set features) { this.features = features; @@ -74,74 +80,6 @@ public static Builder builder() { return new Builder(); } - public enum RepositoryFeature { - - /** - * Include {@link Attachment} messages. - *

- * Disable to reduce memory usage. - */ - INCLUDE_ATTACHMENTS, - - /** - * Include {@link io.cucumber.messages.types.GherkinDocument} messages. - *

- * Disable to reduce memory usage. - */ - INCLUDE_GHERKIN_DOCUMENTS, - - /** - * Include {@link Hook} messages. - *

- * Disable to reduce memory usage. - */ - INCLUDE_HOOKS, - - /** - * Include {@link StepDefinition} messages. - *

- * Disable to reduce memory usage. - */ - INCLUDE_STEP_DEFINITIONS, - - /** - * Include {@link Suggestion} messages. - *

- * Disable to reduce memory usage. - */ - INCLUDE_SUGGESTIONS, - - /** - * Include {@link UndefinedParameterType} messages. - *

- * Disable to reduce memory usage. - */ - INCLUDE_UNDEFINED_PARAMETER_TYPES, - } - - public static class Builder { - private final EnumSet features = EnumSet.noneOf(RepositoryFeature.class); - - private Builder(){ - - } - /** - * Toggles a given feature. - */ - public Builder feature(RepositoryFeature feature, boolean enabled) { - if (enabled) { - features.add(feature); - } else { - features.remove(feature); - } - return this; - } - - public Repository build() { - return new Repository(EnumSet.copyOf(features)); - } - } - public void update(Envelope envelope) { envelope.getMeta().ifPresent(this::updateMeta); envelope.getTestRunStarted().ifPresent(this::updateTestRunStarted); @@ -281,4 +219,72 @@ private BiFunction, List> updateList(E element) { }; } + public enum RepositoryFeature { + + /** + * Include {@link Attachment} messages. + *

+ * Disable to reduce memory usage. + */ + INCLUDE_ATTACHMENTS, + + /** + * Include {@link io.cucumber.messages.types.GherkinDocument} messages. + *

+ * Disable to reduce memory usage. + */ + INCLUDE_GHERKIN_DOCUMENTS, + + /** + * Include {@link Hook} messages. + *

+ * Disable to reduce memory usage. + */ + INCLUDE_HOOKS, + + /** + * Include {@link StepDefinition} messages. + *

+ * Disable to reduce memory usage. + */ + INCLUDE_STEP_DEFINITIONS, + + /** + * Include {@link Suggestion} messages. + *

+ * Disable to reduce memory usage. + */ + INCLUDE_SUGGESTIONS, + + /** + * Include {@link UndefinedParameterType} messages. + *

+ * Disable to reduce memory usage. + */ + INCLUDE_UNDEFINED_PARAMETER_TYPES + } + + public static final class Builder { + private final EnumSet features = EnumSet.noneOf(RepositoryFeature.class); + + private Builder() { + + } + + /** + * Toggles a given feature. + */ + public Builder feature(RepositoryFeature feature, boolean enabled) { + if (enabled) { + features.add(feature); + } else { + features.remove(feature); + } + return this; + } + + public Repository build() { + return new Repository(EnumSet.copyOf(features)); + } + } } diff --git a/java/src/main/java/io/cucumber/query/package-info.java b/java/src/main/java/io/cucumber/query/package-info.java new file mode 100644 index 00000000..04d6d669 --- /dev/null +++ b/java/src/main/java/io/cucumber/query/package-info.java @@ -0,0 +1,4 @@ +@NullMarked +package io.cucumber.query; + +import org.jspecify.annotations.NullMarked; \ No newline at end of file diff --git a/java/src/test/java/io/cucumber/query/NamingStrategyAcceptanceTest.java b/java/src/test/java/io/cucumber/query/NamingStrategyAcceptanceTest.java index 95485161..9f0b1011 100644 --- a/java/src/test/java/io/cucumber/query/NamingStrategyAcceptanceTest.java +++ b/java/src/test/java/io/cucumber/query/NamingStrategyAcceptanceTest.java @@ -31,11 +31,11 @@ import static io.cucumber.query.NamingStrategy.Strategy.SHORT; import static java.nio.charset.StandardCharsets.UTF_8; import static java.nio.file.Files.newOutputStream; -import static java.nio.file.Files.readAllBytes; +import static java.util.Objects.requireNonNull; import static org.assertj.core.api.Assertions.assertThat; -public class NamingStrategyAcceptanceTest { - private static final NdjsonToMessageIterable.Deserializer deserializer = (json) -> OBJECT_MAPPER.readValue(json, Envelope.class); +class NamingStrategyAcceptanceTest { + private static final NdjsonToMessageIterable.Deserializer deserializer = json -> OBJECT_MAPPER.readValue(json, Envelope.class); static List acceptance() { Map strategies = new LinkedHashMap<>(); @@ -62,13 +62,13 @@ static List acceptance() { private static String writeResults(TestCase testCase, NamingStrategy strategy) throws IOException { ByteArrayOutputStream out = new ByteArrayOutputStream(); writeResults(strategy, testCase, out); - return new String(out.toByteArray(), UTF_8); + return out.toString(UTF_8); } private static void writeResults(NamingStrategy strategy, TestCase testCase, OutputStream out) throws IOException { try (InputStream in = Files.newInputStream(testCase.source)) { try (NdjsonToMessageIterable envelopes = new NdjsonToMessageIterable(in, deserializer)) { - try (PrintWriter writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(out)))) { + try (PrintWriter writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(out, UTF_8)))) { Repository repository = createRepository(); for (Envelope envelope : envelopes) { repository.update(envelope); @@ -90,12 +90,11 @@ private static Repository createRepository() { .build(); } - @ParameterizedTest @MethodSource("acceptance") void test(TestCase testCase) throws IOException { String actual = writeResults(testCase, testCase.strategy); - String expected = new String(readAllBytes(testCase.expected), UTF_8); + String expected = Files.readString(testCase.expected); assertThat(actual).isEqualTo(expected); } @@ -122,7 +121,7 @@ static class TestCase { this.strategyName = strategyName; String fileName = source.getFileName().toString(); this.name = fileName.substring(0, fileName.lastIndexOf(".ndjson")); - this.expected = source.getParent().resolve(name + ".naming-strategy." + strategyName + ".txt"); + this.expected = requireNonNull(source.getParent()).resolve(name + ".naming-strategy." + strategyName + ".txt"); } @Override diff --git a/java/src/test/java/io/cucumber/query/QueryAcceptanceTest.java b/java/src/test/java/io/cucumber/query/QueryAcceptanceTest.java index 0758c0a2..3c4dbcde 100644 --- a/java/src/test/java/io/cucumber/query/QueryAcceptanceTest.java +++ b/java/src/test/java/io/cucumber/query/QueryAcceptanceTest.java @@ -3,7 +3,22 @@ import com.fasterxml.jackson.core.util.DefaultPrettyPrinter; import io.cucumber.messages.Convertor; import io.cucumber.messages.NdjsonToMessageIterable; -import io.cucumber.messages.types.*; +import io.cucumber.messages.types.Envelope; +import io.cucumber.messages.types.Hook; +import io.cucumber.messages.types.Pickle; +import io.cucumber.messages.types.PickleStep; +import io.cucumber.messages.types.Step; +import io.cucumber.messages.types.StepDefinition; +import io.cucumber.messages.types.Suggestion; +import io.cucumber.messages.types.TestCase; +import io.cucumber.messages.types.TestCaseFinished; +import io.cucumber.messages.types.TestCaseStarted; +import io.cucumber.messages.types.TestRunHookFinished; +import io.cucumber.messages.types.TestRunHookStarted; +import io.cucumber.messages.types.TestStep; +import io.cucumber.messages.types.TestStepFinished; +import io.cucumber.messages.types.TestStepResult; +import io.cucumber.messages.types.TestStepStarted; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; @@ -15,19 +30,31 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; import java.util.function.Function; import static com.fasterxml.jackson.core.util.DefaultIndenter.SYSTEM_LINEFEED_INSTANCE; import static io.cucumber.query.Jackson.OBJECT_MAPPER; -import static io.cucumber.query.Repository.RepositoryFeature.*; +import static io.cucumber.query.Repository.RepositoryFeature.INCLUDE_ATTACHMENTS; +import static io.cucumber.query.Repository.RepositoryFeature.INCLUDE_GHERKIN_DOCUMENTS; +import static io.cucumber.query.Repository.RepositoryFeature.INCLUDE_HOOKS; +import static io.cucumber.query.Repository.RepositoryFeature.INCLUDE_STEP_DEFINITIONS; +import static io.cucumber.query.Repository.RepositoryFeature.INCLUDE_SUGGESTIONS; +import static io.cucumber.query.Repository.RepositoryFeature.INCLUDE_UNDEFINED_PARAMETER_TYPES; import static java.nio.charset.StandardCharsets.UTF_8; import static java.util.Arrays.asList; +import static java.util.Objects.requireNonNull; import static java.util.stream.Collectors.toList; import static org.assertj.core.api.Assertions.assertThat; -public class QueryAcceptanceTest { - private static final NdjsonToMessageIterable.Deserializer deserializer = (json) -> OBJECT_MAPPER.readValue(json, Envelope.class); +class QueryAcceptanceTest { + private static final NdjsonToMessageIterable.Deserializer deserializer = json -> OBJECT_MAPPER.readValue(json, Envelope.class); static List acceptance() { List testCases = new ArrayList<>(); @@ -60,8 +87,8 @@ private static List getSources() { @MethodSource("acceptance") void test(QueryTestCase testCase) throws IOException { ByteArrayOutputStream bytes = writeQueryResults(testCase, new ByteArrayOutputStream()); - String expected = new String(Files.readAllBytes(testCase.expected), UTF_8); - String actual = new String(bytes.toByteArray(), UTF_8); + String expected = Files.readString(testCase.expected); + String actual = bytes.toString(UTF_8); assertThat(actual).isEqualTo(expected); } @@ -108,25 +135,25 @@ static Map> createQueries() { queries.put("countMostSevereTestStepResultStatus", Query::countMostSevereTestStepResultStatus); queries.put("countTestCasesStarted", Query::countTestCasesStarted); - queries.put("findAllPickles", (query) -> query.findAllPickles().size()); - queries.put("findAllPickleSteps", (query) -> query.findAllPickleSteps().size()); - queries.put("findAllStepDefinitions", (query) -> query.findAllStepDefinitions().size()); - queries.put("findAllTestCaseStarted", (query) -> query.findAllTestCaseStarted().size()); - queries.put("findAllTestCaseFinished", (query) -> query.findAllTestCaseFinished().size()); - queries.put("findAllTestRunHookStarted", (query) -> query.findAllTestRunHookStarted().size()); - queries.put("findAllTestRunHookFinished", (query) -> query.findAllTestRunHookFinished().size()); - queries.put("findAllTestSteps", (query) -> query.findAllTestSteps().size()); - queries.put("findAllTestStepsStarted", (query) -> query.findAllTestStepStarted().size()); - queries.put("findAllTestStepsFinished", (query) -> query.findAllTestStepFinished().size()); - queries.put("findAllTestCases", (query) -> query.findAllTestCases().size()); - queries.put("findAllUndefinedParameterTypes", (query) -> query.findAllUndefinedParameterTypes().stream() + queries.put("findAllPickles", query -> query.findAllPickles().size()); + queries.put("findAllPickleSteps", query -> query.findAllPickleSteps().size()); + queries.put("findAllStepDefinitions", query -> query.findAllStepDefinitions().size()); + queries.put("findAllTestCaseStarted", query -> query.findAllTestCaseStarted().size()); + queries.put("findAllTestCaseFinished", query -> query.findAllTestCaseFinished().size()); + queries.put("findAllTestRunHookStarted", query -> query.findAllTestRunHookStarted().size()); + queries.put("findAllTestRunHookFinished", query -> query.findAllTestRunHookFinished().size()); + queries.put("findAllTestSteps", query -> query.findAllTestSteps().size()); + queries.put("findAllTestStepsStarted", query -> query.findAllTestStepStarted().size()); + queries.put("findAllTestStepsFinished", query -> query.findAllTestStepFinished().size()); + queries.put("findAllTestCases", query -> query.findAllTestCases().size()); + queries.put("findAllUndefinedParameterTypes", query -> query.findAllUndefinedParameterTypes().stream() .map(undefinedParameterType -> Arrays.asList( undefinedParameterType.getName(), undefinedParameterType.getExpression() )) .collect(toList())); - queries.put("findAttachmentsBy", (query) -> { + queries.put("findAttachmentsBy", query -> { Map results = new LinkedHashMap<>(); results.put("testStepFinished", query.findAllTestCaseStarted().stream() .map(query::findTestStepFinishedAndTestStepBy) @@ -153,7 +180,7 @@ static Map> createQueries() { return results; }); - queries.put("findHookBy", (query) -> { + queries.put("findHookBy", query -> { Map results = new LinkedHashMap<>(); results.put("testStep", query.findAllTestSteps().stream() .map(query::findHookBy) @@ -173,7 +200,7 @@ static Map> createQueries() { return results; }); - queries.put("findLineageBy", (query) -> { + queries.put("findLineageBy", query -> { Map results = new LinkedHashMap<>(); NamingStrategy namingStrategy = NamingStrategy.strategy(NamingStrategy.Strategy.LONG).build(); results.put("testCaseStarted", query.findAllTestCaseStarted().stream() @@ -197,13 +224,13 @@ static Map> createQueries() { return results; }); - queries.put("findLocationOf", (query) -> query.findAllPickles().stream() + queries.put("findLocationOf", query -> query.findAllPickles().stream() .map(query::findLocationOf) .filter(Optional::isPresent) .collect(toList())); - queries.put("findMeta", (query) -> query.findMeta().map(meta -> meta.getImplementation().getName())); + queries.put("findMeta", query -> query.findMeta().map(meta -> meta.getImplementation().getName())); - queries.put("findMostSevereTestStepResultBy", (query) -> { + queries.put("findMostSevereTestStepResultBy", query -> { Map results = new LinkedHashMap<>(); results.put("testCaseStarted", query.findAllTestCaseStarted().stream() .map(query::findMostSevereTestStepResultBy) @@ -220,7 +247,7 @@ static Map> createQueries() { return results; }); - queries.put("findPickleBy", (query) -> { + queries.put("findPickleBy", query -> { Map results = new LinkedHashMap<>(); results.put("testCaseStarted", query.findAllTestCaseStarted().stream() .map(query::findPickleBy) @@ -241,22 +268,22 @@ static Map> createQueries() { return results; }); - queries.put("findPickleStepBy", (query) -> query.findAllTestSteps().stream() + queries.put("findPickleStepBy", query -> query.findAllTestSteps().stream() .map(query::findPickleStepBy) .map(pickleStep -> pickleStep.map(PickleStep::getText)) .filter(Optional::isPresent) .collect(toList())); - queries.put("findStepBy", (query) -> query.findAllPickleSteps().stream() + queries.put("findStepBy", query -> query.findAllPickleSteps().stream() .map(query::findStepBy) .map(step -> step.map(Step::getText)) .collect(toList())); - queries.put("findStepDefinitionsBy", (query) -> query.findAllTestSteps().stream() + queries.put("findStepDefinitionsBy", query -> query.findAllTestSteps().stream() .map(query::findStepDefinitionsBy) .map(stepDefinitions -> stepDefinitions.stream().map(StepDefinition::getId) .collect(toList())) .collect(toList())); - queries.put("findSuggestionsBy", (query) -> { + queries.put("findSuggestionsBy", query -> { Map results = new LinkedHashMap<>(); results.put("pickleStep", query.findAllPickleSteps().stream() .map(query::findSuggestionsBy) @@ -271,13 +298,13 @@ static Map> createQueries() { return results; }); - queries.put("findUnambiguousStepDefinitionBy", (query) -> query.findAllTestSteps().stream() + queries.put("findUnambiguousStepDefinitionBy", query -> query.findAllTestSteps().stream() .map(query::findUnambiguousStepDefinitionBy) .filter(Optional::isPresent) .map(Optional::get) .map(StepDefinition::getId)); - queries.put("findTestCaseStartedBy", (query) -> { + queries.put("findTestCaseStartedBy", query -> { Map results = new LinkedHashMap<>(); results.put("testCaseFinished", query.findAllTestCaseFinished().stream() .map(query::findTestCaseStartedBy) @@ -294,7 +321,7 @@ static Map> createQueries() { return results; }); - queries.put("findTestCaseBy", (query) -> { + queries.put("findTestCaseBy", query -> { Map results = new LinkedHashMap<>(); results.put("testCaseStarted", query.findAllTestCaseStarted().stream() .map(query::findTestCaseBy) @@ -315,7 +342,7 @@ static Map> createQueries() { return results; }); - queries.put("findTestCaseDurationBy", (query) -> { + queries.put("findTestCaseDurationBy", query -> { Map results = new LinkedHashMap<>(); results.put("testCaseStarted", query.findAllTestCaseStarted().stream() .map(query::findTestCaseDurationBy) @@ -328,22 +355,22 @@ static Map> createQueries() { return results; }); - queries.put("findTestCaseFinishedBy", (query) -> query.findAllTestCaseStarted().stream() + queries.put("findTestCaseFinishedBy", query -> query.findAllTestCaseStarted().stream() .map(query::findTestCaseFinishedBy) .map(testCaseFinished -> testCaseFinished.map(TestCaseFinished::getTestCaseStartedId)) .collect(toList())); - queries.put("findTestRunDuration", (query) -> query.findTestRunDuration() + queries.put("findTestRunDuration", query -> query.findTestRunDuration() .map(Convertor::toMessage)); queries.put("findTestRunFinished", Query::findTestRunFinished); queries.put("findTestRunStarted", Query::findTestRunStarted); - queries.put("findTestStepBy", (query) -> query.findAllTestCaseStarted().stream() + queries.put("findTestStepBy", query -> query.findAllTestCaseStarted().stream() .map(query::findTestStepsStartedBy) .flatMap(Collection::stream) .map(query::findTestStepBy) .map(testStep -> testStep.map(TestStep::getId)) .collect(toList())); - queries.put("findTestStepsStartedBy", (query) -> { + queries.put("findTestStepsStartedBy", query -> { Map results = new LinkedHashMap<>(); results.put("testCaseStarted", query.findAllTestCaseStarted().stream() @@ -359,16 +386,16 @@ static Map> createQueries() { return results; }); - queries.put("findTestRunHookFinishedBy", (query) -> query.findAllTestRunHookStarted().stream() + queries.put("findTestRunHookFinishedBy", query -> query.findAllTestRunHookStarted().stream() .map(query::findTestRunHookFinishedBy) .map(testRunHookFinished -> testRunHookFinished.map(TestRunHookFinished::getTestRunHookStartedId)) .collect(toList())); - queries.put("findTestRunHookStartedBy", (query) -> query.findAllTestRunHookFinished().stream() + queries.put("findTestRunHookStartedBy", query -> query.findAllTestRunHookFinished().stream() .map(query::findTestRunHookStartedBy) .map(testRunHookStarted -> testRunHookStarted.map(TestRunHookStarted::getId)) .collect(toList())); - queries.put("findTestStepByTestStepFinished", (query) -> { + queries.put("findTestStepByTestStepFinished", query -> { Map results = new LinkedHashMap<>(); results.put("testCaseStarted", query.findAllTestCaseStarted().stream() @@ -387,11 +414,11 @@ static Map> createQueries() { return results; }); - queries.put("findTestStepsFinishedBy", (query) -> query.findAllTestCaseStarted().stream() + queries.put("findTestStepsFinishedBy", query -> query.findAllTestCaseStarted().stream() .map(query::findTestStepsFinishedBy) .map(testStepFinisheds -> testStepFinisheds.stream().map(TestStepFinished::getTestStepId).collect(toList())) .collect(toList())); - queries.put("findTestStepFinishedAndTestStepBy", (query) -> query.findAllTestCaseStarted().stream() + queries.put("findTestStepFinishedAndTestStepBy", query -> query.findAllTestCaseStarted().stream() .map(query::findTestStepFinishedAndTestStepBy) .flatMap(Collection::stream) .map(entry -> asList(entry.getKey().getTestStepId(), entry.getValue().getId())) @@ -413,7 +440,7 @@ static class QueryTestCase { this.query = query; String fileName = source.getFileName().toString(); this.name = fileName.substring(0, fileName.lastIndexOf(".ndjson")); - this.expected = source.getParent().resolve(name + "." + methodName + ".results.json"); + this.expected = requireNonNull(source.getParent()).resolve(name + "." + methodName + ".results.json"); } @Override diff --git a/java/src/test/java/io/cucumber/query/QueryTest.java b/java/src/test/java/io/cucumber/query/QueryTest.java index e479ee80..f420d6a8 100644 --- a/java/src/test/java/io/cucumber/query/QueryTest.java +++ b/java/src/test/java/io/cucumber/query/QueryTest.java @@ -18,9 +18,9 @@ class QueryTest { @Test void retainsInsertionOrderForTestCaseStarted() { - TestCaseStarted a = new TestCaseStarted(0L, randomId(), randomId(), "main", new Timestamp(1L, 0L)); - TestCaseStarted b = new TestCaseStarted(0L, randomId(), randomId(), "main", new Timestamp(1L, 0L)); - TestCaseStarted c = new TestCaseStarted(0L, randomId(), randomId(), "main", new Timestamp(1L, 0L)); + TestCaseStarted a = new TestCaseStarted(0L, randomId(), randomId(), "main", new Timestamp(1L, 0)); + TestCaseStarted b = new TestCaseStarted(0L, randomId(), randomId(), "main", new Timestamp(1L, 0)); + TestCaseStarted c = new TestCaseStarted(0L, randomId(), randomId(), "main", new Timestamp(1L, 0)); Stream.of(a, b, c) .map(Envelope::of) @@ -31,10 +31,10 @@ void retainsInsertionOrderForTestCaseStarted() { @Test void omitsTestCaseStartedIfFinishedAndWillBeRetried() { - TestCaseStarted a = new TestCaseStarted(0L, randomId(), randomId(), "main", new Timestamp(0L, 0L)); - TestCaseFinished b = new TestCaseFinished(a.getId(), new Timestamp(0L, 0L), true); - TestCaseStarted c = new TestCaseStarted(0L, randomId(), randomId(), "main", new Timestamp(0L, 0L)); - TestCaseFinished d = new TestCaseFinished(c.getId(), new Timestamp(0L, 0L), false); + TestCaseStarted a = new TestCaseStarted(0L, randomId(), randomId(), "main", new Timestamp(0L, 0)); + TestCaseFinished b = new TestCaseFinished(a.getId(), new Timestamp(0L, 0), true); + TestCaseStarted c = new TestCaseStarted(0L, randomId(), randomId(), "main", new Timestamp(0L, 0)); + TestCaseFinished d = new TestCaseFinished(c.getId(), new Timestamp(0L, 0), false); Stream.of(a, c) .map(Envelope::of)