Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Overrirde runnder tags #112

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package com.pdsl.gherkin.filter;

import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import java.util.stream.Collectors;

/**
* This class adapts the `GherkinTagFilterer` interface to the `TagFilterer` interface. It provides
* a way to use the functionality of `GherkinTagFilterer` with code that expects a `TagFilterer`.
*/
public class GherkinTagFiltererAdapter implements TagFilterer {

/**
* The instance of the `GherkinTagFilterer` to be adapted.
*/
private final GherkinTagFilterer gherkinTagFilterer;

/**
* Constructor for the `GherkinTagFiltererAdapter`.
*
* @param gherkinTagFilterer The instance of the `GherkinTagFilterer` to be adapted.
*/
public GherkinTagFiltererAdapter(GherkinTagFilterer gherkinTagFilterer) {
this.gherkinTagFilterer = gherkinTagFilterer;
}

/**
* This method checks whether a collection of tags matches a given tag expression. It converts the
* collection of tags to a `Set` using a `HashSet` and then delegates the logic to the
* `gherkinTagFilterer.tagExpressionMatchesPickle` method.
*
* @param tags The collection of tags to be checked.
* @param tagExpression The tag expression to match against.
* @return True if the tags match the tag expression, False otherwise.
*/

@Override
public boolean tagExpressionMatches(Collection<String> tags, String tagExpression) {
return gherkinTagFilterer.tagExpressionMatchesPickle(new HashSet<>(tags), tagExpression);
}
}
13 changes: 13 additions & 0 deletions src/main/java/com/pdsl/gherkin/filter/TagFilterer.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.pdsl.gherkin.filter;

import java.util.Collection;
import java.util.Set;

/**
* Determines if a test case derived from a gherkin file (i.e., a pickle) matches a particular tag
* expression.
*/
public interface TagFilterer {

boolean tagExpressionMatches(Collection<String> tags, String tagExpression);
}
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ public InterpreterObj get() {
private static PdslTestParams getPdslTestParams(
PdslTestDto pdslTestDto, PdslConfiguration pdslConfiguration) {

return new PdslTestParams(
return PdslTestParams.from(
getRecognizerLexer(pdslTestDto, pdslConfiguration),
getRecognizerParser(pdslTestDto, pdslConfiguration),
getInterpreterParams(pdslTestDto, pdslConfiguration),
Expand Down
25 changes: 22 additions & 3 deletions src/main/java/com/pdsl/runners/PdslTestParams.java
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package com.pdsl.runners;

import com.pdsl.gherkin.filter.TagFilterer;
import org.antlr.v4.runtime.Lexer;
import org.antlr.v4.runtime.Parser;

import java.util.List;
import org.junit.jupiter.engine.descriptor.PdslTestParameter;

/**
* A container for parameters useful for any framework implementing PDSL.
Expand All @@ -17,15 +19,32 @@
* @param excludesResources the tests to ignore
*/
public record PdslTestParams (
Class<? extends Lexer> lexerRecognizerClass,
Class<? extends Parser> parserRecognizerClass,
InterpreterParam[] interpreters,
List<String> tags,
String[] includesResources,
String[] excludesResources,
TagFilterer tagFilterer,
String tagExpression) {
public static final String DEFAULT_ALL_RULE = "polymorphicDslAllRules";
public static final String DEFAULT_SYNTAX_RULE = "polymorphicDslSyntaxCheck";

public static PdslTestParams from(
Class<? extends Lexer> lexerRecognizerClass,
Class<? extends Parser> parserRecognizerClass,
InterpreterParam[] interpreters,
List<String> tags,
String[] includesResources,
String[] excludesResources) {
public static final String DEFAULT_ALL_RULE = "polymorphicDslAllRules";
public static final String DEFAULT_SYNTAX_RULE = "polymorphicDslSyntaxCheck";
String[] excludesResources){

/* Creates a default tag filter that always returns true, effectively disabling tag filtering.,
Empty tag expression as no filtering is applied */
return new PdslTestParams(
lexerRecognizerClass, parserRecognizerClass, interpreters,
tags, includesResources, excludesResources,
(tags1, tagExpression) -> true, "");
}
/**
* A visitor used to extend the behavior of the PdslTestParams obje3ct without modifying
* the record itself.
Expand Down
33 changes: 32 additions & 1 deletion src/main/java/com/pdsl/runners/SharedTestSuiteVisitor.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,19 @@

import com.google.common.base.Preconditions;
import com.pdsl.executors.InterpreterObj;
import com.pdsl.gherkin.filter.TagFilterer;
import com.pdsl.specifications.TestResourceFinder;
import com.pdsl.specifications.TestResourceFinderGenerator;
import com.pdsl.specifications.TestSpecification;
import com.pdsl.specifications.TestSpecificationFactory;
import com.pdsl.testcases.DefaultTaggedTestCase;
import com.pdsl.testcases.SharedTestSuite;
import com.pdsl.testcases.TaggedTestCase;
import com.pdsl.testcases.TestCase;
import com.pdsl.testcases.TestCaseFactory;
import com.pdsl.transformers.DefaultPolymorphicDslPhraseFilter;
import com.pdsl.transformers.PolymorphicDslPhraseFilter;
import java.util.stream.Collectors;
import org.antlr.v4.runtime.Lexer;
import org.antlr.v4.runtime.Parser;

Expand All @@ -27,6 +31,7 @@
*/
public class SharedTestSuiteVisitor implements RecognizerParams.RecognizerParamsOperation<SharedTestSuite> {


@Override
public SharedTestSuite recognizerParamsOperation(RecognizerParams recognizerParams) {
Preconditions.checkNotNull(recognizerParams.applicationName(), "Application name cannot be null");
Expand All @@ -39,6 +44,7 @@ public SharedTestSuite recognizerParamsOperation(RecognizerParams recognizerPara
recognizerParams.pdslTestParams().forEach(interpreter -> Preconditions.checkNotNull(interpreter, "No null objects can be in the interpreter array!"));
// Create a Shared Test Suite
List<List<TestCase>> testCasesPerInterpreters = new ArrayList<>();
List<TestCase> matchedTestCases = new ArrayList<>();
List<InterpreterObj> interpreterObjs = new ArrayList<>();
for (PdslTestParams params : recognizerParams.pdslTestParams()) {

Expand All @@ -57,9 +63,34 @@ public SharedTestSuite recognizerParamsOperation(RecognizerParams recognizerPara
// test cases to create from each file, which parts to ignore, etc.
Collection<TestSpecification> specifications = getSpecifications(parser, recognizerParams, params, testResources);
// Convert the specificaitons into test cases

/*
* Filters test cases based on tags and organizes them per interpreter.
*
* This code iterates through a collection of test cases for a single interpreter,
* filters them based on tags using a provided `TagFilterer`, and then adds the
* matched test cases to a list of test cases per interpreter. It also collects
* the interpreter objects.
*/
List<TestCase> testCasesForSingleInterpreter = new ArrayList<>(getTestCases(recognizerParams.providers().testCaseFactoryProvider().get(), specifications));
testCasesPerInterpreters.add(testCasesForSingleInterpreter);
for (TestCase testcase : testCasesForSingleInterpreter) {
if (testcase instanceof TaggedTestCase) {
// Cast the TestCase to TaggedTestCase to access tag information.
TaggedTestCase test = (TaggedTestCase) testcase;
//Filter test cases by tags using the injected TagFilterer
// Check if any of the tags on the test case match the given tag expression.
boolean anyMatchedTag = params.tagFilterer().tagExpressionMatches(test.getTags(), params.tagExpression());
// If the test case's tags match the tag expression, add it to the matched test cases.
if (anyMatchedTag) {
matchedTestCases.add(testcase);
}
}
}
// Add the list of matched test cases for the current interpreter to the overall list.
testCasesPerInterpreters.add(matchedTestCases);
// Get the interpreter object from the parser provider and add it to the list of interpreter objects.
interpreterObjs.add(parser.interpreterProvider().get());

}
}
return SharedTestSuite.of(testCasesPerInterpreters, interpreterObjs);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ public class PdslGherkinJUnit4Runner extends BlockJUnit4ClassRunner {

public PdslGherkinJUnit4Runner(Class<?> testClass) throws InitializationError {
super(testClass);
System.out.print("JS23001 : 50");
pdslGherkinApplication = testClass.getAnnotation(PdslGherkinApplication.class);
Preconditions.checkNotNull(pdslGherkinApplication, String.format("Class run with %s must be annotated with %s!",
getClass().getSimpleName(), PdslConfiguration.class.getSimpleName()));
Expand Down
15 changes: 8 additions & 7 deletions src/main/java/com/pdsl/testcases/PreorderTestCaseFactory.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.pdsl.testcases;

import com.pdsl.gherkin.filter.TagFilterer;
import com.pdsl.specifications.PolymorphicDslTransformationException;
import com.pdsl.specifications.TaggedTestSpecification;
import com.pdsl.specifications.TestSpecification;
Expand Down Expand Up @@ -73,13 +74,13 @@ private List<TestCase> recursiveWalkAndCreateOnLeaf(TestSpecification testSpecif
}
return testCases;
} else {
TestCase testCase = new DefaultPdslTestCase(testSpecification.getName(), childTestBodyFragments, testSpecification.getOriginalTestResource());
if (!tags.isEmpty()) {
testCase = new DefaultTaggedTestCase(testCase, tags);
}
List<TestCase> singleTestCase = new ArrayList<>(1);
singleTestCase.add(testCase);
return singleTestCase;
TestCase testCase = new DefaultPdslTestCase(testSpecification.getName(), childTestBodyFragments, testSpecification.getOriginalTestResource());
if (!tags.isEmpty()) {
testCase = new DefaultTaggedTestCase(testCase, tags);
}
List<TestCase> singleTestCase = new ArrayList<>(1);
singleTestCase.add(testCase);
return singleTestCase;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,10 @@ private static List<PdslTestParams> convert(Collection<PdslTestParameter> parame
getInterpreterParams(config, p),
List.of(p.getTagExpression()),
p.getIncludesResources(),
p.getExcludesResources());
p.getExcludesResources(),
p.getTagFilterer(),
p.getTagExpression()
);
params.add(pdslTestParams);
}
return params;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
package org.junit.jupiter.engine.descriptor;

import com.google.common.base.Preconditions;
import com.pdsl.gherkin.filter.GherkinTagFiltererAdapter;
import com.pdsl.gherkin.filter.GherkinTagsVisitorImpl;
import com.pdsl.gherkin.filter.TagFilterer;
import java.util.logging.Logger;
import org.antlr.v4.runtime.Lexer;
import org.antlr.v4.runtime.Parser;
import org.antlr.v4.runtime.tree.ParseTreeListener;
Expand All @@ -23,6 +27,7 @@
*/
public class PdslTestParameter {

private static final Logger logger = Logger.getLogger(PdslTestParameter.class.getName());
private final Optional<Class<? extends Parser>> recognizedByParser;
private final Optional<Class<? extends Lexer>> recognizedByLexer;
private final Class<? extends Parser> parser;
Expand All @@ -35,9 +40,10 @@ public class PdslTestParameter {
private final String[] excludesResources;
private final String startRule;
private final Optional<String> recognizerRule;
private final TagFilterer tagFilterer;

private PdslTestParameter(Builder builder) {
Preconditions.checkArgument((builder.listener.isPresent()
Preconditions.checkArgument((builder.listener.isPresent()
^ builder.visitor.isPresent() ^ builder.interpreterParams.isPresent()),
"You can only have one of a visitor, listener or list of interpreterDtos!");
this.parser = builder.parser;
Expand All @@ -52,6 +58,7 @@ private PdslTestParameter(Builder builder) {
this.recognizedByLexer = builder.recognizedByLexer;
this.recognizedByParser = builder.recognizedByParser;
this.interpreterParams = builder.interpreterParams;
this.tagFilterer = builder.tagFilterer;
}

public Optional<List<Interpreter>> getInterpreters() { return interpreterParams; }
Expand Down Expand Up @@ -100,7 +107,11 @@ public Optional<String> getRecognizerRule() {
return recognizerRule;
}

public static class Builder {
public TagFilterer getTagFilterer() {
return tagFilterer;
}

public static class Builder {
private Class<? extends Parser> parser;
private Class<? extends Lexer> lexer;
private Optional<Class<? extends Parser>> recognizedByParser = Optional.empty();
Expand All @@ -114,6 +125,15 @@ public static class Builder {
private Optional<String> recognizerRule = Optional.empty();
private Optional<List<Interpreter>> interpreterParams = Optional.empty();

private TagFilterer tagFilterer = new GherkinTagFiltererAdapter(new GherkinTagsVisitorImpl());

public Builder withTagFilterer(TagFilterer tagFilterer) {
this.tagFilterer = tagFilterer;
return this;
}



public Builder(
Class<? extends Lexer> lexer,
Class<? extends Parser> parser,
Expand Down Expand Up @@ -186,9 +206,22 @@ public Builder withVisitor(Supplier<? extends ParseTreeVisitor<?>> visitor) {
}

public Builder withTagExpression(String str) {
Preconditions.checkNotNull(str, "Tag expression cannot be null!");
Preconditions.checkNotNull(str, "Tag expression cannot be null!");
// Check if there are tags specified using the system property "tags".
String commandLineTags = System.getProperty("tags");
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use a different property than generic "tags" to avoid collisions with other frameworks:
pdsl.filter.tags

if (commandLineTags != null && !commandLineTags.isEmpty()) {
// If command-line tags are present, use them and log a message informing the user
// that the provided tag expression is being ignored.
this.tagExpression = commandLineTags;
logger.info("Overriding runner tags with tags provided in the command line {%s}".formatted(
commandLineTags));
logger.info("Ignoring provided tag expression {%s}".formatted(str));
} else {
// If no command-line tags are present, use the provided tag expression.
this.tagExpression = str;
return this;
}

return this;
}

public Builder withIncludedResources(String[] resources) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,16 @@ private static class PdslExtension extends PdslGherkinInvocationContextProvider

@Override
public Stream<TestTemplateInvocationContext> provideTestTemplateInvocationContexts(ExtensionContext context) {
String defaultTagExpression = "@comment_tag#2";
String commandLineTags = System.getProperty("tags");
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use pdsl.filter.tags instread

String effectiveTagExpression = (commandLineTags != null && !commandLineTags.isEmpty())
? commandLineTags
: defaultTagExpression;
return getInvocationContext(PdslConfigParameter.createGherkinPdslConfig(
List.of(
new PdslTestParameter.Builder(parseTreeListenerSupplier,
AllGrammarsLexer.class, AllGrammarsParser.class)
.withTagExpression("@comment_tag#2")
.withTagExpression(effectiveTagExpression)
.withIncludedResources(new String[] {"tags.feature"})
.build()
)
Expand Down
Loading
Loading