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  
18  package org.apache.commons.cli.bug;
19  
20  import static org.junit.Assert.assertEquals;
21  import static org.junit.Assert.assertFalse;
22  import static org.junit.Assert.assertNotEquals;
23  import static org.junit.Assert.assertNull;
24  import static org.junit.Assert.assertTrue;
25  
26  import org.apache.commons.cli.CommandLine;
27  import org.apache.commons.cli.DefaultParser;
28  import org.apache.commons.cli.Option;
29  import org.apache.commons.cli.Options;
30  import org.junit.Before;
31  import org.junit.Test;
32  
33  /**
34   * Test for CLI-265.
35   * <p>
36   * The issue is that a short option with an optional value will use whatever comes next as value.
37   */
38  public class BugCLI265Test {
39  
40      private DefaultParser parser;
41      private Options options;
42  
43      @Before
44      public void setUp() {
45          parser = new DefaultParser();
46  
47          final Option optionT1 = Option.builder("t1").hasArg().numberOfArgs(1).optionalArg(true).argName("t1_path").build();
48          final Option optionA = Option.builder("a").hasArg(false).build();
49          final Option optionB = Option.builder("b").hasArg(false).build();
50          final Option optionLast = Option.builder("last").hasArg(false).build();
51  
52          options = new Options().addOption(optionT1).addOption(optionA).addOption(optionB).addOption(optionLast);
53      }
54  
55      @Test
56      public void shouldParseConcatenatedShortOptions() throws Exception {
57          final String[] concatenatedShortOptions = {"-t1", "-ab"};
58  
59          final CommandLine commandLine = parser.parse(options, concatenatedShortOptions);
60  
61          assertTrue(commandLine.hasOption("t1"));
62          assertNull(commandLine.getOptionValue("t1"));
63          assertTrue(commandLine.hasOption("a"));
64          assertTrue(commandLine.hasOption("b"));
65          assertFalse(commandLine.hasOption("last"));
66      }
67  
68      @Test
69      public void shouldParseShortOptionWithoutValue() throws Exception {
70          final String[] twoShortOptions = {"-t1", "-last"};
71  
72          final CommandLine commandLine = parser.parse(options, twoShortOptions);
73  
74          assertTrue(commandLine.hasOption("t1"));
75          assertNotEquals("Second option has been used as value for first option", "-last", commandLine.getOptionValue("t1"));
76          assertTrue("Second option has not been detected", commandLine.hasOption("last"));
77      }
78  
79      @Test
80      public void shouldParseShortOptionWithValue() throws Exception {
81          final String[] shortOptionWithValue = {"-t1", "path/to/my/db"};
82  
83          final CommandLine commandLine = parser.parse(options, shortOptionWithValue);
84  
85          assertEquals("path/to/my/db", commandLine.getOptionValue("t1"));
86          assertFalse(commandLine.hasOption("last"));
87      }
88  }