Skip to content

boolean @Option with default value "true" is set to 'false' when --option=true passed #2474

@PavelKamozin-DW

Description

@PavelKamozin-DW

Greetings,

I have one question related to the boolean @option with a default value of "true".

Let's say we have a command class:

import picocli.CommandLine;

@CommandLine.Command(name = "demo-command", description = "Demo for a default boolean value == true")
public class MyCommand {
	
	@CommandLine.Option(names = {"--use-ssl"}, description = "Use SSL.", defaultValue = "true")
    private boolean usesSSL;
	
}

I created a test for it:

public class MyCommandTest {
    private CommandLine cli;
    private MyCommand command;
    private StringWriter errorWriter;

    @BeforeEach
    public void setup() {
        command = Mockito.spy(MyCommand.class);
        errorWriter = new StringWriter();
        cli = new CommandLine(command).setErr(new PrintWriter(errorWriter));
        Mockito.doNothing().when(command).run();
    }
	
	
    @Test
    public void testBooleanOptionDefaultTrueSetting() {
        cli.execute("--use-ssl", "true");
        String errorOutput = errorWriter.toString();
        assertTrue(command.getConfig().isUsesSSL());
    }
}

But I get the error:

org.opentest4j.AssertionFailedError: 
Expected :true
Actual   :false

errorOutput contains the message 'Unmatched argument at index 1: 'true'

After quick debugging, it seems the problem is in this part of the code:

	/info/picocli/picocli/4.7.5/picocli-4.7.5-sources.jar!/picocli/CommandLine.java:13776 (version 4.7.5)
	            while (!args.isEmpty()) {
                if (endOfOptions) {
                    processRemainderAsPositionalParameters(required, initialized, args);
                    return;
                }
                String originalArg = args.pop();
                String arg = smartUnquoteIfEnabled(originalArg);
                boolean actuallyUnquoted = !originalArg.equals(arg);

There, the 'true' parameter value is mistakenly popped up as an argument instead of the"--use-ssl" parameter name. That part works fine for the String option with default values and for Boolean with a 'false' default value.

Note, when I modify the command in this way (by adding arity = "1"):

    @CommandLine.Option(names = {"--use-ssl"}, description = "Use SSL.", defaultValue = "true", arity = "1")
    private boolean usesSSL;		

the test passed.

Is this expected behaviour? Shouldn't we get the ability to implicitly set 'true' for a boolean option even if it is 'true' by default?

Thanks in advance for your response!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions