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.jupiter.api.Assertions.assertEquals;
21  import static org.junit.jupiter.api.Assertions.assertFalse;
22  import static org.junit.jupiter.api.Assertions.assertNotNull;
23  import static org.junit.jupiter.api.Assertions.assertNull;
24  import static org.junit.jupiter.api.Assertions.assertTrue;
25  import static org.junit.jupiter.api.Assertions.fail;
26  
27  import java.io.ByteArrayOutputStream;
28  import java.io.PrintStream;
29  import java.io.PrintWriter;
30  import java.util.Iterator;
31  import java.util.Properties;
32  
33  import org.apache.commons.cli.CommandLine;
34  import org.apache.commons.cli.CommandLineParser;
35  import org.apache.commons.cli.GnuParser;
36  import org.apache.commons.cli.HelpFormatter;
37  import org.apache.commons.cli.MissingArgumentException;
38  import org.apache.commons.cli.Option;
39  import org.apache.commons.cli.OptionBuilder;
40  import org.apache.commons.cli.OptionGroup;
41  import org.apache.commons.cli.Options;
42  import org.apache.commons.cli.ParseException;
43  import org.apache.commons.cli.Parser;
44  import org.apache.commons.cli.PosixParser;
45  import org.junit.jupiter.api.Test;
46  
47  @SuppressWarnings("deprecation") // tests some deprecated classes
48  public class BugsTest {
49      @Test
50      public void test11456() throws Exception {
51          // POSIX
52          Options options = new Options();
53          options.addOption(OptionBuilder.hasOptionalArg().create('a'));
54          options.addOption(OptionBuilder.hasArg().create('b'));
55          String[] args = {"-a", "-bvalue"};
56  
57          CommandLineParser parser = new PosixParser();
58  
59          CommandLine cmd = parser.parse(options, args);
60          assertEquals(cmd.getOptionValue('b'), "value");
61  
62          // GNU
63          options = new Options();
64          options.addOption(OptionBuilder.hasOptionalArg().create('a'));
65          options.addOption(OptionBuilder.hasArg().create('b'));
66          args = new String[] {"-a", "-b", "value"};
67  
68          parser = new GnuParser();
69  
70          cmd = parser.parse(options, args);
71          assertEquals(cmd.getOptionValue('b'), "value");
72      }
73  
74      @Test
75      public void test11457() throws Exception {
76          final Options options = new Options();
77          options.addOption(OptionBuilder.withLongOpt("verbose").create());
78          final String[] args = {"--verbose"};
79  
80          final CommandLineParser parser = new PosixParser();
81  
82          final CommandLine cmd = parser.parse(options, args);
83          assertTrue(cmd.hasOption("verbose"));
84      }
85  
86      @Test
87      public void test11458() throws Exception {
88          final Options options = new Options();
89          options.addOption(OptionBuilder.withValueSeparator('=').hasArgs().create('D'));
90          options.addOption(OptionBuilder.withValueSeparator(':').hasArgs().create('p'));
91          final String[] args = {"-DJAVA_HOME=/opt/java", "-pfile1:file2:file3"};
92  
93          final CommandLineParser parser = new PosixParser();
94  
95          final CommandLine cmd = parser.parse(options, args);
96  
97          String[] values = cmd.getOptionValues('D');
98  
99          assertEquals(values[0], "JAVA_HOME");
100         assertEquals(values[1], "/opt/java");
101 
102         values = cmd.getOptionValues('p');
103 
104         assertEquals(values[0], "file1");
105         assertEquals(values[1], "file2");
106         assertEquals(values[2], "file3");
107 
108         final Iterator<Option> iter = cmd.iterator();
109         while (iter.hasNext()) {
110             final Option opt = iter.next();
111             switch (opt.getId()) {
112             case 'D':
113                 assertEquals(opt.getValue(0), "JAVA_HOME");
114                 assertEquals(opt.getValue(1), "/opt/java");
115                 break;
116             case 'p':
117                 assertEquals(opt.getValue(0), "file1");
118                 assertEquals(opt.getValue(1), "file2");
119                 assertEquals(opt.getValue(2), "file3");
120                 break;
121             default:
122                 fail("-D option not found");
123             }
124         }
125     }
126 
127     @Test
128     public void test11680() throws Exception {
129         final Options options = new Options();
130         final Option optionF = options.addOption("f", true, "foobar").getOption("f");
131         final Option optionM = options.addOption("m", true, "missing").getOption("m");
132         final String[] args = { "-f", "foo" };
133         final CommandLineParser parser = new PosixParser();
134         final CommandLine cmd = parser.parse(options, args);
135         // 1.7.0 API:
136         cmd.getOptionValue(optionF, () -> "default f");
137         cmd.getOptionValue(optionM, () -> "default m");
138         // 1.7.0 API:
139         cmd.getOptionValue('f', () -> "default f");
140         cmd.getOptionValue('m', () -> "default m");
141         // 1.5.0 API:
142         cmd.getOptionValue(optionF, "default f");
143         cmd.getOptionValue(optionM, "default m");
144         // Original API:
145         cmd.getOptionValue("f", "default f");
146         cmd.getOptionValue("m", "default m");
147         //
148         assertNull(cmd.getOptionValue((String) null, (String) null));
149         assertEquals("default", cmd.getOptionValue((String) null, "default"));
150     }
151 
152     @Test
153     public void test12210() throws Exception {
154         // create the main options object which will handle the first parameter
155         final Options mainOptions = new Options();
156         // There can be 2 main exclusive options: -exec|-rep
157 
158         // Therefore, place them in an option group
159 
160         String[] argv = {"-exec", "-exec_opt1", "-exec_opt2"};
161         final OptionGroup grp = new OptionGroup();
162 
163         grp.addOption(new Option("exec", false, "description for this option"));
164 
165         grp.addOption(new Option("rep", false, "description for this option"));
166 
167         mainOptions.addOptionGroup(grp);
168 
169         // for the exec option, there are 2 options...
170         final Options execOptions = new Options();
171         execOptions.addOption("exec_opt1", false, " desc");
172         execOptions.addOption("exec_opt2", false, " desc");
173 
174         // similarly, for rep there are 2 options...
175         final Options repOptions = new Options();
176         repOptions.addOption("repopto", false, "desc");
177         repOptions.addOption("repoptt", false, "desc");
178 
179         // create the parser
180         final GnuParser parser = new GnuParser();
181 
182         // finally, parse the arguments:
183 
184         // first parse the main options to see what the user has specified
185         // We set stopAtNonOption to true so it does not touch the remaining
186         // options
187         CommandLine cmd = parser.parse(mainOptions, argv, true);
188         // get the remaining options...
189         argv = cmd.getArgs();
190 
191         if (cmd.hasOption("exec")) {
192             cmd = parser.parse(execOptions, argv, false);
193             // process the exec_op1 and exec_opt2...
194             assertTrue(cmd.hasOption("exec_opt1"));
195             assertTrue(cmd.hasOption("exec_opt2"));
196         } else if (cmd.hasOption("rep")) {
197             cmd = parser.parse(repOptions, argv, false);
198             // process the rep_op1 and rep_opt2...
199         } else {
200             fail("exec option not found");
201         }
202     }
203 
204     @Test
205     public void test13425() throws Exception {
206         final Options options = new Options();
207         //@formatter:off
208         final Option oldpass = OptionBuilder.withLongOpt("old-password")
209             .withDescription("Use this option to specify the old password")
210             .hasArg()
211             .create('o');
212         final Option newpass = OptionBuilder.withLongOpt("new-password")
213             .withDescription("Use this option to specify the new password")
214             .hasArg()
215             .create('n');
216         //@formatter:on
217 
218         final String[] args = {"-o", "-n", "newpassword"};
219 
220         options.addOption(oldpass);
221         options.addOption(newpass);
222 
223         final Parser parser = new PosixParser();
224 
225         try {
226             parser.parse(options, args);
227             fail("MissingArgumentException not caught.");
228         } catch (final MissingArgumentException expected) {
229         }
230     }
231 
232     @Test
233     public void test13666() throws Exception {
234         final Options options = new Options();
235         final Option dirOption = OptionBuilder.withDescription("dir").hasArg().create('d');
236         options.addOption(dirOption);
237         final PrintStream oldSystemOut = System.out;
238         try {
239             final ByteArrayOutputStream baos = new ByteArrayOutputStream();
240             final String eol = System.lineSeparator();
241             System.setOut(new PrintStream(baos));
242             final HelpFormatter formatter = new HelpFormatter();
243             formatter.printHelp("dir", options);
244             assertEquals("usage: dir" + eol + " -d <arg>   dir" + eol, baos.toString());
245         } finally {
246             System.setOut(oldSystemOut);
247         }
248     }
249 
250     @Test
251     public void test13666_Builder() throws Exception {
252         final Options options = new Options();
253         final Option dirOption = OptionBuilder.withDescription("dir").hasArg().create('d');
254         options.addOption(dirOption);
255         final ByteArrayOutputStream baos = new ByteArrayOutputStream();
256         final String eol = System.lineSeparator();
257         final HelpFormatter formatter = HelpFormatter.builder().setPrintWriter(new PrintWriter(baos)).get();
258         formatter.printHelp("dir", options);
259         assertEquals("usage: dir" + eol + " -d <arg>   dir" + eol, baos.toString());
260     }
261 
262     @Test
263     public void test13935() throws Exception {
264         final OptionGroup directions = new OptionGroup();
265 
266         final Option left = new Option("l", "left", false, "go left");
267         final Option right = new Option("r", "right", false, "go right");
268         final Option straight = new Option("s", "straight", false, "go straight");
269         final Option forward = new Option("f", "forward", false, "go forward");
270         forward.setRequired(true);
271 
272         directions.addOption(left);
273         directions.addOption(right);
274         directions.setRequired(true);
275 
276         final Options opts = new Options();
277         opts.addOptionGroup(directions);
278         opts.addOption(straight);
279 
280         final CommandLineParser parser = new PosixParser();
281 
282         String[] args = {};
283         try {
284             parser.parse(opts, args);
285             fail("Expected ParseException");
286         } catch (final ParseException expected) {
287         }
288 
289         args = new String[] {"-s"};
290         try {
291             parser.parse(opts, args);
292             fail("Expected ParseException");
293         } catch (final ParseException expected) {
294         }
295 
296         args = new String[] {"-s", "-l"};
297         CommandLine line = parser.parse(opts, args);
298         assertNotNull(line);
299 
300         opts.addOption(forward);
301         args = new String[] {"-s", "-l", "-f"};
302         line = parser.parse(opts, args);
303         assertNotNull(line);
304     }
305 
306     @Test
307     public void test14786() throws Exception {
308         final Option o = OptionBuilder.isRequired().withDescription("test").create("test");
309         final Options opts = new Options();
310         opts.addOption(o);
311         opts.addOption(o);
312 
313         final CommandLineParser parser = new GnuParser();
314 
315         final String[] args = {"-test"};
316 
317         final CommandLine line = parser.parse(opts, args);
318         assertTrue(line.hasOption("test"));
319     }
320 
321     @Test
322     public void test15046() throws Exception {
323         final CommandLineParser parser = new PosixParser();
324         final String[] cliArgs = {"-z", "c"};
325 
326         final Options options = new Options();
327         options.addOption(new Option("z", "timezone", true, "affected option"));
328 
329         parser.parse(options, cliArgs);
330 
331         // now add conflicting option
332         options.addOption("c", "conflict", true, "conflict option");
333         final CommandLine line = parser.parse(options, cliArgs);
334         assertEquals(line.getOptionValue('z'), "c");
335         assertFalse(line.hasOption("c"));
336     }
337 
338     @Test
339     public void test15648() throws Exception {
340         final CommandLineParser parser = new PosixParser();
341         final String[] args = {"-m", "\"Two Words\""};
342         final Option m = OptionBuilder.hasArgs().create("m");
343         final Options options = new Options();
344         options.addOption(m);
345         final CommandLine line = parser.parse(options, args);
346         assertEquals("Two Words", line.getOptionValue("m"));
347     }
348 
349     @Test
350     public void test31148() throws ParseException {
351         final Option multiArgOption = new Option("o", "option with multiple args");
352         multiArgOption.setArgs(1);
353 
354         final Options options = new Options();
355         options.addOption(multiArgOption);
356 
357         final Parser parser = new PosixParser();
358         final String[] args = {};
359         final Properties props = new Properties();
360         props.setProperty("o", "ovalue");
361         final CommandLine cl = parser.parse(options, args, props);
362 
363         assertTrue(cl.hasOption('o'));
364         assertEquals("ovalue", cl.getOptionValue('o'));
365     }
366 
367 }