forked from cucumber/common
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
some initial commits towards https://github.com/cucumber/common/issue…
- Loading branch information
1 parent
2953f39
commit b0501c1
Showing
6 changed files
with
408 additions
and
0 deletions.
There are no files selected for viewing
34 changes: 34 additions & 0 deletions
34
gherkin-utils/java/src/main/java/org/gherkin/util/DefaultFilters.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
package org.gherkin.util; | ||
|
||
import io.cucumber.messages.types.Background; | ||
import io.cucumber.messages.types.Feature; | ||
import io.cucumber.messages.types.Rule; | ||
import io.cucumber.messages.types.Scenario; | ||
import io.cucumber.messages.types.Step; | ||
|
||
public class DefaultFilters implements IFilters { | ||
@Override | ||
public boolean acceptScenario(Scenario scenario) { | ||
return true; | ||
} | ||
|
||
@Override | ||
public boolean acceptStep(Step step) { | ||
return true; | ||
} | ||
|
||
@Override | ||
public boolean acceptBackground(Background background) { | ||
return true; | ||
} | ||
|
||
@Override | ||
public boolean acceptRule(Rule rule) { | ||
return true; | ||
} | ||
|
||
@Override | ||
public boolean acceptFeature(Feature feature) { | ||
return true; | ||
} | ||
} |
34 changes: 34 additions & 0 deletions
34
gherkin-utils/java/src/main/java/org/gherkin/util/DefaultHandlers.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
package org.gherkin.util; | ||
|
||
import io.cucumber.messages.types.Background; | ||
import io.cucumber.messages.types.Feature; | ||
import io.cucumber.messages.types.Rule; | ||
import io.cucumber.messages.types.Scenario; | ||
import io.cucumber.messages.types.Step; | ||
|
||
public class DefaultHandlers implements IHandlers { | ||
@Override | ||
public void handleStep(Step step) { | ||
// no-op | ||
} | ||
|
||
@Override | ||
public void handleScenario(Scenario scenario) { | ||
// no-op | ||
} | ||
|
||
@Override | ||
public void handleBackground(Background background) { | ||
// no-op | ||
} | ||
|
||
@Override | ||
public void handleRule(Rule rule) { | ||
// no-op | ||
} | ||
|
||
@Override | ||
public void handleFeature(Feature feature) { | ||
// no-op | ||
} | ||
} |
276 changes: 276 additions & 0 deletions
276
gherkin-utils/java/src/main/java/org/gherkin/util/GherkinDocumentWalker.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,276 @@ | ||
package org.gherkin.util; | ||
|
||
import java.util.ArrayList; | ||
import java.util.List; | ||
import java.util.Map; | ||
import java.util.Objects; | ||
import java.util.Set; | ||
import java.util.function.Function; | ||
import java.util.stream.Collectors; | ||
|
||
import io.cucumber.messages.types.Background; | ||
import io.cucumber.messages.types.Feature; | ||
import io.cucumber.messages.types.FeatureChild; | ||
import io.cucumber.messages.types.GherkinDocument; | ||
import io.cucumber.messages.types.Rule; | ||
import io.cucumber.messages.types.RuleChild; | ||
import io.cucumber.messages.types.Scenario; | ||
import io.cucumber.messages.types.Step; | ||
import io.cucumber.messages.types.Tag; | ||
|
||
public class GherkinDocumentWalker { | ||
private final IFilters filters; | ||
private final IHandlers handlers; | ||
|
||
GherkinDocumentWalker(IFilters filters, IHandlers handlers) { | ||
this.filters = filters == null ? new DefaultFilters() : filters; | ||
this.handlers = handlers == null ? new DefaultHandlers() : handlers; | ||
} | ||
|
||
GherkinDocumentWalker() { | ||
this.filters = new DefaultFilters(); | ||
this.handlers = new DefaultHandlers(); | ||
} | ||
|
||
public GherkinDocument walkGherkinDocument(GherkinDocument gherkinDocument) { | ||
if (gherkinDocument.getFeature() == null) { | ||
return null; | ||
} | ||
|
||
Feature feature = walkFeature(gherkinDocument.getFeature()); | ||
|
||
if (feature == null) { | ||
return null; | ||
} | ||
|
||
return new GherkinDocument(gherkinDocument.getUri(), gherkinDocument.getFeature(), | ||
gherkinDocument.getComments()); | ||
|
||
} | ||
|
||
protected Feature walkFeature(Feature feature) { | ||
List<FeatureChild> keptChildren = walkFeatureChildren(feature.getChildren()); | ||
|
||
handlers.handleFeature(feature); | ||
|
||
List<FeatureChild> backgroundKept = keptChildren.stream().filter(fc -> fc.getBackground() != null).collect(Collectors.toList()); | ||
|
||
if (filters.acceptFeature(feature) || !backgroundKept.isEmpty()) { | ||
return copyFeature( | ||
feature, | ||
feature.getChildren().stream().map((child) -> { | ||
if (child.getBackground() != null) { | ||
new FeatureChild(null, copyBackground(child.getBackground()), null); | ||
} | ||
if (child.getScenario() != null) { | ||
return new FeatureChild(null, null, copyScenario(child.getScenario())); | ||
} | ||
if (child.getRule() != null) { | ||
return new FeatureChild(copyRule(child.getRule(), child.getRule().getChildren()), null, null); | ||
} | ||
return null; | ||
}).collect(Collectors.toList())); | ||
} | ||
|
||
if (keptChildren.stream().anyMatch(Objects::nonNull)) { | ||
return copyFeature(feature, keptChildren); | ||
} | ||
return null; | ||
} | ||
|
||
private Feature copyFeature( | ||
Feature feature, | ||
List<FeatureChild> children | ||
) { | ||
return new Feature( | ||
feature.getLocation(), | ||
copyTags(feature.getTags()), | ||
feature.getLanguage(), | ||
feature.getKeyword(), | ||
feature.getName(), | ||
feature.getDescription(), | ||
filterFeatureChildren(feature, children)); | ||
} | ||
|
||
private List<Tag> copyTags(List<Tag> tags) { | ||
return tags.stream().map(tag -> new Tag(tag.getLocation(), tag.getName(), tag.getId())).collect(Collectors.toList()); | ||
} | ||
|
||
private List<FeatureChild> filterFeatureChildren( | ||
Feature feature, | ||
List<FeatureChild> children) { | ||
List<FeatureChild> copyChildren = new ArrayList<>(); | ||
Map<String, FeatureChild> scenariosKeptById = children.stream() | ||
.filter(child -> child.getScenario() != null) | ||
.collect(Collectors.toMap(fc -> fc.getScenario().getId(), Function.identity())); | ||
|
||
Map<String, FeatureChild> ruleKeptById = children.stream() | ||
.filter(child -> child.getRule() != null) | ||
.collect(Collectors.toMap(fc -> fc.getRule().getId(), Function.identity())); | ||
|
||
for (FeatureChild child : feature.getChildren()) { | ||
if (child.getBackground() != null) { | ||
copyChildren.add(new FeatureChild(null, child.getBackground(), null)); | ||
} | ||
if (child.getScenario() != null) { | ||
FeatureChild scenarioCopy = scenariosKeptById.get(child.getScenario().getId()); | ||
if (scenarioCopy != null) { | ||
copyChildren.add(scenarioCopy); | ||
} | ||
} | ||
if (child.getRule() != null) { | ||
FeatureChild ruleCopy = ruleKeptById.get(child.getRule().getId()); | ||
if (ruleCopy != null) { | ||
copyChildren.add(ruleCopy); | ||
} | ||
} | ||
} | ||
return copyChildren; | ||
} | ||
|
||
private List<FeatureChild> walkFeatureChildren(List<FeatureChild> children) { | ||
List<FeatureChild> childrenCopy = new ArrayList<>(); | ||
|
||
for (FeatureChild child : children) { | ||
Background backgroundCopy = null; | ||
Scenario scenarioCopy = null; | ||
Rule ruleCopy = null; | ||
|
||
if (child.getBackground() != null) { | ||
backgroundCopy = walkBackground(child.getBackground()); | ||
} | ||
if (child.getScenario() != null) { | ||
scenarioCopy = walkScenario(child.getScenario()); | ||
} | ||
if (child.getRule() != null) { | ||
ruleCopy = walkRule(child.getRule()); | ||
} | ||
|
||
if (backgroundCopy != null || scenarioCopy != null || ruleCopy != null) { | ||
childrenCopy.add(new FeatureChild(ruleCopy, | ||
backgroundCopy, | ||
scenarioCopy)); | ||
} | ||
} | ||
|
||
return childrenCopy; | ||
} | ||
|
||
protected Rule walkRule(Rule rule) { | ||
List<RuleChild> children = walkRuleChildren(rule.getChildren()); | ||
|
||
this.handlers.handleRule(rule); | ||
|
||
boolean backgroundKept = children.stream().anyMatch(child -> child != null && child.getBackground() != null); | ||
List<RuleChild> scenariosKept = children.stream().filter(child -> child != null && child.getScenario() != null).collect( | ||
Collectors.toList()); | ||
|
||
if (this.filters.acceptRule(rule) || backgroundKept) { | ||
return copyRule(rule, rule.getChildren()); | ||
} | ||
if (!scenariosKept.isEmpty()) { | ||
return copyRule(rule, scenariosKept); | ||
} | ||
return null; | ||
} | ||
|
||
private Rule copyRule(Rule rule, List<RuleChild> children) { | ||
return new Rule(rule.getLocation(), | ||
copyTags(rule.getTags()), | ||
rule.getKeyword(), | ||
rule.getName(), | ||
rule.getDescription(), | ||
filterRuleChildren(rule.getChildren(), children), | ||
rule.getId()); | ||
} | ||
|
||
private List<RuleChild> filterRuleChildren( | ||
List<RuleChild> children, | ||
List<RuleChild> childrenKept) { | ||
List<RuleChild> childrenCopy = new ArrayList<>(); | ||
Set<String> scenariosKeptIds = childrenKept | ||
.stream().filter(child -> child.getScenario() != null) | ||
.map(child -> child.getScenario().getId()) | ||
.collect(Collectors.toSet()); | ||
|
||
for (RuleChild child : children) { | ||
if (child.getBackground() != null) { | ||
childrenCopy.add(new RuleChild(copyBackground(child.getBackground()), null)); | ||
} | ||
if (child.getScenario() != null && scenariosKeptIds.contains(child.getScenario().getId())) { | ||
childrenCopy.add(new RuleChild(null, copyScenario(child.getScenario()))); | ||
} | ||
} | ||
return childrenCopy; | ||
} | ||
|
||
private List<RuleChild> walkRuleChildren(List<RuleChild> children) { | ||
List<RuleChild> childrenCopy = new ArrayList<>(); | ||
|
||
for (RuleChild child : children) { | ||
if (child.getBackground() != null) { | ||
childrenCopy.add(new RuleChild(walkBackground(child.getBackground()), null)); | ||
} | ||
if (child.getScenario() != null) { | ||
childrenCopy.add(new RuleChild(null, walkScenario(child.getScenario()))); | ||
} | ||
} | ||
return childrenCopy; | ||
} | ||
|
||
protected Background walkBackground(Background background) { | ||
List<Step> steps = walkAllSteps(background.getSteps()); | ||
handlers.handleBackground(background); | ||
|
||
if (this.filters.acceptBackground(background) || steps.stream().anyMatch(Objects::nonNull)) { | ||
return copyBackground(background); | ||
} | ||
return null; | ||
} | ||
|
||
private Background copyBackground(Background background) { | ||
return new Background(background.getLocation(), | ||
background.getKeyword(), | ||
background.getName(), | ||
background.getDescription(), | ||
background.getSteps().stream().map(step -> copyStep(step)).collect(Collectors.toList()), | ||
background.getId()); | ||
} | ||
|
||
protected Scenario walkScenario(Scenario scenario) { | ||
List<Step> steps = walkAllSteps(scenario.getSteps()); | ||
handlers.handleScenario(scenario); | ||
|
||
if (this.filters.acceptScenario(scenario) || steps.stream().anyMatch(Objects::nonNull)) { | ||
return copyScenario(scenario); | ||
} | ||
return null; | ||
} | ||
|
||
private Scenario copyScenario(Scenario scenario) { | ||
return new Scenario(scenario.getLocation(), | ||
copyTags(scenario.getTags()), | ||
scenario.getKeyword(), | ||
scenario.getName(), | ||
scenario.getDescription(), | ||
scenario.getSteps().stream().map(this::copyStep).collect(Collectors.toList()), | ||
scenario.getExamples(), | ||
scenario.getId()); | ||
} | ||
|
||
protected List<Step> walkAllSteps(List<Step> steps) { | ||
return steps.stream().map(step -> walkStep(step)).collect(Collectors.toList()); | ||
} | ||
|
||
protected Step walkStep(Step step) { | ||
handlers.handleStep(step); | ||
if (!filters.acceptStep(step)) { | ||
return null; | ||
} | ||
return copyStep(step); | ||
} | ||
|
||
private Step copyStep(Step step) { | ||
return new Step(step.getLocation(), step.getKeyword(), step.getText(), step.getDocString(), step.getDataTable(), step.getId()); | ||
} | ||
} |
15 changes: 15 additions & 0 deletions
15
gherkin-utils/java/src/main/java/org/gherkin/util/IFilters.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
package org.gherkin.util; | ||
|
||
import io.cucumber.messages.types.Background; | ||
import io.cucumber.messages.types.Feature; | ||
import io.cucumber.messages.types.Rule; | ||
import io.cucumber.messages.types.Scenario; | ||
import io.cucumber.messages.types.Step; | ||
|
||
public interface IFilters { | ||
boolean acceptScenario(Scenario scenario); | ||
boolean acceptStep(Step step); | ||
boolean acceptBackground(Background background); | ||
boolean acceptRule(Rule rule); | ||
boolean acceptFeature(Feature feature); | ||
} |
15 changes: 15 additions & 0 deletions
15
gherkin-utils/java/src/main/java/org/gherkin/util/IHandlers.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
package org.gherkin.util; | ||
|
||
import io.cucumber.messages.types.Background; | ||
import io.cucumber.messages.types.Feature; | ||
import io.cucumber.messages.types.Rule; | ||
import io.cucumber.messages.types.Scenario; | ||
import io.cucumber.messages.types.Step; | ||
|
||
public interface IHandlers { | ||
void handleStep(Step step); | ||
void handleScenario(Scenario scenario); | ||
void handleBackground(Background background); | ||
void handleRule(Rule rule); | ||
void handleFeature(Feature feature); | ||
} |
Oops, something went wrong.