Support optional command line arguments with empty values

Spring Framework provides two implementations of the
CommandLinePropertySource API: SimpleCommandLinePropertySource and
JOptCommandLinePropertySource.

Prior to this commit, JOptCommandLinePropertySource supported empty
values for optional arguments; whereas, SimpleCommandLinePropertySource
did not.

This commit modifies the implementation of SimpleCommandLinePropertySource
to allow empty values for optional arguments.

Closes gh-24464
This commit is contained in:
Sam Brannen
2020-02-03 15:03:43 +01:00
parent 8dfacbc210
commit d77a28aac3
5 changed files with 85 additions and 55 deletions

View File

@@ -28,6 +28,7 @@ import static org.assertj.core.api.Assertions.assertThat;
* Unit tests for {@link JOptCommandLinePropertySource}.
*
* @author Chris Beams
* @author Sam Brannen
* @since 3.1
*/
class JOptCommandLinePropertySourceTests {
@@ -53,6 +54,17 @@ class JOptCommandLinePropertySourceTests {
assertThat(ps.getProperty("foo")).isEqualTo("");
}
@Test // gh-24464
void withOptionalArg_andArgIsEmpty() {
OptionParser parser = new OptionParser();
parser.accepts("foo").withOptionalArg();
OptionSet options = parser.parse("--foo=");
PropertySource<?> ps = new JOptCommandLinePropertySource(options);
assertThat(ps.containsProperty("foo")).isTrue();
assertThat(ps.getProperty("foo")).isEqualTo("");
}
@Test
void withNoArg() {
OptionParser parser = new OptionParser();
@@ -74,7 +86,7 @@ class JOptCommandLinePropertySourceTests {
OptionSet options = parser.parse("--foo=bar,baz,biz");
CommandLinePropertySource<?> ps = new JOptCommandLinePropertySource(options);
assertThat(ps.getOptionValues("foo")).isEqualTo(Arrays.asList("bar","baz","biz"));
assertThat(ps.getOptionValues("foo")).containsExactly("bar", "baz", "biz");
assertThat(ps.getProperty("foo")).isEqualTo("bar,baz,biz");
}
@@ -85,7 +97,7 @@ class JOptCommandLinePropertySourceTests {
OptionSet options = parser.parse("--foo=bar", "--foo=baz", "--foo=biz");
CommandLinePropertySource<?> ps = new JOptCommandLinePropertySource(options);
assertThat(ps.getOptionValues("foo")).isEqualTo(Arrays.asList("bar","baz","biz"));
assertThat(ps.getOptionValues("foo")).containsExactly("bar", "baz", "biz");
assertThat(ps.getProperty("foo")).isEqualTo("bar,baz,biz");
}
@@ -123,7 +135,7 @@ class JOptCommandLinePropertySourceTests {
assertThat(ps.containsProperty("nonOptionArgs")).isFalse();
assertThat(ps.getProperty("nonOptionArgs")).isNull();
assertThat(ps.getPropertyNames().length).isEqualTo(2);
assertThat(ps.getPropertyNames()).hasSize(2);
}
@Test

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -25,17 +25,24 @@ import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
class SimpleCommandLineParserTests {
/**
* Unit tests for {@link SimpleCommandLineArgsParser}.
*
* @author Chris Beams
* @author Sam Brannen
*/
class SimpleCommandLineArgsParserTests {
private final SimpleCommandLineArgsParser parser = new SimpleCommandLineArgsParser();
@Test
void withNoOptions() {
SimpleCommandLineArgsParser parser = new SimpleCommandLineArgsParser();
assertThat(parser.parse().getOptionValues("foo")).isNull();
}
@Test
void withSingleOptionAndNoValue() {
SimpleCommandLineArgsParser parser = new SimpleCommandLineArgsParser();
CommandLineArgs args = parser.parse("--o1");
assertThat(args.containsOption("o1")).isTrue();
assertThat(args.getOptionValues("o1")).isEqualTo(Collections.EMPTY_LIST);
@@ -43,63 +50,52 @@ class SimpleCommandLineParserTests {
@Test
void withSingleOptionAndValue() {
SimpleCommandLineArgsParser parser = new SimpleCommandLineArgsParser();
CommandLineArgs args = parser.parse("--o1=v1");
assertThat(args.containsOption("o1")).isTrue();
assertThat(args.getOptionValues("o1").get(0)).isEqualTo("v1");
assertThat(args.getOptionValues("o1")).containsExactly("v1");
}
@Test
void withMixOfOptionsHavingValueAndOptionsHavingNoValue() {
SimpleCommandLineArgsParser parser = new SimpleCommandLineArgsParser();
CommandLineArgs args = parser.parse("--o1=v1", "--o2");
assertThat(args.containsOption("o1")).isTrue();
assertThat(args.containsOption("o2")).isTrue();
assertThat(args.containsOption("o3")).isFalse();
assertThat(args.getOptionValues("o1").get(0)).isEqualTo("v1");
assertThat(args.getOptionValues("o1")).containsExactly("v1");
assertThat(args.getOptionValues("o2")).isEqualTo(Collections.EMPTY_LIST);
assertThat(args.getOptionValues("o3")).isNull();
}
@Test
void withEmptyOptionText() {
SimpleCommandLineArgsParser parser = new SimpleCommandLineArgsParser();
assertThatIllegalArgumentException().isThrownBy(() ->
parser.parse("--"));
assertThatIllegalArgumentException().isThrownBy(() -> parser.parse("--"));
}
@Test
void withEmptyOptionName() {
SimpleCommandLineArgsParser parser = new SimpleCommandLineArgsParser();
assertThatIllegalArgumentException().isThrownBy(() ->
parser.parse("--=v1"));
assertThatIllegalArgumentException().isThrownBy(() -> parser.parse("--=v1"));
}
@Test
void withEmptyOptionValue() {
SimpleCommandLineArgsParser parser = new SimpleCommandLineArgsParser();
assertThatIllegalArgumentException().isThrownBy(() ->
parser.parse("--o1="));
CommandLineArgs args = parser.parse("--o1=");
assertThat(args.containsOption("o1")).isTrue();
assertThat(args.getOptionValues("o1")).containsExactly("");
}
@Test
void withEmptyOptionNameAndEmptyOptionValue() {
SimpleCommandLineArgsParser parser = new SimpleCommandLineArgsParser();
assertThatIllegalArgumentException().isThrownBy(() ->
parser.parse("--="));
assertThatIllegalArgumentException().isThrownBy(() -> parser.parse("--="));
}
@Test
void withNonOptionArguments() {
SimpleCommandLineArgsParser parser = new SimpleCommandLineArgsParser();
CommandLineArgs args = parser.parse("--o1=v1", "noa1", "--o2=v2", "noa2");
assertThat(args.getOptionValues("o1").get(0)).isEqualTo("v1");
assertThat(args.getOptionValues("o2").get(0)).isEqualTo("v2");
assertThat(args.getOptionValues("o1")).containsExactly("v1");
assertThat(args.getOptionValues("o2")).containsExactly("v2");
List<String> nonOptions = args.getNonOptionArgs();
assertThat(nonOptions.get(0)).isEqualTo("noa1");
assertThat(nonOptions.get(1)).isEqualTo("noa2");
assertThat(nonOptions.size()).isEqualTo(2);
assertThat(nonOptions).containsExactly("noa1", "noa2");
}
@Test

View File

@@ -26,6 +26,7 @@ import static org.assertj.core.api.Assertions.assertThat;
* Unit tests for {@link SimpleCommandLinePropertySource}.
*
* @author Chris Beams
* @author Sam Brannen
* @since 3.1
*/
class SimpleCommandLinePropertySourceTests {
@@ -60,6 +61,14 @@ class SimpleCommandLinePropertySourceTests {
assertThat(ps.getProperty("o3")).isNull();
}
@Test // gh-24464
void withOptionalArg_andArgIsEmpty() {
EnumerablePropertySource<?> ps = new SimpleCommandLinePropertySource("--foo=");
assertThat(ps.containsProperty("foo")).isTrue();
assertThat(ps.getProperty("foo")).isEqualTo("");
}
@Test
void withDefaultNonOptionArgsNameAndNoNonOptionArgsPresent() {
EnumerablePropertySource<?> ps = new SimpleCommandLinePropertySource("--o1=v1", "--o2");
@@ -70,7 +79,7 @@ class SimpleCommandLinePropertySourceTests {
assertThat(ps.containsProperty("nonOptionArgs")).isFalse();
assertThat(ps.getProperty("nonOptionArgs")).isNull();
assertThat(ps.getPropertyNames().length).isEqualTo(2);
assertThat(ps.getPropertyNames()).hasSize(2);
}
@Test