diff --git a/RELEASE-NOTES.md b/RELEASE-NOTES.md index 84245a322..5a11a7c8a 100644 --- a/RELEASE-NOTES.md +++ b/RELEASE-NOTES.md @@ -138,6 +138,7 @@ No features have been promoted in this picocli release. - [#262] New Feature: new `showDefaultValue` attribute on `@Option` and `@Parameters` gives fine-grained control over which default values to show or hide. Thanks to [ymenager](https://github.com/ymenager) for the request. - [#268] New Feature: new `helpCommand` attribute on `@Command`: if the command line arguments contain a subcommand annotated with `helpCommand`, the parser will not validate the required options or positional parameters of the parent command. Thanks to [ymenager](https://github.com/ymenager) for the request. - [#277] New Feature: new `hidden` attribute on `@Command` to omit the specified subcommand from the usage help message command list of the parent command. Thanks to [pditommaso](https://github.com/pditommaso). +- [#279] Enhancement: assign empty String when String option was specified without value. Thanks to [pditommaso](https://github.com/pditommaso) for the request. ## Deprecations diff --git a/src/test/java/picocli/CommandLineArityTest.java b/src/test/java/picocli/CommandLineArityTest.java index 594ee42b8..4641f1d01 100644 --- a/src/test/java/picocli/CommandLineArityTest.java +++ b/src/test/java/picocli/CommandLineArityTest.java @@ -26,11 +26,7 @@ import org.junit.Ignore; import org.junit.Test; -import picocli.CommandLine.MissingParameterException; -import picocli.CommandLine.Option; -import picocli.CommandLine.Parameters; -import picocli.CommandLine.Range; -import picocli.CommandLine.UnmatchedArgumentException; +import picocli.CommandLine.*; import static org.junit.Assert.*; import static picocli.HelpTestUtil.setTraceLevel; @@ -541,6 +537,22 @@ class App { ": java.lang.NumberFormatException: For input string: \"-boolean\"", ex.getMessage()); } } + /** see issue #279 */ + @Test + public void testSingleValueFieldWithOptionalParameter_279() { + @Command(name="sample") + class Sample { + @Option(names="--foo", arity="0..1") String foo; + } + Sample sample1 = CommandLine.populateCommand(new Sample()); // not specified + assertNull("optional option is null when option not specified", sample1.foo); + + Sample sample2 = CommandLine.populateCommand(new Sample(), "--foo"); // no arguments + assertEquals("optional option is empty string when specified without args", "", sample2.foo); + + Sample sample3 = CommandLine.populateCommand(new Sample(), "--foo", "value"); // no arguments + assertEquals("optional option has value when specified", "value", sample3.foo); + } @Test public void testIntOptionArity1_nConsumes1Argument() { // ignores varargs @@ -863,7 +875,7 @@ class Arg { @Test public void test130MixPositionalParamsWithOptions() { - @CommandLine.Command(name = "test-command", description = "tests help from a command script") + @Command(name = "test-command", description = "tests help from a command script") class Arg { @Parameters(description = "some parameters") diff --git a/src/test/java/picocli/CommandLineModelTest.java b/src/test/java/picocli/CommandLineModelTest.java index 2ed798946..699cf1116 100644 --- a/src/test/java/picocli/CommandLineModelTest.java +++ b/src/test/java/picocli/CommandLineModelTest.java @@ -23,14 +23,8 @@ import org.junit.Test; -import picocli.CommandLine.CommandSpec; +import picocli.CommandLine.*; import picocli.CommandLine.Help.Ansi; -import picocli.CommandLine.ITypeConverter; -import picocli.CommandLine.InitializationException; -import picocli.CommandLine.OptionSpec; -import picocli.CommandLine.PositionalParamSpec; -import picocli.CommandLine.Range; -import picocli.CommandLine.UnmatchedArgumentException; import static org.junit.Assert.*; import static picocli.HelpTestUtil.setTraceLevel; @@ -611,4 +605,28 @@ public void testOptionSpecRequiresAtLeastOneName() throws Exception { public void testConversion() { // TODO convertion with aux types (abstract field types, generic map with and without explicit type attribute etc) } + + /** see issue #279 */ + @Test + public void testSingleValueFieldWithOptionalParameter_279() { + @Command(name="sample") + class Sample { + @Option(names="--foo", arity="0..1") String foo; + } + List parsed1 = new CommandLine(new Sample()).parse();// not specified + OptionSpec option1 = parsed1.get(0).getCommandSpec().optionsMap().get("--foo"); + assertNull("optional option is null when option not specified", option1.getValue()); + assertTrue("optional option has no raw string value when option not specified", option1.rawStringValues().isEmpty()); + + List parsed2 = new CommandLine(new Sample()).parse("--foo");// specified without value + OptionSpec option2 = parsed2.get(0).getCommandSpec().optionsMap().get("--foo"); + assertEquals("optional option is empty string when specified without args", "", option2.getValue()); + assertEquals("optional option raw string value when specified without args", "", option2.rawStringValues().get(0)); + + List parsed3 = new CommandLine(new Sample()).parse("--foo", "value");// specified with value + OptionSpec option3 = parsed3.get(0).getCommandSpec().optionsMap().get("--foo"); + assertEquals("optional option is empty string when specified without args", "value", option3.getValue()); + assertEquals("optional option raw string value when specified without args", "value", option3.rawStringValues().get(0)); + } + }