Skip to content
Merged
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
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]
### Fixed
- [JUnit Platform Engine] Corrupted junit-xml report when using `surefire.rerunFailingTestsCount` parameter ([#2709](https://github.com/cucumber/cucumber-jvm/pull/2709) M.P. Korstanje)

## [7.11.1] - 2023-01-27
### Added
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package io.cucumber.junit.platform.engine;

import io.cucumber.core.feature.FeatureParser;
import io.cucumber.core.gherkin.Feature;
import io.cucumber.core.resource.Resource;

import java.net.URI;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

class CachingFeatureParser {

private final Map<URI, Optional<Feature>> cache = new HashMap<>();
private final FeatureParser delegate;

CachingFeatureParser(FeatureParser delegate) {
this.delegate = delegate;
}

Optional<Feature> parseResource(Resource resource) {
return cache.computeIfAbsent(resource.getUri(), uri -> delegate.parseResource(resource));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@

class DiscoverySelectorResolver {

private static final Logger log = LoggerFactory.getLogger(FeatureResolver.class);
private static final Logger log = LoggerFactory.getLogger(DiscoverySelectorResolver.class);

private static boolean warnedWhenCucumberFeaturesPropertyIsUsed = false;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ class FeatureDescriptor extends AbstractTestDescriptor implements Node<CucumberE
this.feature = feature;
}

Feature getFeature() {
return feature;
}

private static void pruneRecursively(TestDescriptor descriptor, Predicate<TestDescriptor> toKeep) {
if (!toKeep.test(descriptor)) {
if (descriptor.isTest()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ final class FeatureResolver {

private static final Logger log = LoggerFactory.getLogger(FeatureResolver.class);

private final FeatureParser featureParser = new FeatureParser(UUID::randomUUID);
private final CachingFeatureParser featureParser = new CachingFeatureParser(new FeatureParser(UUID::randomUUID));
private final ResourceScanner<Feature> featureScanner = new ResourceScanner<>(
ClassLoaders::getDefaultClassLoader,
FeatureIdentifier::isFeature,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,17 +89,17 @@ public Type getType() {

static final class PickleDescriptor extends NodeDescriptor {

private final Pickle pickleEvent;
private final Pickle pickle;
private final Set<TestTag> tags;
private final Set<ExclusiveResource> exclusiveResources = new LinkedHashSet<>(0);

PickleDescriptor(
ConfigurationParameters parameters, UniqueId uniqueId, String name, TestSource source,
Pickle pickleEvent
Pickle pickle
) {
super(parameters, uniqueId, name, source);
this.pickleEvent = pickleEvent;
this.tags = getTags(pickleEvent);
this.pickle = pickle;
this.tags = getTags(pickle);
this.tags.forEach(tag -> {
ExclusiveResourceOptions exclusiveResourceOptions = new ExclusiveResourceOptions(parameters, tag);
exclusiveResourceOptions.exclusiveReadWriteResource()
Expand All @@ -111,6 +111,10 @@ static final class PickleDescriptor extends NodeDescriptor {
});
}

Pickle getPickle() {
return pickle;
}

private Set<TestTag> getTags(Pickle pickleEvent) {
return pickleEvent.getTags().stream()
.map(tag -> tag.substring(1))
Expand All @@ -136,7 +140,7 @@ public SkipResult shouldBeSkipped(CucumberEngineExecutionContext context) {

private Optional<SkipResult> shouldBeSkippedByTagFilter(CucumberEngineExecutionContext context) {
return context.getOptions().tagFilter().map(expression -> {
if (expression.evaluate(pickleEvent.getTags())) {
if (expression.evaluate(pickle.getTags())) {
return SkipResult.doNotSkip();
}
return SkipResult
Expand All @@ -148,7 +152,7 @@ private Optional<SkipResult> shouldBeSkippedByTagFilter(CucumberEngineExecutionC

private Optional<SkipResult> shouldBeSkippedByNameFilter(CucumberEngineExecutionContext context) {
return context.getOptions().nameFilter().map(pattern -> {
if (pattern.matcher(pickleEvent.getName()).matches()) {
if (pattern.matcher(pickle.getName()).matches()) {
return SkipResult.doNotSkip();
}
return SkipResult
Expand All @@ -161,7 +165,7 @@ private Optional<SkipResult> shouldBeSkippedByNameFilter(CucumberEngineExecution
public CucumberEngineExecutionContext execute(
CucumberEngineExecutionContext context, DynamicTestExecutor dynamicTestExecutor
) {
context.runTestCase(pickleEvent);
context.runTestCase(pickle);
return context;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package io.cucumber.junit.platform.engine;

import io.cucumber.core.gherkin.Feature;
import io.cucumber.core.gherkin.Pickle;
import io.cucumber.core.logging.LogRecordListener;
import io.cucumber.junit.platform.engine.NodeDescriptor.PickleDescriptor;
import io.cucumber.junit.platform.engine.nofeatures.NoFeatures;
Expand All @@ -23,6 +25,7 @@
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
Expand All @@ -33,6 +36,7 @@
import java.util.logging.Level;
import java.util.logging.LogRecord;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static io.cucumber.junit.platform.engine.Constants.FEATURES_PROPERTY_NAME;
import static java.util.Collections.singleton;
Expand Down Expand Up @@ -382,15 +386,54 @@ void resolveRequestWithMultipleUniqueIdSelector() {
.collect(toSet()));
}

@Test
void resolveRequestWithMultipleUniqueIdSelectorFromTheSameFeature() {
Set<UniqueId> selectors = new HashSet<>();

DiscoverySelector resource = selectDirectory(
"src/test/resources/io/cucumber/junit/platform/engine/feature-with-outline.feature");
selectAllPickles(resource).forEach(selectors::add);

EngineDiscoveryRequest discoveryRequest = new SelectorRequest(
selectors.stream()
.map(DiscoverySelectors::selectUniqueId)
.collect(Collectors.toList()));

resolver.resolveSelectors(discoveryRequest, testDescriptor);

Set<String> pickleIdsFromFeature = testDescriptor.getDescendants()
.stream()
.filter(FeatureDescriptor.class::isInstance)
.map(FeatureDescriptor.class::cast)
.map(FeatureDescriptor::getFeature)
.map(Feature::getPickles)
.flatMap(Collection::stream)
.map(Pickle::getId)
.collect(toSet());

Set<String> pickleIdsFromPickles = testDescriptor.getDescendants()
.stream()
.filter(PickleDescriptor.class::isInstance)
.map(PickleDescriptor.class::cast)
.map(PickleDescriptor::getPickle)
.map(Pickle::getId)
.collect(toSet());

assertEquals(pickleIdsFromFeature, pickleIdsFromPickles);
}

private Optional<UniqueId> selectSomePickle(DiscoverySelector resource) {
return selectAllPickles(resource).findFirst();
}

private Stream<UniqueId> selectAllPickles(DiscoverySelector resource) {
EngineDiscoveryRequest discoveryRequest = new SelectorRequest(resource);
resolver.resolveSelectors(discoveryRequest, testDescriptor);
Set<? extends TestDescriptor> descendants = testDescriptor.getDescendants();
resetTestDescriptor();
return descendants.stream()
.filter(PickleDescriptor.class::isInstance)
.map(TestDescriptor::getUniqueId)
.findFirst();
.map(TestDescriptor::getUniqueId);
}

@Test
Expand Down