Skip to content

Commit 36d7d59

Browse files
committed
Add tests
1 parent 3f7d699 commit 36d7d59

2 files changed

Lines changed: 113 additions & 3 deletions

File tree

src/main/java/org/apache/commons/cli/DefaultParser.java

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -175,11 +175,19 @@ static int indexOfEqual(final String token) {
175175
protected Options options;
176176

177177
/**
178-
* Flag indicating how unrecognized tokens are handled. {@code true} to stop the parsing and add the remaining
179-
* tokens to the args list. {@code false} to throw an exception.
178+
* Flag indicating how unrecognized tokens are handled: {@code true} to stop the parsing and add the remaining
179+
* tokens to the args list. {@code false} add current token to the arg list and continue parsing.
180180
*/
181181
protected boolean stopAtNonOption;
182182

183+
/**
184+
* Flag indicating how unrecognized tokens are handled: {@code true} to abort parsing by throwing {@link ParseException}.
185+
* {@code false} to ignore it.
186+
*
187+
* @since 1.10.0
188+
*/
189+
protected boolean throwAtNonOption = true;
190+
183191
/** The token currently processed. */
184192
protected String currentToken;
185193

@@ -583,9 +591,10 @@ private void handleToken(final String token) throws ParseException {
583591
*
584592
* @param token the command line token to handle
585593
* @throws ParseException if parsing should fail
594+
* @since 1.10.0
586595
*/
587596
protected void handleUnknownToken(final String token) throws ParseException {
588-
if (token.startsWith("-") && token.length() > 1 && !stopAtNonOption) {
597+
if (token.startsWith("-") && token.length() > 1 && throwAtNonOption) {
589598
throw new UnrecognizedOptionException("Unrecognized option: " + token, token);
590599
}
591600
addArg(token);
@@ -692,6 +701,9 @@ public CommandLine parse(final Options options, final String[] arguments) throws
692701
return parse(options, arguments, null);
693702
}
694703

704+
/**
705+
* @see #parse(Options, String[], Properties, boolean, boolean)
706+
*/
695707
@Override
696708
public CommandLine parse(final Options options, final String[] arguments, final boolean stopAtNonOption) throws ParseException {
697709
return parse(options, arguments, null, stopAtNonOption);
@@ -722,11 +734,31 @@ public CommandLine parse(final Options options, final String[] arguments, final
722734
*
723735
* @return the list of atomic option and value tokens
724736
* @throws ParseException if there are any problems encountered while parsing the command line tokens.
737+
* @see #parse(Options, String[], Properties, boolean, boolean)
725738
*/
726739
public CommandLine parse(final Options options, final String[] arguments, final Properties properties, final boolean stopAtNonOption)
727740
throws ParseException {
741+
return parse(options, arguments, properties, stopAtNonOption, !stopAtNonOption);
742+
}
743+
744+
/**
745+
* Parses the arguments according to the specified options and properties.
746+
*
747+
* @param options the specified Options
748+
* @param arguments the command line arguments
749+
* @param properties command line option name-value pairs
750+
* @param stopAtNonOption see {@link #stopAtNonOption}.
751+
* @param throwAtNonOption see {@link #throwAtNonOption}.
752+
*
753+
* @return the list of atomic option and value tokens
754+
* @throws ParseException if there are any problems encountered while parsing the command line tokens.
755+
* @since 1.10.0
756+
*/
757+
public CommandLine parse(final Options options, final String[] arguments, final Properties properties, final boolean stopAtNonOption,
758+
final boolean throwAtNonOption) throws ParseException {
728759
this.options = options;
729760
this.stopAtNonOption = stopAtNonOption;
761+
this.throwAtNonOption = throwAtNonOption;
730762
skipParsing = false;
731763
currentOption = null;
732764
expectedOpts = new ArrayList<>(options.getRequiredOptions());

src/test/java/org/apache/commons/cli/DefaultParserTest.java

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ Licensed to the Apache Software Foundation (ASF) under one or more
1919

2020
import static org.junit.jupiter.api.Assertions.assertEquals;
2121
import static org.junit.jupiter.api.Assertions.assertFalse;
22+
import static org.junit.jupiter.api.Assertions.assertThrows;
2223
import static org.junit.jupiter.api.Assertions.assertTrue;
2324

2425
import java.util.HashSet;
@@ -157,6 +158,83 @@ public void setUp() {
157158
parser = new DefaultParser();
158159
}
159160

161+
@Test
162+
void chainingParsersHappyPath() throws ParseException {
163+
Option a = Option.builder().option("a").longOpt("first-letter").build();
164+
Option b = Option.builder().option("b").longOpt("second-letter").build();
165+
Option c = Option.builder().option("c").longOpt("third-letter").build();
166+
Option d = Option.builder().option("d").longOpt("fourth-letter").build();
167+
168+
Options baseOptions = new Options();
169+
baseOptions.addOption(a);
170+
baseOptions.addOption(b);
171+
Options specificOptions = new Options();
172+
specificOptions.addOption(a);
173+
specificOptions.addOption(b);
174+
specificOptions.addOption(c);
175+
specificOptions.addOption(d);
176+
177+
String[] args = {"-a", "-b", "-c", "-d", "arg1", "arg2"};
178+
179+
DefaultParser parser = new DefaultParser();
180+
181+
CommandLine baseCommandLine = parser.parse(baseOptions, args, null, false, false);
182+
assertEquals(2, baseCommandLine.getOptions().length);
183+
assertEquals(4, baseCommandLine.getArgs().length);
184+
assertTrue(baseCommandLine.hasOption("a"));
185+
assertTrue(baseCommandLine.hasOption("b"));
186+
assertFalse(baseCommandLine.hasOption("c"));
187+
assertFalse(baseCommandLine.hasOption("d"));
188+
assertFalse(baseCommandLine.getArgList().contains("-a"));
189+
assertFalse(baseCommandLine.getArgList().contains("-b"));
190+
assertTrue(baseCommandLine.getArgList().contains("-c"));
191+
assertTrue(baseCommandLine.getArgList().contains("-d"));
192+
assertTrue(baseCommandLine.getArgList().contains("arg1"));
193+
assertTrue(baseCommandLine.getArgList().contains("arg2"));
194+
195+
CommandLine specificCommandLine = parser.parse(specificOptions, args, null, false, true);
196+
assertEquals(4, specificCommandLine.getOptions().length);
197+
assertEquals(2, specificCommandLine.getArgs().length);
198+
assertTrue(specificCommandLine.hasOption("a"));
199+
assertTrue(specificCommandLine.hasOption("b"));
200+
assertTrue(specificCommandLine.hasOption("c"));
201+
assertTrue(specificCommandLine.hasOption("d"));
202+
assertFalse(specificCommandLine.getArgList().contains("-a"));
203+
assertFalse(specificCommandLine.getArgList().contains("-b"));
204+
assertFalse(specificCommandLine.getArgList().contains("-c"));
205+
assertFalse(specificCommandLine.getArgList().contains("-d"));
206+
assertTrue(specificCommandLine.getArgList().contains("arg1"));
207+
assertTrue(specificCommandLine.getArgList().contains("arg2"));
208+
}
209+
210+
@Test
211+
void chainingParsersNonHappyPath() throws ParseException {
212+
Option a = Option.builder().option("a").longOpt("first-letter").build();
213+
Option b = Option.builder().option("b").longOpt("second-letter").build();
214+
Option c = Option.builder().option("c").longOpt("third-letter").build();
215+
Option d = Option.builder().option("d").longOpt("fourth-letter").build();
216+
217+
Options baseOptions = new Options();
218+
baseOptions.addOption(a);
219+
baseOptions.addOption(b);
220+
Options specificOptions = new Options();
221+
specificOptions.addOption(a);
222+
specificOptions.addOption(b);
223+
specificOptions.addOption(c);
224+
specificOptions.addOption(d);
225+
226+
String[] args = {"-a", "-b", "-c", "-d", "arg1", "arg2", "--rogue-option"};
227+
228+
DefaultParser parser = new DefaultParser();
229+
230+
CommandLine baseCommandLine = parser.parse(baseOptions, args, null, false, false);
231+
assertEquals(2, baseCommandLine.getOptions().length);
232+
assertEquals(5, baseCommandLine.getArgs().length);
233+
234+
UnrecognizedOptionException e = assertThrows(UnrecognizedOptionException.class, () -> parser.parse(specificOptions, args, null, false, true));
235+
assertTrue(e.getMessage().contains("--rogue-option"));
236+
}
237+
160238
@Test
161239
void testBuilder() {
162240
// @formatter:off

0 commit comments

Comments
 (0)