1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.commons.cli;
19
20 import static org.junit.jupiter.api.Assertions.assertArrayEquals;
21 import static org.junit.jupiter.api.Assertions.assertEquals;
22 import static org.junit.jupiter.api.Assertions.assertFalse;
23 import static org.junit.jupiter.api.Assertions.assertNotNull;
24 import static org.junit.jupiter.api.Assertions.assertNull;
25 import static org.junit.jupiter.api.Assertions.assertThrows;
26 import static org.junit.jupiter.api.Assertions.assertTrue;
27
28 import java.util.Arrays;
29 import java.util.List;
30 import java.util.Properties;
31
32 import org.junit.jupiter.api.BeforeEach;
33 import org.junit.jupiter.api.Test;
34
35
36
37
38
39
40 public abstract class AbstractParserTestCase {
41
42 protected CommandLineParser parser;
43
44 protected Options options;
45
46 @SuppressWarnings("deprecation")
47 private CommandLine parse(final CommandLineParser parser, final Options options, final String[] args, final Properties properties) throws ParseException {
48 if (parser instanceof Parser) {
49 return ((Parser) parser).parse(options, args, properties);
50 }
51 if (parser instanceof DefaultParser) {
52 return ((DefaultParser) parser).parse(options, args, properties);
53 }
54 throw new UnsupportedOperationException("Default options not supported by this parser");
55 }
56
57 @BeforeEach
58 public void setUp() {
59
60 options = new Options()
61 .addOption("a", "enable-a", false, "turn [a] on or off")
62 .addOption("b", "bfile", true, "set the value of [b]")
63 .addOption("c", "copt", false, "turn [c] on or off");
64
65 }
66
67 @Test
68 void testAmbiguousArgParsing() throws Exception {
69 final String[] args = { "-=-" };
70 final Options options = new Options();
71 assertThrows(UnrecognizedOptionException.class, () -> parser.parse(options, args));
72 }
73
74 @Test
75 void testAmbiguousLongWithoutEqualSingleDash() throws Exception {
76 final String[] args = { "-b", "-foobar" };
77 final Options options = new Options();
78 options.addOption(OptionBuilder.withLongOpt("foo").hasOptionalArg().create('f'));
79 options.addOption(OptionBuilder.withLongOpt("bar").hasOptionalArg().create('b'));
80 final CommandLine cl = parser.parse(options, args);
81 assertTrue(cl.hasOption("b"));
82 assertTrue(cl.hasOption("f"));
83 assertEquals("bar", cl.getOptionValue("foo"));
84 }
85
86 @Test
87 void testAmbiguousLongWithoutEqualSingleDash2() throws Exception {
88 final String[] args = { "-b", "-foobar" };
89 final Options options = new Options();
90 options.addOption(Option.builder().longOpt("foo").option("f").optionalArg(true).get());
91 options.addOption(Option.builder().longOpt("bar").option("b").optionalArg(false).get());
92 final CommandLine cl = parser.parse(options, args);
93 assertTrue(cl.hasOption("b"));
94 assertTrue(cl.hasOption("f"));
95 assertEquals("bar", cl.getOptionValue("foo"));
96 }
97
98 @Test
99 void testAmbiguousPartialLongOption1() throws Exception {
100 final String[] args = { "--ver" };
101 final Options options = new Options();
102 options.addOption(OptionBuilder.withLongOpt("version").create());
103 options.addOption(OptionBuilder.withLongOpt("verbose").create());
104 final AmbiguousOptionException e = assertThrows(AmbiguousOptionException.class, () -> parser.parse(options, args));
105 assertEquals("--ver", e.getOption(), "Partial option");
106 assertNotNull(e.getMatchingOptions(), "Matching options null");
107 assertEquals(2, e.getMatchingOptions().size(), "Matching options size");
108 }
109
110 @Test
111 void testAmbiguousPartialLongOption2() throws Exception {
112 final String[] args = { "-ver" };
113 final Options options = new Options();
114 options.addOption(OptionBuilder.withLongOpt("version").create());
115 options.addOption(OptionBuilder.withLongOpt("verbose").create());
116 final AmbiguousOptionException e = assertThrows(AmbiguousOptionException.class, () -> parser.parse(options, args));
117 assertEquals("-ver", e.getOption(), "Partial option");
118 assertNotNull(e.getMatchingOptions(), "Matching options null");
119 assertEquals(2, e.getMatchingOptions().size(), "Matching options size");
120 }
121
122 @Test
123 void testAmbiguousPartialLongOption3() throws Exception {
124 final String[] args = { "--ver=1" };
125 final Options options = new Options();
126 options.addOption(OptionBuilder.withLongOpt("version").create());
127 options.addOption(OptionBuilder.withLongOpt("verbose").hasOptionalArg().create());
128 final AmbiguousOptionException e = assertThrows(AmbiguousOptionException.class, () -> parser.parse(options, args));
129 assertEquals("--ver", e.getOption(), "Partial option");
130 assertNotNull(e.getMatchingOptions(), "Matching options null");
131 assertEquals(2, e.getMatchingOptions().size(), "Matching options size");
132 }
133
134 @Test
135 void testAmbiguousPartialLongOption4() throws Exception {
136 final String[] args = { "-ver=1" };
137 final Options options = new Options();
138 options.addOption(OptionBuilder.withLongOpt("version").create());
139 options.addOption(OptionBuilder.withLongOpt("verbose").hasOptionalArg().create());
140 final AmbiguousOptionException e = assertThrows(AmbiguousOptionException.class, () -> parser.parse(options, args));
141 assertEquals("-ver", e.getOption(), "Partial option");
142 assertNotNull(e.getMatchingOptions(), "Matching options null");
143 assertEquals(2, e.getMatchingOptions().size(), "Matching options size");
144 }
145
146 @Test
147 void testArgumentStartingWithHyphen() throws Exception {
148 final String[] args = { "-b", "-foo" };
149 final CommandLine cl = parser.parse(options, args);
150 assertEquals("-foo", cl.getOptionValue("b"));
151 }
152
153 @Test
154 void testBursting() throws Exception {
155 final String[] args = { "-acbtoast", "foo", "bar" };
156 final CommandLine cl = parser.parse(options, args);
157 assertTrue(cl.hasOption("a"), "Confirm -a is set");
158 assertTrue(cl.hasOption("b"), "Confirm -b is set");
159 assertTrue(cl.hasOption("c"), "Confirm -c is set");
160 assertEquals("toast", cl.getOptionValue("b"), "Confirm arg of -b");
161 assertEquals(2, cl.getArgList().size(), "Confirm size of extra args");
162 }
163
164 @Test
165 void testDoubleDash1() throws Exception {
166 final String[] args = { "--copt", "--", "-b", "toast" };
167 final CommandLine cl = parser.parse(options, args);
168 assertTrue(cl.hasOption("c"), "Confirm -c is set");
169 assertFalse(cl.hasOption("b"), "Confirm -b is not set");
170 assertEquals(2, cl.getArgList().size(), "Confirm 2 extra args: " + cl.getArgList().size());
171 }
172
173 @Test
174 void testDoubleDash2() throws Exception {
175 final Options options = new Options();
176 options.addOption(OptionBuilder.hasArg().create('n'));
177 options.addOption(OptionBuilder.create('m'));
178 final MissingArgumentException e = assertThrows(MissingArgumentException.class, () -> parser.parse(options, new String[] { "-n", "--", "-m" }));
179 assertNotNull(e.getOption(), "option null");
180 assertEquals("n", e.getOption().getOpt());
181 }
182
183 @Test
184 void testLongOptionQuoteHandling() throws Exception {
185 final String[] args = { "--bfile", "\"quoted string\"" };
186 final CommandLine cl = parser.parse(options, args);
187 assertEquals("quoted string", cl.getOptionValue("b"), "Confirm --bfile \"arg\" strips quotes");
188 }
189
190 @Test
191 void testLongOptionWithEqualsQuoteHandling() throws Exception {
192 final String[] args = { "--bfile=\"quoted string\"" };
193 final CommandLine cl = parser.parse(options, args);
194 assertEquals("quoted string", cl.getOptionValue("b"), "Confirm --bfile=\"arg\" strips quotes");
195 }
196
197 @Test
198 void testLongWithEqualDoubleDash() throws Exception {
199 final String[] args = { "--foo=bar" };
200 final Options options = new Options();
201 options.addOption(OptionBuilder.withLongOpt("foo").hasArg().create('f'));
202 final CommandLine cl = parser.parse(options, args);
203 assertEquals("bar", cl.getOptionValue("foo"));
204 }
205
206 @Test
207 void testLongWithEqualSingleDash() throws Exception {
208 final String[] args = { "-foo=bar" };
209 final Options options = new Options();
210 options.addOption(OptionBuilder.withLongOpt("foo").hasArg().create('f'));
211 final CommandLine cl = parser.parse(options, args);
212 assertEquals("bar", cl.getOptionValue("foo"));
213 }
214
215 @Test
216 void testLongWithoutEqualDoubleDash() throws Exception {
217 final String[] args = { "--foobar" };
218 final Options options = new Options();
219 options.addOption(OptionBuilder.withLongOpt("foo").hasArg().create('f'));
220 final CommandLine cl = parser.parse(options, args, true);
221 assertFalse(cl.hasOption("foo"));
222 }
223
224 @Test
225 void testLongWithoutEqualSingleDash() throws Exception {
226 final Options options = new Options();
227 options.addOption(OptionBuilder.withLongOpt("foo").hasArg().create('f'));
228 final CommandLine cl = parser.parse(options, new String[] { "-foobar" });
229 assertEquals("bar", cl.getOptionValue("foo"));
230 }
231
232 @Test
233 void testLongWithUnexpectedArgument1() throws Exception {
234 final Options options = new Options();
235 options.addOption(OptionBuilder.withLongOpt("foo").create('f'));
236 final UnrecognizedOptionException e = assertThrows(UnrecognizedOptionException.class, () -> parser.parse(options, new String[] { "--foo=bar" }));
237 assertEquals("--foo=bar", e.getOption());
238 }
239
240 @Test
241 void testLongWithUnexpectedArgument2() throws Exception {
242 final Options options = new Options();
243 options.addOption(OptionBuilder.withLongOpt("foo").create('f'));
244 final UnrecognizedOptionException e = assertThrows(UnrecognizedOptionException.class, () -> parser.parse(options, new String[] { "-foobar" }));
245 assertEquals("-foobar", e.getOption());
246 }
247
248 @Test
249 void testMissingArg() throws Exception {
250 final MissingArgumentException e = assertThrows(MissingArgumentException.class, () -> parser.parse(options, new String[] { "-b" }));
251 assertEquals("b", e.getOption().getOpt(), "option missing an argument");
252 }
253
254 @Test
255 void testMissingArgWithBursting() throws Exception {
256 final String[] args = { "-acb" };
257 final MissingArgumentException e = assertThrows(MissingArgumentException.class, () -> parser.parse(options, args));
258 assertEquals("b", e.getOption().getOpt(), "option missing an argument");
259 }
260
261 @Test
262 void testMissingRequiredGroup() throws Exception {
263 final OptionGroup optionGroup = new OptionGroup();
264 optionGroup.addOption(OptionBuilder.create("a"));
265 optionGroup.addOption(OptionBuilder.create("b"));
266 optionGroup.setRequired(true);
267 final Options options = new Options();
268 options.addOptionGroup(optionGroup);
269 options.addOption(OptionBuilder.isRequired().create("c"));
270 final MissingOptionException e = assertThrows(MissingOptionException.class, () -> parser.parse(options, new String[] { "-c" }));
271 assertEquals(1, e.getMissingOptions().size());
272 assertTrue(e.getMissingOptions().get(0) instanceof OptionGroup);
273 }
274
275 @Test
276 void testMissingRequiredOption() {
277 final String[] args = { "-a" };
278 final Options options = new Options();
279 options.addOption("a", "enable-a", false, null);
280 options.addOption(OptionBuilder.withLongOpt("bfile").hasArg().isRequired().create('b'));
281 final MissingOptionException e = assertThrows(MissingOptionException.class, () -> parser.parse(options, args));
282 assertEquals("Missing required option: b", e.getMessage(), "Incorrect exception message");
283 assertTrue(e.getMissingOptions().contains("b"));
284 }
285
286 @Test
287 void testMissingRequiredOptions() {
288 final String[] args = { "-a" };
289 final Options options = new Options();
290 options.addOption("a", "enable-a", false, null);
291 options.addOption(OptionBuilder.withLongOpt("bfile").hasArg().isRequired().create('b'));
292 options.addOption(OptionBuilder.withLongOpt("cfile").hasArg().isRequired().create('c'));
293 final MissingOptionException e = assertThrows(MissingOptionException.class, () -> parser.parse(options, args));
294 assertEquals("Missing required options: b, c", e.getMessage(), "Incorrect exception message");
295 assertTrue(e.getMissingOptions().contains("b"));
296 assertTrue(e.getMissingOptions().contains("c"));
297 }
298
299 @Test
300 void testMultiple() throws Exception {
301 final String[] args = { "-c", "foobar", "-b", "toast" };
302 CommandLine cl = parser.parse(options, args, true);
303 assertTrue(cl.hasOption("c"), "Confirm -c is set");
304 assertEquals(3, cl.getArgList().size(), "Confirm 3 extra args: " + cl.getArgList().size());
305 cl = parser.parse(options, cl.getArgs());
306 assertFalse(cl.hasOption("c"), "Confirm -c is not set");
307 assertTrue(cl.hasOption("b"), "Confirm -b is set");
308 assertEquals("toast", cl.getOptionValue("b"), "Confirm arg of -b");
309 assertEquals(1, cl.getArgList().size(), "Confirm 1 extra arg: " + cl.getArgList().size());
310 assertEquals("foobar", cl.getArgList().get(0), "Confirm value of extra arg: " + cl.getArgList().get(0));
311 }
312
313 @Test
314 void testMultipleWithLong() throws Exception {
315 final String[] args = { "--copt", "foobar", "--bfile", "toast" };
316 CommandLine cl = parser.parse(options, args, true);
317 assertTrue(cl.hasOption("c"), "Confirm -c is set");
318 assertEquals(3, cl.getArgList().size(), "Confirm 3 extra args: " + cl.getArgList().size());
319 cl = parser.parse(options, cl.getArgs());
320 assertFalse(cl.hasOption("c"), "Confirm -c is not set");
321 assertTrue(cl.hasOption("b"), "Confirm -b is set");
322 assertEquals("toast", cl.getOptionValue("b"), "Confirm arg of -b");
323 assertEquals(1, cl.getArgList().size(), "Confirm 1 extra arg: " + cl.getArgList().size());
324 assertEquals("foobar", cl.getArgList().get(0), "Confirm value of extra arg: " + cl.getArgList().get(0));
325 }
326
327 @Test
328 void testMultipleWithNull() throws Exception {
329 final String[] args = { null, "-c", null, "foobar", null, "-b", null, "toast", null };
330 CommandLine cl = parser.parse(options, args, true);
331 assertTrue(cl.hasOption("c"), "Confirm -c is set");
332 assertEquals(3, cl.getArgList().size(), "Confirm 3 extra args: " + cl.getArgList().size());
333 cl = parser.parse(options, cl.getArgs());
334 assertFalse(cl.hasOption("c"), "Confirm -c is not set");
335 assertTrue(cl.hasOption("b"), "Confirm -b is set");
336 assertEquals("toast", cl.getOptionValue("b"), "Confirm arg of -b");
337 assertEquals(1, cl.getArgList().size(), "Confirm 1 extra arg: " + cl.getArgList().size());
338 assertEquals("foobar", cl.getArgList().get(0), "Confirm value of extra arg: " + cl.getArgList().get(0));
339 }
340
341 @Test
342 void testNegativeArgument() throws Exception {
343 final String[] args = { "-b", "-1" };
344 final CommandLine cl = parser.parse(options, args);
345 assertEquals("-1", cl.getOptionValue("b"));
346 }
347
348 @Test
349 void testNegativeOption() throws Exception {
350 final String[] args = { "-b", "-1" };
351 options.addOption("1", false, null);
352 final CommandLine cl = parser.parse(options, args);
353 assertEquals("-1", cl.getOptionValue("b"));
354 }
355
356 @Test
357 void testOptionalArgsOptionBuilder() throws Exception {
358 final Options options = new Options();
359 options.addOption(OptionBuilder.hasOptionalArgs(2).create('i'));
360 final Properties properties = new Properties();
361
362 CommandLine cmd = parse(parser, options, new String[] { "-i" }, properties);
363 assertTrue(cmd.hasOption("i"));
364 assertNull(cmd.getOptionValues("i"));
365
366 cmd = parse(parser, options, new String[] { "-i", "paper" }, properties);
367 assertTrue(cmd.hasOption("i"));
368 assertArrayEquals(new String[] { "paper" }, cmd.getOptionValues("i"));
369
370 cmd = parse(parser, options, new String[] { "-i", "paper", "scissors" }, properties);
371 assertTrue(cmd.hasOption("i"));
372 assertArrayEquals(new String[] { "paper", "scissors" }, cmd.getOptionValues("i"));
373
374 cmd = parse(parser, options, new String[] { "-i", "paper", "scissors", "rock" }, properties);
375 assertTrue(cmd.hasOption("i"));
376 assertArrayEquals(new String[] { "paper", "scissors" }, cmd.getOptionValues("i"));
377 assertArrayEquals(new String[] { "rock" }, cmd.getArgs());
378 }
379
380 @Test
381 void testOptionalArgsOptionDotBuilder() throws Exception {
382 final Options options = new Options();
383 options.addOption(Option.builder("i").numberOfArgs(2).optionalArg(true).get());
384 final Properties properties = new Properties();
385
386 CommandLine cmd = parse(parser, options, new String[] { "-i" }, properties);
387 assertTrue(cmd.hasOption("i"));
388 assertNull(cmd.getOptionValues("i"));
389
390 cmd = parse(parser, options, new String[] { "-i", "paper" }, properties);
391 assertTrue(cmd.hasOption("i"));
392 assertArrayEquals(new String[] { "paper" }, cmd.getOptionValues("i"));
393
394 cmd = parse(parser, options, new String[] { "-i", "paper", "scissors" }, properties);
395 assertTrue(cmd.hasOption("i"));
396 assertArrayEquals(new String[] { "paper", "scissors" }, cmd.getOptionValues("i"));
397
398 cmd = parse(parser, options, new String[] { "-i", "paper", "scissors", "rock" }, properties);
399 assertTrue(cmd.hasOption("i"));
400 assertArrayEquals(new String[] { "paper", "scissors" }, cmd.getOptionValues("i"));
401 assertArrayEquals(new String[] { "rock" }, cmd.getArgs());
402
403 options.addOption(Option.builder("j").numberOfArgs(3).optionalArg(true).get());
404 cmd = parse(parser, options, new String[] { "-j" }, properties);
405 }
406
407 @Test
408 void testOptionAndRequiredOption() throws Exception {
409 final String[] args = { "-a", "-b", "file" };
410
411 final Options options = new Options();
412 options.addOption("a", "enable-a", false, null);
413 options.addOption(OptionBuilder.withLongOpt("bfile").hasArg().isRequired().create('b'));
414
415 final CommandLine cl = parser.parse(options, args);
416
417 assertTrue(cl.hasOption("a"), "Confirm -a is set");
418 assertTrue(cl.hasOption("b"), "Confirm -b is set");
419 assertEquals("file", cl.getOptionValue("b"), "Confirm arg of -b");
420 assertTrue(cl.getArgList().isEmpty(), "Confirm NO of extra args");
421 }
422
423 @Test
424 void testOptionGroup() throws Exception {
425 final OptionGroup optionGroup = new OptionGroup();
426 assertFalse(optionGroup.isSelected());
427 optionGroup.addOption(OptionBuilder.create("a"));
428 optionGroup.addOption(OptionBuilder.create("b"));
429
430 final Options options = new Options();
431 options.addOptionGroup(optionGroup);
432
433 parser.parse(options, new String[] { "-b" });
434
435 assertTrue(optionGroup.isSelected());
436 assertEquals("b", optionGroup.getSelected(), "selected option");
437 }
438
439 @Test
440 void testOptionGroupLong() throws Exception {
441 final OptionGroup optionGroup = new OptionGroup();
442 optionGroup.addOption(OptionBuilder.withLongOpt("foo").create());
443 optionGroup.addOption(OptionBuilder.withLongOpt("bar").create());
444
445 final Options options = new Options();
446 options.addOptionGroup(optionGroup);
447
448 final CommandLine cl = parser.parse(options, new String[] { "--bar" });
449
450 assertTrue(cl.hasOption("bar"));
451 assertTrue(optionGroup.isSelected());
452 assertEquals("bar", optionGroup.getSelected(), "selected option");
453 }
454
455 @Test
456 void testPartialLongOptionSingleDash() throws Exception {
457 final String[] args = { "-ver" };
458
459 final Options options = new Options();
460 options.addOption(OptionBuilder.withLongOpt("version").create());
461 options.addOption(OptionBuilder.hasArg().create('v'));
462
463 final CommandLine cl = parser.parse(options, args);
464
465 assertTrue(cl.hasOption("version"), "Confirm --version is set");
466 assertFalse(cl.hasOption("v"), "Confirm -v is not set");
467 }
468
469 @Test
470 void testPropertiesOption1() throws Exception {
471 final String[] args = { "-Jsource=1.5", "-J", "target", "1.5", "foo" };
472
473 final Options options = new Options();
474 options.addOption(OptionBuilder.withValueSeparator().hasArgs(2).create('J'));
475
476 final CommandLine cl = parser.parse(options, args);
477
478 final List<String> values = Arrays.asList(cl.getOptionValues("J"));
479 assertNotNull(values, "null values");
480 assertEquals(4, values.size(), "number of values");
481 assertEquals("source", values.get(0), "value 1");
482 assertEquals("1.5", values.get(1), "value 2");
483 assertEquals("target", values.get(2), "value 3");
484 assertEquals("1.5", values.get(3), "value 4");
485
486 final List<?> argsleft = cl.getArgList();
487 assertEquals(1, argsleft.size(), "Should be 1 arg left");
488 assertEquals("foo", argsleft.get(0), "Expecting foo");
489 }
490
491 @Test
492 void testPropertiesOption2() throws Exception {
493 final String[] args = { "-Dparam1", "-Dparam2=value2", "-D" };
494
495 final Options options = new Options();
496 options.addOption(OptionBuilder.withValueSeparator().hasOptionalArgs(2).create('D'));
497
498 final CommandLine cl = parser.parse(options, args);
499
500 final Properties props = cl.getOptionProperties("D");
501 assertNotNull(props, "null properties");
502 assertEquals(2, props.size(), "number of properties in " + props);
503 assertEquals("true", props.getProperty("param1"), "property 1");
504 assertEquals("value2", props.getProperty("param2"), "property 2");
505
506 final List<?> argsleft = cl.getArgList();
507 assertEquals(0, argsleft.size(), "Should be no arg left");
508 }
509
510 @Test
511 void testPropertyOptionFlags() throws Exception {
512 final Options options = new Options();
513 options.addOption("a", false, "toggle -a");
514 options.addOption("c", "c", false, "toggle -c");
515 options.addOption(OptionBuilder.hasOptionalArg().create('e'));
516
517 Properties properties = new Properties();
518 properties.setProperty("a", "true");
519 properties.setProperty("c", "yes");
520 properties.setProperty("e", "1");
521
522 CommandLine cmd = parse(parser, options, null, properties);
523 assertTrue(cmd.hasOption("a"));
524 assertTrue(cmd.hasOption("c"));
525 assertTrue(cmd.hasOption("e"));
526
527 properties = new Properties();
528 properties.setProperty("a", "false");
529 properties.setProperty("c", "no");
530 properties.setProperty("e", "0");
531
532 cmd = parse(parser, options, null, properties);
533 assertFalse(cmd.hasOption("a"));
534 assertFalse(cmd.hasOption("c"));
535 assertTrue(cmd.hasOption("e"));
536
537 properties = new Properties();
538 properties.setProperty("a", "TRUE");
539 properties.setProperty("c", "nO");
540 properties.setProperty("e", "TrUe");
541
542 cmd = parse(parser, options, null, properties);
543 assertTrue(cmd.hasOption("a"));
544 assertFalse(cmd.hasOption("c"));
545 assertTrue(cmd.hasOption("e"));
546
547 properties = new Properties();
548 properties.setProperty("a", "just a string");
549 properties.setProperty("e", "");
550
551 cmd = parse(parser, options, null, properties);
552 assertFalse(cmd.hasOption("a"));
553 assertFalse(cmd.hasOption("c"));
554 assertTrue(cmd.hasOption("e"));
555
556 properties = new Properties();
557 properties.setProperty("a", "0");
558 properties.setProperty("c", "1");
559
560 cmd = parse(parser, options, null, properties);
561 assertFalse(cmd.hasOption("a"));
562 assertTrue(cmd.hasOption("c"));
563 }
564
565 @Test
566 void testPropertyOptionGroup() throws Exception {
567 final Options options = new Options();
568
569 final OptionGroup optionGroup1 = new OptionGroup();
570 optionGroup1.addOption(new Option("a", null));
571 optionGroup1.addOption(new Option("b", null));
572 options.addOptionGroup(optionGroup1);
573
574 final OptionGroup optionGroup2 = new OptionGroup();
575 optionGroup2.addOption(new Option("x", null));
576 optionGroup2.addOption(new Option("y", null));
577 options.addOptionGroup(optionGroup2);
578
579 final String[] args = { "-a" };
580
581 final Properties properties = new Properties();
582 properties.put("b", "true");
583 properties.put("x", "true");
584
585 final CommandLine cmd = parse(parser, options, args, properties);
586
587 assertTrue(cmd.hasOption("a"));
588 assertFalse(cmd.hasOption("b"));
589 assertTrue(cmd.hasOption("x"));
590 assertFalse(cmd.hasOption("y"));
591 }
592
593 @Test
594 void testPropertyOptionMultipleValues() throws Exception {
595 final Options options = new Options();
596 options.addOption(OptionBuilder.hasArgs().withValueSeparator(',').create('k'));
597
598 final Properties properties = new Properties();
599 properties.setProperty("k", "one,two");
600
601 final CommandLine cmd = parse(parser, options, null, properties);
602 assertTrue(cmd.hasOption("k"));
603 final String[] values = { "one", "two" };
604 assertArrayEquals(values, cmd.getOptionValues('k'));
605 }
606
607 @Test
608 void testPropertyOptionRequired() throws Exception {
609 final Options options = new Options();
610 options.addOption(OptionBuilder.isRequired().create("f"));
611
612 final Properties properties = new Properties();
613 properties.setProperty("f", "true");
614
615 final CommandLine cmd = parse(parser, options, null, properties);
616 assertTrue(cmd.hasOption("f"));
617 }
618
619 @Test
620 void testPropertyOptionSingularValue() throws Exception {
621 final Options options = new Options();
622 options.addOption(OptionBuilder.hasOptionalArgs(2).withLongOpt("hide").create());
623
624 final Properties properties = new Properties();
625 properties.setProperty("hide", "seek");
626
627 final CommandLine cmd = parse(parser, options, null, properties);
628 assertTrue(cmd.hasOption("hide"));
629 assertEquals("seek", cmd.getOptionValue("hide"));
630 assertFalse(cmd.hasOption("fake"));
631 }
632
633 @Test
634 void testPropertyOptionUnexpected() throws Exception {
635 final Options options = new Options();
636 final Properties properties = new Properties();
637 properties.setProperty("f", "true");
638 assertThrows(UnrecognizedOptionException.class, () -> parse(parser, options, null, properties));
639 }
640
641 @Test
642 void testPropertyOverrideValues() throws Exception {
643 final Options options = new Options();
644 options.addOption(OptionBuilder.hasOptionalArgs(2).create('i'));
645 options.addOption(OptionBuilder.hasOptionalArgs().create('j'));
646
647 final String[] args = { "-j", "found", "-i", "ink" };
648
649 final Properties properties = new Properties();
650 properties.setProperty("j", "seek");
651
652 final CommandLine cmd = parse(parser, options, args, properties);
653 assertTrue(cmd.hasOption("j"));
654 assertEquals("found", cmd.getOptionValue("j"));
655 assertTrue(cmd.hasOption("i"));
656 assertEquals("ink", cmd.getOptionValue("i"));
657 assertFalse(cmd.hasOption("fake"));
658 }
659
660 @Test
661 void testReuseOptionsTwice() throws Exception {
662 final Options options = new Options();
663 options.addOption(OptionBuilder.isRequired().create('v'));
664
665 parser.parse(options, new String[] { "-v" });
666
667 assertThrows(MissingOptionException.class, () -> parser.parse(options, new String[0]));
668 }
669
670 @Test
671 void testShortOptionConcatenatedQuoteHandling() throws Exception {
672 final CommandLine cl = parser.parse(options, new String[] { "-b\"quoted string\"" });
673 assertEquals("quoted string", cl.getOptionValue("b"), "Confirm -b\"arg\" strips quotes");
674 }
675
676 @Test
677 void testShortOptionQuoteHandling() throws Exception {
678 final CommandLine cl = parser.parse(options, new String[] { "-b", "\"quoted string\"" });
679 assertEquals("quoted string", cl.getOptionValue("b"), "Confirm -b \"arg\" strips quotes");
680 }
681
682 @Test
683 void testShortWithEqual() throws Exception {
684 final Options options = new Options();
685 options.addOption(OptionBuilder.withLongOpt("foo").hasArg().create('f'));
686 final CommandLine cl = parser.parse(options, new String[] { "-f=bar" });
687 assertEquals("bar", cl.getOptionValue("foo"));
688 }
689
690 @Test
691 void testShortWithoutEqual() throws Exception {
692 final Options options = new Options();
693 options.addOption(OptionBuilder.withLongOpt("foo").hasArg().create('f'));
694 final CommandLine cl = parser.parse(options, new String[] { "-fbar" });
695 assertEquals("bar", cl.getOptionValue("foo"));
696 }
697
698 @Test
699 void testShortWithUnexpectedArgument() throws Exception {
700 final Options options = new Options();
701 options.addOption(OptionBuilder.withLongOpt("foo").create('f'));
702 final UnrecognizedOptionException e = assertThrows(UnrecognizedOptionException.class, () -> parser.parse(options, new String[] { "-f=bar" }));
703 assertEquals("-f=bar", e.getOption());
704 }
705
706 @Test
707 void testSimpleLong() throws Exception {
708 final CommandLine cl = parser.parse(options, new String[] { "--enable-a", "--bfile", "toast", "foo", "bar" });
709 assertTrue(cl.hasOption("a"), "Confirm -a is set");
710 assertTrue(cl.hasOption("b"), "Confirm -b is set");
711 assertEquals("toast", cl.getOptionValue("b"), "Confirm arg of -b");
712 assertEquals("toast", cl.getOptionValue("bfile"), "Confirm arg of --bfile");
713 assertEquals(2, cl.getArgList().size(), "Confirm size of extra args");
714 }
715
716 @Test
717 void testSimpleShort() throws Exception {
718 final CommandLine cl = parser.parse(options, new String[] { "-a", "-b", "toast", "foo", "bar" });
719 assertTrue(cl.hasOption("a"), "Confirm -a is set");
720 assertTrue(cl.hasOption("b"), "Confirm -b is set");
721 assertEquals("toast", cl.getOptionValue("b"), "Confirm arg of -b");
722 assertEquals(2, cl.getArgList().size(), "Confirm size of extra args");
723 }
724
725 @Test
726 void testSingleDash() throws Exception {
727 final CommandLine cl = parser.parse(options, new String[] { "--copt", "-b", "-", "-a", "-" });
728 assertTrue(cl.hasOption("a"), "Confirm -a is set");
729 assertTrue(cl.hasOption("b"), "Confirm -b is set");
730 assertEquals("-", cl.getOptionValue("b"), "Confirm arg of -b");
731 assertEquals(1, cl.getArgList().size(), "Confirm 1 extra arg: " + cl.getArgList().size());
732 assertEquals("-", cl.getArgList().get(0), "Confirm value of extra arg: " + cl.getArgList().get(0));
733 }
734
735 @Test
736 void testStopAtExpectedArg() throws Exception {
737 final String[] args = { "-b", "foo" };
738 final CommandLine cl = parser.parse(options, args, true);
739 assertTrue(cl.hasOption('b'), "Confirm -b is set");
740 assertEquals("foo", cl.getOptionValue('b'), "Confirm -b is set");
741 assertTrue(cl.getArgList().isEmpty(), "Confirm no extra args: " + cl.getArgList().size());
742 }
743
744 @Test
745 void testStopAtNonOptionLong() throws Exception {
746 final String[] args = { "--zop==1", "-abtoast", "--b=bar" };
747 final CommandLine cl = parser.parse(options, args, true);
748 assertFalse(cl.hasOption("a"), "Confirm -a is not set");
749 assertFalse(cl.hasOption("b"), "Confirm -b is not set");
750 assertEquals(3, cl.getArgList().size(), "Confirm 3 extra args: " + cl.getArgList().size());
751 }
752
753 @Test
754 void testStopAtNonOptionShort() throws Exception {
755 final CommandLine cl = parser.parse(options, new String[] { "-z", "-a", "-btoast" }, true);
756 assertFalse(cl.hasOption("a"), "Confirm -a is not set");
757 assertEquals(3, cl.getArgList().size(), "Confirm 3 extra args: " + cl.getArgList().size());
758 }
759
760 @Test
761 void testStopAtUnexpectedArg() throws Exception {
762 final CommandLine cl = parser.parse(options, new String[] { "-c", "foober", "-b", "toast" }, true);
763 assertTrue(cl.hasOption("c"), "Confirm -c is set");
764 assertEquals(3, cl.getArgList().size(), "Confirm 3 extra args: " + cl.getArgList().size());
765 }
766
767 @Test
768 void testStopBursting() throws Exception {
769 final CommandLine cl = parser.parse(options, new String[] { "-azc" }, true);
770 assertTrue(cl.hasOption("a"), "Confirm -a is set");
771 assertFalse(cl.hasOption("c"), "Confirm -c is not set");
772 assertEquals(1, cl.getArgList().size(), "Confirm 1 extra arg: " + cl.getArgList().size());
773 assertTrue(cl.getArgList().contains("zc"));
774 }
775
776 @Test
777 void testStopBursting2() throws Exception {
778 CommandLine cl = parser.parse(options, new String[] { "-c", "foobar", "-btoast" }, true);
779 assertTrue(cl.hasOption("c"), "Confirm -c is set");
780 assertEquals(2, cl.getArgList().size(), "Confirm 2 extra args: " + cl.getArgList().size());
781 cl = parser.parse(options, cl.getArgs());
782 assertFalse(cl.hasOption("c"), "Confirm -c is not set");
783 assertTrue(cl.hasOption("b"), "Confirm -b is set");
784 assertEquals("toast", cl.getOptionValue("b"), "Confirm arg of -b");
785 assertEquals(1, cl.getArgList().size(), "Confirm 1 extra arg: " + cl.getArgList().size());
786 assertEquals("foobar", cl.getArgList().get(0), "Confirm value of extra arg: " + cl.getArgList().get(0));
787 }
788
789 @Test
790 void testUnambiguousPartialLongOption1() throws Exception {
791 final Options options = new Options();
792 options.addOption(OptionBuilder.withLongOpt("version").create());
793 options.addOption(OptionBuilder.withLongOpt("help").create());
794 final CommandLine cl = parser.parse(options, new String[] { "--ver" });
795 assertTrue(cl.hasOption("version"), "Confirm --version is set");
796 }
797
798 @Test
799 void testUnambiguousPartialLongOption2() throws Exception {
800 final Options options = new Options();
801 options.addOption(OptionBuilder.withLongOpt("version").create());
802 options.addOption(OptionBuilder.withLongOpt("help").create());
803 final CommandLine cl = parser.parse(options, new String[] { "-ver" });
804 assertTrue(cl.hasOption("version"), "Confirm --version is set");
805 }
806
807 @Test
808 void testUnambiguousPartialLongOption3() throws Exception {
809 final Options options = new Options();
810 options.addOption(OptionBuilder.withLongOpt("verbose").hasOptionalArg().create());
811 options.addOption(OptionBuilder.withLongOpt("help").create());
812 final CommandLine cl = parser.parse(options, new String[] { "--ver=1" });
813 assertTrue(cl.hasOption("verbose"), "Confirm --verbose is set");
814 assertEquals("1", cl.getOptionValue("verbose"));
815 }
816
817 @Test
818 void testUnambiguousPartialLongOption4() throws Exception {
819 final Options options = new Options();
820 options.addOption(OptionBuilder.withLongOpt("verbose").hasOptionalArg().create());
821 options.addOption(OptionBuilder.withLongOpt("help").create());
822 final CommandLine cl = parser.parse(options, new String[] { "-ver=1" });
823 assertTrue(cl.hasOption("verbose"), "Confirm --verbose is set");
824 assertEquals("1", cl.getOptionValue("verbose"));
825 }
826
827 @Test
828 void testUnlimitedArgs() throws Exception {
829 final Options options = new Options();
830 options.addOption(OptionBuilder.hasArgs().create("e"));
831 options.addOption(OptionBuilder.hasArgs().create("f"));
832 final CommandLine cl = parser.parse(options, new String[] { "-e", "one", "two", "-f", "alpha" });
833 assertTrue(cl.hasOption("e"), "Confirm -e is set");
834 assertEquals(2, cl.getOptionValues("e").length, "number of arg for -e");
835 assertTrue(cl.hasOption("f"), "Confirm -f is set");
836 assertEquals(1, cl.getOptionValues("f").length, "number of arg for -f");
837 }
838
839 @Test
840 void testUnrecognizedOption() throws Exception {
841 final UnrecognizedOptionException e = assertThrows(UnrecognizedOptionException.class,
842 () -> parser.parse(options, new String[] { "-a", "-d", "-b", "toast", "foo", "bar" }));
843 assertEquals("-d", e.getOption());
844 }
845
846 @Test
847 void testUnrecognizedOptionWithBursting() throws Exception {
848 final UnrecognizedOptionException e = assertThrows(UnrecognizedOptionException.class,
849 () -> parser.parse(options, new String[] { "-adbtoast", "foo", "bar" }));
850 assertEquals("-adbtoast", e.getOption());
851 }
852
853 @Test
854 void testWithRequiredOption() throws Exception {
855 final String[] args = { "-b", "file" };
856 final Options options = new Options();
857 options.addOption("a", "enable-a", false, null);
858 options.addOption(OptionBuilder.withLongOpt("bfile").hasArg().isRequired().create('b'));
859 final CommandLine cl = parser.parse(options, args);
860 assertFalse(cl.hasOption("a"), "Confirm -a is NOT set");
861 assertTrue(cl.hasOption("b"), "Confirm -b is set");
862 assertEquals("file", cl.getOptionValue("b"), "Confirm arg of -b");
863 assertTrue(cl.getArgList().isEmpty(), "Confirm NO of extra args");
864 }
865 }