diff --git a/documentation/src/docs/asciidoc/release-notes/release-notes-5.12.0-M1.adoc b/documentation/src/docs/asciidoc/release-notes/release-notes-5.12.0-M1.adoc index aabaedaf61e..520da97eef4 100644 --- a/documentation/src/docs/asciidoc/release-notes/release-notes-5.12.0-M1.adoc +++ b/documentation/src/docs/asciidoc/release-notes/release-notes-5.12.0-M1.adoc @@ -34,6 +34,7 @@ JUnit repository on GitHub. * Add support for passing line and column number to `ConsoleLauncher` via `--select-file` and `--select-resource`. * `ConsoleLauncher` now accepts multiple values for all `--select` options. +* Add `--select-unique-id` support to ConsoleLauncher. [[release-notes-5.12.0-M1-junit-jupiter]] diff --git a/junit-platform-console/src/main/java/org/junit/platform/console/options/SelectorConverter.java b/junit-platform-console/src/main/java/org/junit/platform/console/options/SelectorConverter.java index 6f180318570..0ef1351722c 100644 --- a/junit-platform-console/src/main/java/org/junit/platform/console/options/SelectorConverter.java +++ b/junit-platform-console/src/main/java/org/junit/platform/console/options/SelectorConverter.java @@ -17,6 +17,7 @@ import static org.junit.platform.engine.discovery.DiscoverySelectors.selectMethod; import static org.junit.platform.engine.discovery.DiscoverySelectors.selectModule; import static org.junit.platform.engine.discovery.DiscoverySelectors.selectPackage; +import static org.junit.platform.engine.discovery.DiscoverySelectors.selectUniqueId; import static org.junit.platform.engine.discovery.DiscoverySelectors.selectUri; import java.net.URI; @@ -34,6 +35,7 @@ import org.junit.platform.engine.discovery.MethodSelector; import org.junit.platform.engine.discovery.ModuleSelector; import org.junit.platform.engine.discovery.PackageSelector; +import org.junit.platform.engine.discovery.UniqueIdSelector; import org.junit.platform.engine.discovery.UriSelector; import picocli.CommandLine.ITypeConverter; @@ -113,6 +115,13 @@ public IterationSelector convert(String value) { } } + static class UniqueId implements ITypeConverter { + @Override + public UniqueIdSelector convert(String value) { + return selectUniqueId(value); + } + } + static class Identifier implements ITypeConverter { @Override public DiscoverySelectorIdentifier convert(String value) { diff --git a/junit-platform-console/src/main/java/org/junit/platform/console/options/TestDiscoveryOptions.java b/junit-platform-console/src/main/java/org/junit/platform/console/options/TestDiscoveryOptions.java index ab9fe3027dd..cf638876466 100644 --- a/junit-platform-console/src/main/java/org/junit/platform/console/options/TestDiscoveryOptions.java +++ b/junit-platform-console/src/main/java/org/junit/platform/console/options/TestDiscoveryOptions.java @@ -35,6 +35,7 @@ import org.junit.platform.engine.discovery.MethodSelector; import org.junit.platform.engine.discovery.ModuleSelector; import org.junit.platform.engine.discovery.PackageSelector; +import org.junit.platform.engine.discovery.UniqueIdSelector; import org.junit.platform.engine.discovery.UriSelector; /** @@ -58,6 +59,7 @@ public class TestDiscoveryOptions { private List selectedMethods = emptyList(); private List selectedClasspathResources = emptyList(); private List selectedIterations = emptyList(); + private List selectedUniqueIds = emptyList(); private List selectorIdentifiers = emptyList(); private List includedClassNamePatterns = singletonList(STANDARD_INCLUDE_PATTERN); @@ -182,6 +184,14 @@ public void setSelectedIterations(List selectedIterations) { this.selectedIterations = selectedIterations; } + public List getSelectedUniqueIds() { + return selectedUniqueIds; + } + + public void setSelectedUniqueId(List selectedUniqueIds) { + this.selectedUniqueIds = selectedUniqueIds; + } + public List getSelectorIdentifiers() { return selectorIdentifiers; } diff --git a/junit-platform-console/src/main/java/org/junit/platform/console/options/TestDiscoveryOptionsMixin.java b/junit-platform-console/src/main/java/org/junit/platform/console/options/TestDiscoveryOptionsMixin.java index dfeb571875a..73e0b61e0d6 100644 --- a/junit-platform-console/src/main/java/org/junit/platform/console/options/TestDiscoveryOptionsMixin.java +++ b/junit-platform-console/src/main/java/org/junit/platform/console/options/TestDiscoveryOptionsMixin.java @@ -27,6 +27,7 @@ import org.junit.platform.engine.discovery.MethodSelector; import org.junit.platform.engine.discovery.ModuleSelector; import org.junit.platform.engine.discovery.PackageSelector; +import org.junit.platform.engine.discovery.UniqueIdSelector; import org.junit.platform.engine.discovery.UriSelector; import picocli.CommandLine; @@ -146,6 +147,11 @@ static class SelectorOptions { "-select-iteration" }, arity = "1..*", hidden = true, converter = SelectorConverter.Iteration.class) private final List selectedIterations2 = new ArrayList<>(); + @Option(names = { "--select-unique-id", + "--uid" }, paramLabel = "UNIQUE-ID", arity = "1..*", converter = SelectorConverter.UniqueId.class, // + description = "Select a unique id for test discovery. This option can be repeated.") + private final List selectedUniqueIds = new ArrayList<>(); + @Option(names = "--select", paramLabel = "PREFIX:VALUE", arity = "1..*", converter = SelectorConverter.Identifier.class, // description = "Select via a prefixed identifier (e.g. method:com.acme.Foo#m selects the m() method in the com.acme.Foo class). " + "This option can be repeated.") @@ -168,6 +174,7 @@ private void applyTo(TestDiscoveryOptions result) { result.setSelectedClasspathResources( merge(this.selectedClasspathResources, this.selectedClasspathResources2)); result.setSelectedIterations(merge(this.selectedIterations, this.selectedIterations2)); + result.setSelectedUniqueId(this.selectedUniqueIds); result.setSelectorIdentifiers(this.selectorIdentifiers); } } @@ -210,12 +217,12 @@ static class FilterOptions { @Option(names = { "--include-methodname" }, paramLabel = "PATTERN", arity = "1", description = "Provide a regular expression to include only methods whose fully qualified names without parameters match. " // + "When this option is repeated, all patterns will be combined using OR semantics.") - private List includeMethodNamePatterns = new ArrayList<>(); + private final List includeMethodNamePatterns = new ArrayList<>(); @Option(names = { "--exclude-methodname" }, paramLabel = "PATTERN", arity = "1", description = "Provide a regular expression to exclude those methods whose fully qualified names without parameters match. " // + "When this option is repeated, all patterns will be combined using OR semantics.") - private List excludeMethodNamePatterns = new ArrayList<>(); + private final List excludeMethodNamePatterns = new ArrayList<>(); @Option(names = { "-t", "--include-tag" }, paramLabel = "TAG", arity = "1", description = "Provide a tag or tag expression to include only tests whose tags match. " diff --git a/platform-tests/src/test/java/org/junit/platform/console/options/CommandLineOptionsParsingTests.java b/platform-tests/src/test/java/org/junit/platform/console/options/CommandLineOptionsParsingTests.java index 15170bdd376..dd5d01a479a 100644 --- a/platform-tests/src/test/java/org/junit/platform/console/options/CommandLineOptionsParsingTests.java +++ b/platform-tests/src/test/java/org/junit/platform/console/options/CommandLineOptionsParsingTests.java @@ -26,6 +26,7 @@ import static org.junit.platform.engine.discovery.DiscoverySelectors.selectMethod; import static org.junit.platform.engine.discovery.DiscoverySelectors.selectModule; import static org.junit.platform.engine.discovery.DiscoverySelectors.selectPackage; +import static org.junit.platform.engine.discovery.DiscoverySelectors.selectUniqueId; import static org.junit.platform.engine.discovery.DiscoverySelectors.selectUri; import java.io.File; @@ -555,6 +556,24 @@ void parseInvalidIterationSelectors() { assertOptionWithMissingRequiredArgumentThrowsException("-i", "--select-iteration"); } + @ParameterizedTest + @EnumSource + void parseValidUniqueIdSelectors(ArgsType type) { + // @formatter:off + assertAll( + () -> assertEquals(List.of(selectUniqueId("[engine:junit-jupiter]/[class:MyClass]/[method:myMethod]")), type.parseArgLine("--uid [engine:junit-jupiter]/[class:MyClass]/[method:myMethod]").discovery.getSelectedUniqueIds()), + () -> assertEquals(List.of(selectUniqueId("[engine:junit-jupiter]/[class:MyClass]/[method:myMethod]")), type.parseArgLine("--select-unique-id [engine:junit-jupiter]/[class:MyClass]/[method:myMethod]").discovery.getSelectedUniqueIds()), + () -> assertEquals(List.of(selectUniqueId("[engine:junit-jupiter]/[class:MyClass1]"), selectUniqueId("[engine:junit-jupiter]/[class:MyClass2]")), type.parseArgLine("--uid [engine:junit-jupiter]/[class:MyClass1] --uid [engine:junit-jupiter]/[class:MyClass2]").discovery.getSelectedUniqueIds()), + () -> assertEquals(List.of(selectUniqueId("[engine:junit-jupiter]/[class:MyClass1]"), selectUniqueId("[engine:junit-jupiter]/[class:MyClass2]")), type.parseArgLine("--uid [engine:junit-jupiter]/[class:MyClass1] [engine:junit-jupiter]/[class:MyClass2]").discovery.getSelectedUniqueIds()) + ); + // @formatter:on + } + + @Test + void parseInvalidUniqueIdSelectors() { + assertOptionWithMissingRequiredArgumentThrowsException("--uid", "--select-unique-id"); + } + @ParameterizedTest @EnumSource void parseClasspathScanningEntries(ArgsType type) { @@ -637,7 +656,8 @@ void parseValidSelectorIdentifier(ArgsType type) { () -> assertEquals(List.of(selectPackage("com.acme.foo")), parseIdentifiers(type,"--select package:com.acme.foo")), () -> assertEquals(List.of(selectModule("com.acme.foo")), parseIdentifiers(type,"--select module:com.acme.foo")), () -> assertEquals(List.of(selectDirectory("foo/bar")), parseIdentifiers(type,"--select directory:foo/bar")), - () -> assertEquals(List.of(selectFile("foo.txt"), selectUri("file:///foo.txt")), parseIdentifiers(type,"--select file:foo.txt --select uri:file:///foo.txt")) + () -> assertEquals(List.of(selectFile("foo.txt"), selectUri("file:///foo.txt")), parseIdentifiers(type,"--select file:foo.txt --select uri:file:///foo.txt")), + () -> assertEquals(List.of(selectUniqueId("[engine:junit-jupiter]/[class:MyClass]/[method:myMethod]")), parseIdentifiers(type,"--select uid:[engine:junit-jupiter]/[class:MyClass]/[method:myMethod]")) ); // @formatter:on }