View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *     http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.cli2.option;
18  
19  import java.text.ParseException;
20  
21  import java.util.ArrayList;
22  import java.util.Arrays;
23  import java.util.Collections;
24  import java.util.HashSet;
25  import java.util.Iterator;
26  import java.util.List;
27  import java.util.ListIterator;
28  import java.util.Set;
29  
30  import org.apache.commons.cli2.Argument;
31  import org.apache.commons.cli2.DisplaySetting;
32  import org.apache.commons.cli2.HelpLine;
33  import org.apache.commons.cli2.Option;
34  import org.apache.commons.cli2.OptionException;
35  import org.apache.commons.cli2.WriteableCommandLine;
36  import org.apache.commons.cli2.builder.ArgumentBuilder;
37  import org.apache.commons.cli2.builder.GroupBuilder;
38  import org.apache.commons.cli2.commandline.WriteableCommandLineImpl;
39  import org.apache.commons.cli2.resource.ResourceConstants;
40  import org.apache.commons.cli2.resource.ResourceHelper;
41  import org.apache.commons.cli2.validation.DateValidator;
42  import org.apache.commons.cli2.validation.DateValidatorTest;
43  
44  /**
45   * @author Rob Oxspring
46   */
47  public class ArgumentTest
48      extends ArgumentTestCase {
49      private ResourceHelper resources = ResourceHelper.getResourceHelper();
50  
51      public static Argument buildUsernameArgument() {
52          return new ArgumentImpl("username", "The user to connect as", 1, 1, '\0', '\0', null,
53                                  ArgumentImpl.DEFAULT_CONSUME_REMAINING, null, 0);
54      }
55  
56      public static Argument buildHostArgument() {
57          return new ArgumentImpl("host", "The host name", 2, 3, '\0', ',', null, null, null, 0);
58      }
59  
60      public static Argument buildPathArgument() {
61          return new ArgumentImpl("path", "The place to look for files", 1, Integer.MAX_VALUE, '=',
62                                  ';', null, ArgumentImpl.DEFAULT_CONSUME_REMAINING, null, 0);
63      }
64  
65      public static Argument buildDateLimitArgument() {
66          return new ArgumentImpl("limit", "the last acceptable date", 0, 1, '=', '\0',
67                                  new DateValidator(DateValidatorTest.YYYY_MM_DD), null, null, 0);
68      }
69  
70      public static Argument buildTargetsArgument() {
71          return new ArgumentImpl("target", "The targets ant should build", 0, Integer.MAX_VALUE,
72                                  '\0', ',', null, null, null, 0);
73      }
74  
75      public static Argument buildSizeArgument() {
76          List defaults = new ArrayList();
77          defaults.add("10");
78  
79          return new ArgumentImpl("size", "The number of units", 1, 1, '\0', '\0', null,
80                                  ArgumentImpl.DEFAULT_CONSUME_REMAINING, defaults, 0);
81      }
82  
83      public static Argument buildBoundsArgument() {
84          List defaults = new ArrayList();
85          defaults.add("5");
86          defaults.add("10");
87  
88          return new ArgumentImpl("size", "The number of units", 2, 2, '\0', '\0', null,
89                                  ArgumentImpl.DEFAULT_CONSUME_REMAINING, defaults, 0);
90      }
91  
92      public void testNew() {
93          try {
94              new ArgumentImpl("limit", "the last acceptable date", 10, 5, '=', '\0',
95                               new DateValidator(DateValidatorTest.YYYY_MM_DD), null, null, 0);
96          } catch (IllegalArgumentException e) {
97              assertEquals(resources.getMessage("Argument.minimum.exceeds.maximum"), e.getMessage());
98          }
99  
100         {
101             ArgumentImpl arg =
102                 new ArgumentImpl(null, "the last acceptable date", 5, 5, '=', '\0',
103                                  new DateValidator(DateValidatorTest.YYYY_MM_DD), null, null, 0);
104             assertEquals("wrong arg name", "arg", arg.getPreferredName());
105         }
106 
107         {
108             List defaults = new ArrayList();
109 
110             try {
111                 new ArgumentImpl(null, "the last acceptable date", 1, 1, '=', '\0',
112                                  new DateValidator(DateValidatorTest.YYYY_MM_DD), null, defaults, 0);
113             } catch (IllegalArgumentException exp) {
114                 assertEquals(resources.getMessage("Argument.too.few.defaults"), exp.getMessage());
115             }
116         }
117 
118         try {
119             List defaults = new ArrayList();
120             defaults.add("1");
121             defaults.add("2");
122 
123             new ArgumentImpl(null, "the last acceptable date", 1, 1, '=', '\0',
124                              new DateValidator(DateValidatorTest.YYYY_MM_DD), null, defaults, 0);
125         } catch (IllegalArgumentException exp) {
126             assertEquals(resources.getMessage("Argument.too.many.defaults"), exp.getMessage());
127         }
128     }
129 
130     /*
131      * (non-Javadoc)
132      *
133      * @see org.apache.commons.cli2.ArgumentTestCase#testProcessValues()
134      */
135     public void testProcessValues()
136         throws OptionException {
137         final Argument option = buildUsernameArgument();
138         final List args = list("rob");
139         final WriteableCommandLine commandLine = commandLine(option, args);
140         final ListIterator iterator = args.listIterator();
141         option.processValues(commandLine, iterator, option);
142 
143         assertFalse(iterator.hasNext());
144         assertTrue(commandLine.hasOption(option));
145         assertTrue(commandLine.hasOption("username"));
146         assertEquals("rob", commandLine.getValue(option));
147     }
148 
149     public void testProcessValues_BoundaryQuotes()
150         throws OptionException {
151         final Argument option = buildUsernameArgument();
152         final List args = list("\"rob\"");
153         final WriteableCommandLine commandLine = commandLine(option, args);
154         final ListIterator iterator = args.listIterator();
155         option.processValues(commandLine, iterator, option);
156 
157         assertFalse(iterator.hasNext());
158         assertTrue(commandLine.hasOption(option));
159         assertTrue(commandLine.hasOption("username"));
160         assertEquals("rob", commandLine.getValue(option));
161     }
162 
163     public void testProcessValues_SpareValues()
164         throws OptionException {
165         final Argument option = buildUsernameArgument();
166         final List args = list("rob", "secret");
167         final WriteableCommandLine commandLine = commandLine(option, args);
168         final ListIterator iterator = args.listIterator();
169         option.processValues(commandLine, iterator, option);
170 
171         assertTrue(iterator.hasNext());
172         assertTrue(commandLine.hasOption(option));
173         assertTrue(commandLine.hasOption("username"));
174         assertEquals("rob", commandLine.getValue(option));
175     }
176 
177     public void testProcessValues_Optional() {
178         final Argument option = buildTargetsArgument();
179         final List args = list();
180         final WriteableCommandLine commandLine = commandLine(option, args);
181         final ListIterator iterator = args.listIterator();
182 
183         try {
184             option.processValues(commandLine, iterator, option);
185         } catch (final OptionException mve) {
186             assertEquals(option, mve.getOption());
187             assertEquals("Missing value(s) target [target ...]", mve.getMessage());
188         }
189 
190         assertFalse(iterator.hasNext());
191         assertFalse(commandLine.hasOption(option));
192         assertFalse(commandLine.hasOption("username"));
193         assertTrue(commandLine.getValues(option).isEmpty());
194     }
195 
196     public void testProcessValues_Multiple()
197         throws OptionException {
198         final Argument option = buildTargetsArgument();
199         final List args = list("compile", "test", "docs");
200         final WriteableCommandLine commandLine = commandLine(option, args);
201         final ListIterator iterator = args.listIterator();
202         option.processValues(commandLine, iterator, option);
203 
204         assertFalse(iterator.hasNext());
205         assertTrue(commandLine.hasOption(option));
206         assertTrue(commandLine.hasOption("target"));
207         assertFalse(commandLine.getValues(option).isEmpty());
208         assertListContentsEqual(args, commandLine.getValues(option));
209     }
210 
211     public void testProcessValues_Contracted()
212         throws OptionException {
213         final Argument option = buildTargetsArgument();
214         final List args = list("compile,test,javadoc", "checkstyle,jdepend");
215         final WriteableCommandLine commandLine = commandLine(option, args);
216         final ListIterator iterator = args.listIterator();
217         option.processValues(commandLine, iterator, option);
218 
219         assertFalse(iterator.hasNext());
220         assertTrue(commandLine.hasOption(option));
221         assertTrue(commandLine.hasOption("target"));
222         assertListContentsEqual(list("compile", "test", "javadoc", "checkstyle", "jdepend"),
223                                 commandLine.getValues(option));
224     }
225 
226     public void testProcessValues_ContractedTooFew() {
227         final Argument option = buildHostArgument();
228         final List args = list("box1");
229         final WriteableCommandLine commandLine = commandLine(option, args);
230         final ListIterator iterator = args.listIterator();
231 
232         try {
233             option.processValues(commandLine, iterator, option);
234             option.validate(commandLine);
235             fail("Expected MissingValueException");
236         } catch (OptionException mve) {
237             assertSame(option, mve.getOption());
238         }
239     }
240 
241     public void testProcessValues_ContractedTooMany() {
242         final Argument option = buildHostArgument();
243         final List args = list("box1,box2,box3,box4");
244         final WriteableCommandLine commandLine = commandLine(option, args);
245         final ListIterator iterator = args.listIterator();
246 
247         try {
248             option.processValues(commandLine, iterator, option);
249             option.validate(commandLine);
250             fail("Expected MissingValueException");
251         } catch (OptionException mve) {
252             assertSame(option, mve.getOption());
253         }
254     }
255 
256     /*
257      * (non-Javadoc)
258      *
259      * @see org.apache.commons.cli2.OptionTestCase#testCanProcess()
260      */
261     public void testCanProcess() {
262         final Argument option = buildTargetsArgument();
263         assertTrue(option.canProcess(new WriteableCommandLineImpl(option, null), "any value"));
264     }
265 
266     /*
267      * (non-Javadoc)
268      *
269      * @see org.apache.commons.cli2.OptionTestCase#testPrefixes()
270      */
271     public void testPrefixes() {
272         final Argument option = buildTargetsArgument();
273         assertTrue(option.getPrefixes().isEmpty());
274     }
275 
276     /*
277      * (non-Javadoc)
278      *
279      * @see org.apache.commons.cli2.OptionTestCase#testProcess()
280      */
281     public void testProcess()
282         throws OptionException {
283         final Argument option = buildPathArgument();
284         final List args = list("-path=/lib;/usr/lib;/usr/local/lib");
285         final WriteableCommandLine commandLine = commandLine(option, args);
286         final ListIterator iterator = args.listIterator();
287         option.process(commandLine, iterator);
288 
289         assertFalse(iterator.hasNext());
290         assertTrue(commandLine.hasOption(option));
291         assertTrue(commandLine.hasOption("path"));
292         assertListContentsEqual(list("-path=/lib", "/usr/lib", "/usr/local/lib"),
293                                 commandLine.getValues(option));
294     }
295 
296     /*
297      * (non-Javadoc)
298      *
299      * @see org.apache.commons.cli2.OptionTestCase#testTriggers()
300      */
301     public void testTriggers() {
302         final Argument option = buildTargetsArgument();
303         assertTrue(option.getTriggers().isEmpty());
304     }
305 
306     /*
307      * (non-Javadoc)
308      *
309      * @see org.apache.commons.cli2.OptionTestCase#testValidate()
310      */
311     public void testValidate()
312         throws OptionException {
313         final Argument option = buildUsernameArgument();
314         final WriteableCommandLine commandLine = commandLine(option, list());
315 
316         commandLine.addValue(option, "rob");
317 
318         option.validate(commandLine);
319     }
320 
321     public void testValidate_Minimum() {
322         final Argument option = buildUsernameArgument();
323         final WriteableCommandLine commandLine = commandLine(option, list());
324 
325         try {
326             option.validate(commandLine);
327             fail("UnexpectedValue");
328         } catch (OptionException mve) {
329             assertEquals(option, mve.getOption());
330         }
331     }
332 
333     public void testRequired() {
334         {
335             final Argument arg = buildBoundsArgument();
336 
337             assertTrue("not required", arg.isRequired());
338         }
339 
340         {
341             final Argument arg = buildTargetsArgument();
342 
343             assertFalse("should not be required", arg.isRequired());
344         }
345     }
346 
347     public void testValidate_Maximum() {
348         final Argument option = buildUsernameArgument();
349         final WriteableCommandLine commandLine = commandLine(option, list());
350 
351         commandLine.addValue(option, "rob");
352         commandLine.addValue(option, "oxspring");
353 
354         try {
355             option.validate(commandLine);
356             fail("UnexpectedValue");
357         } catch (OptionException uve) {
358             assertEquals(option, uve.getOption());
359         }
360     }
361 
362     public void testValidate_Validator()
363         throws OptionException, ParseException {
364         final Argument option = buildDateLimitArgument();
365         final WriteableCommandLine commandLine = commandLine(option, list());
366 
367         commandLine.addValue(option, "2004-01-01");
368 
369         option.validate(commandLine, option);
370         assertContentsEqual(Arrays.asList(new Object[] {
371                                               DateValidatorTest.YYYY_MM_DD.parse("2004-01-01")
372                                           }), commandLine.getValues(option));
373     }
374 
375     public void testValidate_ValidatorInvalidDate()
376         throws OptionException, ParseException {
377         final Argument option = buildDateLimitArgument();
378         final WriteableCommandLine commandLine = commandLine(option, list());
379 
380         commandLine.addValue(option, "12-12-2004");
381 
382         try {
383             option.validate(commandLine, option);
384         } catch (OptionException exp) {
385             OptionException e =
386                 new OptionException(option, ResourceConstants.ARGUMENT_UNEXPECTED_VALUE,
387                                     "12-12-2004");
388             assertEquals("wrong exception message", e.getMessage(), exp.getMessage());
389         }
390     }
391 
392     /*
393      * (non-Javadoc)
394      *
395      * @see org.apache.commons.cli2.OptionTestCase#testAppendUsage()
396      */
397     public void testAppendUsage() {
398         final Option option = buildUsernameArgument();
399         final StringBuffer buffer = new StringBuffer();
400         option.appendUsage(buffer, DisplaySetting.ALL, null);
401 
402         assertEquals("<username>", buffer.toString());
403     }
404 
405     public void testAppendUsage_Infinite() {
406         final Option option = buildTargetsArgument();
407         final StringBuffer buffer = new StringBuffer();
408         option.appendUsage(buffer, DisplaySetting.ALL, null);
409 
410         assertEquals("[<target1> [<target2> ...]]", buffer.toString());
411     }
412 
413     public void testAppendUsage_InfiniteNoOptional() {
414         final Option option = buildTargetsArgument();
415         final StringBuffer buffer = new StringBuffer();
416         final Set settings = new HashSet(DisplaySetting.ALL);
417         settings.remove(DisplaySetting.DISPLAY_OPTIONAL);
418         option.appendUsage(buffer, settings, null);
419 
420         assertEquals("<target1> [<target2> ...]", buffer.toString());
421     }
422 
423     public void testAppendUsage_InfiniteNoNumbering() {
424         final Option option = buildTargetsArgument();
425         final StringBuffer buffer = new StringBuffer();
426         final Set settings = new HashSet(DisplaySetting.ALL);
427         settings.remove(DisplaySetting.DISPLAY_ARGUMENT_NUMBERED);
428         option.appendUsage(buffer, settings, null);
429 
430         assertEquals("[<target> [<target> ...]]", buffer.toString());
431     }
432 
433     public void testAppendUsage_Minimum() {
434         final Option option = buildHostArgument();
435         final StringBuffer buffer = new StringBuffer();
436         option.appendUsage(buffer, DisplaySetting.ALL, null);
437 
438         assertEquals("<host1> <host2> [<host3>]", buffer.toString());
439     }
440 
441     /*
442      * (non-Javadoc)
443      *
444      * @see org.apache.commons.cli2.OptionTestCase#testGetPreferredName()
445      */
446     public void testGetPreferredName() {
447         final Option option = buildPathArgument();
448         assertEquals("path", option.getPreferredName());
449     }
450 
451     /*
452      * (non-Javadoc)
453      *
454      * @see org.apache.commons.cli2.OptionTestCase#testGetDescription()
455      */
456     public void testGetDescription() {
457         final Option option = buildHostArgument();
458         assertEquals("The host name", option.getDescription());
459     }
460 
461     /*
462      * (non-Javadoc)
463      *
464      * @see org.apache.commons.cli2.OptionTestCase#testHelpLines()
465      */
466     public void testHelpLines() {
467         final Option option = buildHostArgument();
468         final List lines = option.helpLines(0, DisplaySetting.ALL, null);
469         final Iterator i = lines.iterator();
470 
471         final HelpLine line1 = (HelpLine) i.next();
472         assertEquals(0, line1.getIndent());
473         assertEquals(option, line1.getOption());
474 
475         assertFalse(i.hasNext());
476     }
477 
478     public void testCanProcess_ConsumeRemaining() {
479         final Option option = buildUsernameArgument();
480 
481         assertTrue(option.canProcess(new WriteableCommandLineImpl(option, null), "--"));
482     }
483 
484     public void testProcess_ConsumeRemaining()
485         throws OptionException {
486         final Option option = buildPathArgument();
487         final List args = list("options", "--", "--ignored", "-Dprop=val");
488         final WriteableCommandLine commandLine = commandLine(option, args);
489         final ListIterator iterator = args.listIterator();
490 
491         option.process(commandLine, iterator);
492 
493         final List values = commandLine.getValues(option);
494         assertTrue(values.contains("options"));
495         assertTrue(values.contains("--ignored"));
496         assertTrue(values.contains("-Dprop=val"));
497         assertEquals(3, values.size());
498         assertFalse(iterator.hasNext());
499     }
500 
501     public void testProcess_ConsumeNothing() {
502         final Option option = buildPathArgument();
503         final List args = list("--");
504         final WriteableCommandLine commandLine = commandLine(option, args);
505         final ListIterator iterator = args.listIterator();
506 
507         try {
508             option.process(commandLine, iterator);
509             option.validate(commandLine);
510             fail("Missing Value!");
511         } catch (OptionException mve) {
512             assertEquals(option, mve.getOption());
513             assertEquals("Missing value(s) path [path ...]", mve.getMessage());
514         }
515 
516         assertTrue(commandLine.getValues(option).isEmpty());
517         assertFalse(iterator.hasNext());
518     }
519 
520     //    public void testProcess_DefinedDefaultValue() throws OptionException {
521     //        final Option size = buildSizeArgument();
522     //        final List args = list();
523     //        final WriteableCommandLine commandLine = commandLine(size, args);
524     //        final ListIterator iterator = args.listIterator();
525     //
526     //        size.process(commandLine, iterator);
527     //
528     //        assertEquals("10", commandLine.getValue(size));
529     //    }
530     //
531     //    public void testProcess_DefinedDefaultValues() throws OptionException {
532     //        final Option bounds = buildBoundsArgument();
533     //        final List args = list();
534     //        final WriteableCommandLine commandLine = commandLine(bounds, args);
535     //        final ListIterator iterator = args.listIterator();
536     //
537     //        bounds.process(commandLine, iterator);
538     //
539     //        List values = new ArrayList();
540     //        values.add("5");
541     //        values.add("10");
542     //        assertEquals(values, commandLine.getValues(bounds));
543     //    }
544     public void testProcess_InterrogatedDefaultValue()
545         throws OptionException {
546         final Option size = buildSizeArgument();
547         final List args = list();
548         final WriteableCommandLine commandLine = commandLine(size, args);
549         final ListIterator iterator = args.listIterator();
550 
551         size.process(commandLine, iterator);
552 
553         assertEquals(new Integer(20), commandLine.getValue(size, new Integer(20)));
554     }
555 
556     public void testTooFewDefaults() {
557         List defaults = new ArrayList();
558         defaults.add("5");
559 
560         try {
561             new ArgumentImpl("size", "The number of units", 2, 2, '\0', '\0', null,
562                              ArgumentImpl.DEFAULT_CONSUME_REMAINING, defaults, 0);
563         } catch (IllegalArgumentException exp) {
564             assertEquals("wrong exception message",
565                          ResourceHelper.getResourceHelper().getMessage(ResourceConstants.ARGUMENT_TOO_FEW_DEFAULTS),
566                          exp.getMessage());
567         }
568     }
569 
570     public void testTooManyDefaults() {
571         List defaults = new ArrayList();
572         defaults.add("5");
573         defaults.add("10");
574         defaults.add("15");
575 
576         try {
577             new ArgumentImpl("size", "The number of units", 2, 2, '\0', '\0', null,
578                              ArgumentImpl.DEFAULT_CONSUME_REMAINING, defaults, 0);
579         } catch (IllegalArgumentException exp) {
580             assertEquals("wrong exception message",
581                          ResourceHelper.getResourceHelper().getMessage(ResourceConstants.ARGUMENT_TOO_MANY_DEFAULTS),
582                          exp.getMessage());
583         }
584     }
585 
586     public void testProcess_InterrogatedDefaultValues()
587         throws OptionException {
588         final Option bounds = buildBoundsArgument();
589         final List args = list();
590         final WriteableCommandLine commandLine = commandLine(bounds, args);
591         final ListIterator iterator = args.listIterator();
592 
593         bounds.process(commandLine, iterator);
594 
595         // test with values
596         List values = new ArrayList();
597         values.add("50");
598         values.add("100");
599         assertEquals(values, commandLine.getValues(bounds, values));
600 
601         // test without values
602         assertEquals(Collections.EMPTY_LIST, commandLine.getValues(bounds, null));
603     }
604 
605     public void testProcess_StripBoundaryQuotes()
606         throws OptionException {
607         final Option bounds = buildBoundsArgument();
608         final List args = list();
609         final WriteableCommandLine commandLine = commandLine(bounds, args);
610         final ListIterator iterator = args.listIterator();
611 
612         bounds.process(commandLine, iterator);
613 
614         List values = new ArrayList();
615         values.add("50\"");
616         values.add("\"100");
617         assertEquals(values, commandLine.getValues(bounds, values));
618     }
619 
620     public void testSourceDestArgument() {
621         final ArgumentBuilder abuilder = new ArgumentBuilder();
622         final GroupBuilder gbuilder = new GroupBuilder();
623         final Argument inputfiles =
624             abuilder.withName("input").withMinimum(0).withMaximum(0).create();
625         final Argument bad_outputfile =
626             abuilder.withName("output").withMinimum(1).withMaximum(2).create();
627 
628         try {
629             final Argument targets = new SourceDestArgument(inputfiles, bad_outputfile);
630         } catch (final IllegalArgumentException exp) {
631             assertEquals("wrong exception message",
632                          ResourceHelper.getResourceHelper().getMessage(ResourceConstants.SOURCE_DEST_MUST_ENFORCE_VALUES),
633                          exp.getMessage());
634         }
635 
636         final Argument outputfile =
637             abuilder.withName("output").withMinimum(1).withMaximum(1).create();
638 
639         final Argument targets = new SourceDestArgument(inputfiles, outputfile);
640         final StringBuffer buffer = new StringBuffer("test content");
641         targets.appendUsage(buffer, Collections.EMPTY_SET, null);
642 
643         assertTrue("buffer not added", buffer.toString().startsWith("test content"));
644         assertFalse("space added", buffer.charAt(12) == ' ');
645     }
646 }