Skip to content

Commit 29b6ddd

Browse files
committed
Return subcommand execution result (instead of null)
When explicitly specifying the `execute` subcommand as advised by: > WARNING: Delegated to the 'execute' command. > This behaviour has been deprecated and will be removed in a future release. > Please use the 'execute' command directly. ... it happens that `ConsoleLauncher.run` returns a `CommandResult` whose `getValue` method always returns `Optional.empty()` instead of the expected (non-empty) `Optional<TestExecutionSummary>`. It turns out that, when `picoli` executes a _subcommand_, it doesn't propagate the return value to the parent `CommandLine`, whose `getExecutionResult` method then returns `null`. There was a question about it last year (remkop/picocli#1656) answered by the [user manual](https://picocli.info/#_executing_commands_with_subcommands): > The `ParseResult` can be used to get the return value from a Callable > or Method subcommand: > ```java > // getting return value from Callable or Method command > Object topResult = cmd.getExecutionResult(); > > // getting return value from Callable or Method subcommand > ParseResult parseResult = cmd.getParseResult(); > if (parseResult.subcommand() != null) { > CommandLine sub = parseResult.subcommand().commandSpec().commandLine(); > Object subResult = sub.getExecutionResult(); > } ``` The present change therefore consists in implementing it. Note: prior to the change, presently adapted tests (now parameterized so as to cover both forms) were all failing on: ```java java.lang.IllegalStateException: TestExecutionSummary not assigned. Exit code is: 0 at app//org.junit.platform.console.ConsoleLauncherWrapperResult.checkTestExecutionSummaryState(ConsoleLauncherWrapperResult.java:42) at app//org.junit.platform.console.ConsoleLauncherWrapperResult.getTestsFoundCount(ConsoleLauncherWrapperResult.java:102) ```
1 parent ffab3a3 commit 29b6ddd

File tree

2 files changed

+35
-16
lines changed

2 files changed

+35
-16
lines changed

junit-platform-console/src/main/java/org/junit/platform/console/options/MainCommand.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,15 @@ private static CommandResult<Object> runCommand(PrintWriter out, PrintWriter err
135135
.setOut(out) //
136136
.setErr(err) //
137137
.execute(args);
138-
return CommandResult.create(exitCode, commandLine.getExecutionResult());
138+
return CommandResult.create(exitCode, getLikelyExecutedCommand(commandLine).getExecutionResult());
139+
}
140+
141+
/**
142+
* Gets the most likely executed subcommand if any, or the main command otherwise.
143+
* @see <a href="https://picocli.info/#_executing_commands_with_subcommands">Executing Commands with Subcommands</a>
144+
*/
145+
private static CommandLine getLikelyExecutedCommand(final CommandLine commandLine) {
146+
return Optional.ofNullable(commandLine.getParseResult().subcommand()).map(
147+
parseResult -> parseResult.commandSpec().commandLine()).orElse(commandLine);
139148
}
140149
}

platform-tests/src/test/java/org/junit/platform/console/ConsoleLauncherIntegrationTests.java

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
import static org.junit.jupiter.api.Assertions.assertEquals;
1717

1818
import org.junit.jupiter.api.Test;
19+
import org.junit.jupiter.params.ParameterizedTest;
20+
import org.junit.jupiter.params.provider.ValueSource;
1921

2022
/**
2123
* @since 1.0
@@ -32,16 +34,23 @@ void executeWithoutArgumentsFailsAndPrintsHelpInformation() {
3234
);
3335
}
3436

35-
@Test
36-
void executeWithoutExcludeClassnameOptionDoesNotExcludeClassesAndMustIncludeAllClassesMatchingTheStandardClassnamePattern() {
37-
String[] args = { "-e", "junit-jupiter", "-p", "org.junit.platform.console.subpackage" };
37+
@ParameterizedTest
38+
@ValueSource(strings = { "-e junit-jupiter -p org.junit.platform.console.subpackage",
39+
"execute -e junit-jupiter -p org.junit.platform.console.subpackage" })
40+
void executeWithoutExcludeClassnameOptionDoesNotExcludeClassesAndMustIncludeAllClassesMatchingTheStandardClassnamePattern(
41+
final String line) {
42+
String[] args = line.split(" ");
3843
assertEquals(9, new ConsoleLauncherWrapper().execute(args).getTestsFoundCount());
3944
}
4045

41-
@Test
42-
void executeWithExcludeClassnameOptionExcludesClasses() {
43-
String[] args = { "-e", "junit-jupiter", "-p", "org.junit.platform.console.subpackage", "--exclude-classname",
44-
"^org\\.junit\\.platform\\.console\\.subpackage\\..*" };
46+
@ParameterizedTest
47+
@ValueSource(strings = {
48+
"-e junit-jupiter -p org.junit.platform.console.subpackage --exclude-classname"
49+
+ " ^org\\.junit\\.platform\\.console\\.subpackage\\..*",
50+
"execute -e junit-jupiter -p org.junit.platform.console.subpackage --exclude-classname"
51+
+ " ^org\\.junit\\.platform\\.console\\.subpackage\\..*" })
52+
void executeWithExcludeClassnameOptionExcludesClasses(final String line) {
53+
String[] args = line.split(" ");
4554
var result = new ConsoleLauncherWrapper().execute(args);
4655
assertAll("all subpackage test classes are excluded by the class name filter", //
4756
() -> assertArrayEquals(args, result.args), //
@@ -50,17 +59,18 @@ void executeWithExcludeClassnameOptionExcludesClasses() {
5059
);
5160
}
5261

53-
@Test
54-
void executeSelectingModuleNames() {
55-
String[] args1 = { "-e", "junit-jupiter", "-o", "java.base" };
62+
@ParameterizedTest
63+
@ValueSource(strings = { "-e junit-jupiter -o java.base", "-e junit-jupiter --select-module java.base",
64+
"execute -e junit-jupiter -o java.base", "execute -e junit-jupiter --select-module java.base" })
65+
void executeSelectingModuleNames(final String line) {
66+
String[] args1 = line.split(" ");
5667
assertEquals(0, new ConsoleLauncherWrapper().execute(args1).getTestsFoundCount());
57-
String[] args2 = { "-e", "junit-jupiter", "--select-module", "java.base" };
58-
assertEquals(0, new ConsoleLauncherWrapper().execute(args2).getTestsFoundCount());
5968
}
6069

61-
@Test
62-
void executeScanModules() {
63-
String[] args1 = { "-e", "junit-jupiter", "--scan-modules" };
70+
@ParameterizedTest
71+
@ValueSource(strings = { "-e junit-jupiter --scan-modules", "execute -e junit-jupiter --scan-modules" })
72+
void executeScanModules(final String line) {
73+
String[] args1 = line.split(" ");
6474
assertEquals(0, new ConsoleLauncherWrapper().execute(args1).getTestsFoundCount());
6575
}
6676

0 commit comments

Comments
 (0)