Skip to content

Commit f800c60

Browse files
committed
[JUnit Platform] Support discovery selectors with FilePosition
There was no good way to discover and execute a single test when using a file based test system like Cucumber. Recently JUnit added support for file position in the `FileSelector` and `ClasspathResourceSelector`. See: junit-team/junit5#2146 This implements a filter that prunes all scenarios that do not match the `FilePosition` from the discovery selector. This feature itself is not new. It was already implemented for the `UriSelector`.
1 parent ff54269 commit f800c60

File tree

4 files changed

+80
-9
lines changed

4 files changed

+80
-9
lines changed

CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
88
## [Unreleased] (In Git)
99

1010
### Added
11+
* [JUnit Platform] Support discovery selectors with FilePosition ([2121](https://github.com/cucumber/cucumber-jvm/pull/2121) M.P. Korstanje)
1112

1213
### Changed
14+
* [JUnit Platform] Update dependency org.junit.platform:junit-platform-engine to v1.7.0
1315

1416
### Deprecated
1517

junit-platform-engine/README.md

+8-1
Original file line numberDiff line numberDiff line change
@@ -237,10 +237,17 @@ Supported `DiscoverySelector`s are:
237237
The only supported `DiscoveryFilter` is the `PackageNameFilter` and only when
238238
features are selected from the classpath.
239239

240+
### Selecting individual scenarios, rules and examples
241+
242+
The `FileSelector` and `ClasspathResourceSelector` support the `FilePosition`.
243+
244+
* `DiscoverySelectors.selectClasspathResource("rule.feature", FilePosition.from(5))`
245+
* `DiscoverySelectors.selectFile("rule.feature", FilePosition.from(5))`
246+
240247
The `UriSelector` supports URI's with a `line` query parameter:
241248
- `classpath:/com/example/example.feature?line=20`
242249
- `file:/path/to/com/example/example.feature?line=20`
243-
250+
244251
Any `TestDescriptor` that matches the line *and* its descendants will be
245252
included in the discovery result.
246253

junit-platform-engine/src/main/java/io/cucumber/junit/platform/engine/FeatureResolver.java

+25-8
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
import org.junit.platform.engine.support.descriptor.FileSource;
2424

2525
import java.net.URI;
26-
import java.nio.file.Path;
2726
import java.util.Optional;
2827
import java.util.UUID;
2928
import java.util.function.Predicate;
@@ -62,16 +61,20 @@ static FeatureResolver createFeatureResolver(
6261
}
6362

6463
void resolveFile(FileSelector selector) {
65-
resolvePath(selector.getPath());
66-
}
64+
Predicate<TestDescriptor> keepTestOnSelectedLine = selector.getPosition()
65+
.map(filePosition -> filePosition.getLine())
66+
.map(FeatureResolver::testDescriptorOnLine)
67+
.orElse(testDescriptor -> true);
6768

68-
private void resolvePath(Path path) {
6969
featureScanner
70-
.scanForResourcesPath(path)
70+
.scanForResourcesPath(selector.getPath())
7171
.stream()
7272
.sorted(comparing(Feature::getUri))
7373
.map(this::createFeatureDescriptor)
74-
.forEach(engineDescriptor::mergeFeature);
74+
.forEach(featureDescriptor -> {
75+
featureDescriptor.prune(keepTestOnSelectedLine);
76+
engineDescriptor.mergeFeature(featureDescriptor);
77+
});
7578
}
7679

7780
private FeatureDescriptor createFeatureDescriptor(Feature feature) {
@@ -137,7 +140,12 @@ private String getNameOrKeyWord(Node node) {
137140
}
138141

139142
void resolveDirectory(DirectorySelector selector) {
140-
resolvePath(selector.getPath());
143+
featureScanner
144+
.scanForResourcesPath(selector.getPath())
145+
.stream()
146+
.sorted(comparing(Feature::getUri))
147+
.map(this::createFeatureDescriptor)
148+
.forEach(engineDescriptor::mergeFeature);
141149
}
142150

143151
void resolvePackageResource(PackageSelector selector) {
@@ -163,12 +171,21 @@ void resolveClass(ClassSelector classSelector) {
163171

164172
void resolveClasspathResource(ClasspathResourceSelector selector) {
165173
String classpathResourceName = selector.getClasspathResourceName();
174+
175+
Predicate<TestDescriptor> keepTestOnSelectedLine = selector.getPosition()
176+
.map(filePosition -> filePosition.getLine())
177+
.map(FeatureResolver::testDescriptorOnLine)
178+
.orElse(testDescriptor -> true);
179+
166180
featureScanner
167181
.scanForClasspathResource(classpathResourceName, packageFilter)
168182
.stream()
169183
.sorted(comparing(Feature::getUri))
170184
.map(this::createFeatureDescriptor)
171-
.forEach(engineDescriptor::mergeFeature);
185+
.forEach(featureDescriptor -> {
186+
featureDescriptor.prune(keepTestOnSelectedLine);
187+
engineDescriptor.mergeFeature(featureDescriptor);
188+
});
172189
}
173190

174191
void resolveClasspathRoot(ClasspathRootSelector selector) {

junit-platform-engine/src/test/java/io/cucumber/junit/platform/engine/DiscoverySelectorResolverTest.java

+45
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import org.junit.platform.engine.TestDescriptor;
1212
import org.junit.platform.engine.UniqueId;
1313
import org.junit.platform.engine.discovery.DiscoverySelectors;
14+
import org.junit.platform.engine.discovery.FilePosition;
1415
import org.junit.platform.engine.discovery.UniqueIdSelector;
1516

1617
import java.io.File;
@@ -62,6 +63,28 @@ void resolveRequestWithClasspathResourceSelector() {
6263
assertEquals(1, testDescriptor.getChildren().size());
6364
}
6465

66+
@Test
67+
void resolveRequestWithClasspathResourceSelectorAndFilePosition() {
68+
DiscoverySelector resource = selectClasspathResource("io/cucumber/junit/platform/engine/rule.feature", FilePosition.from(5));
69+
EngineDiscoveryRequest discoveryRequest = new SelectorRequest(resource);
70+
resolver.resolveSelectors(discoveryRequest, testDescriptor);
71+
assertEquals(1L, testDescriptor.getDescendants()
72+
.stream()
73+
.filter(TestDescriptor::isTest)
74+
.count());
75+
}
76+
77+
@Test
78+
void resolveRequestWithClasspathResourceSelectorAndFilePositionOfContainer() {
79+
DiscoverySelector resource = selectClasspathResource("io/cucumber/junit/platform/engine/rule.feature", FilePosition.from(3));
80+
EngineDiscoveryRequest discoveryRequest = new SelectorRequest(resource);
81+
resolver.resolveSelectors(discoveryRequest, testDescriptor);
82+
assertEquals(2L, testDescriptor.getDescendants()
83+
.stream()
84+
.filter(TestDescriptor::isTest)
85+
.count());
86+
}
87+
6588
@Test
6689
void resolveRequestWithMultipleClasspathResourceSelector() {
6790
DiscoverySelector resource1 = selectClasspathResource("io/cucumber/junit/platform/engine/single.feature");
@@ -155,6 +178,28 @@ void resolveRequestWithFileSelector() {
155178
assertEquals(1, testDescriptor.getChildren().size());
156179
}
157180

181+
@Test
182+
void resolveRequestWithFileSelectorAndPosition() {
183+
DiscoverySelector resource = selectFile("src/test/resources/io/cucumber/junit/platform/engine/rule.feature", FilePosition.from(5));
184+
EngineDiscoveryRequest discoveryRequest = new SelectorRequest(resource);
185+
resolver.resolveSelectors(discoveryRequest, testDescriptor);
186+
assertEquals(1L, testDescriptor.getDescendants()
187+
.stream()
188+
.filter(TestDescriptor::isTest)
189+
.count());
190+
}
191+
192+
@Test
193+
void resolveRequestWithFileSelectorAndPositionOfContainer() {
194+
DiscoverySelector resource = selectFile("src/test/resources/io/cucumber/junit/platform/engine/rule.feature", FilePosition.from(3));
195+
EngineDiscoveryRequest discoveryRequest = new SelectorRequest(resource);
196+
resolver.resolveSelectors(discoveryRequest, testDescriptor);
197+
assertEquals(2L, testDescriptor.getDescendants()
198+
.stream()
199+
.filter(TestDescriptor::isTest)
200+
.count());
201+
}
202+
158203
@Test
159204
void resolveRequestWithDirectorySelector() {
160205
DiscoverySelector resource = selectDirectory("src/test/resources/io/cucumber/junit/platform/engine");

0 commit comments

Comments
 (0)