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;
19  
20  import static org.junit.Assert.assertEquals;
21  import static org.junit.Assert.assertTrue;
22  
23  import java.io.PrintWriter;
24  import java.io.StringWriter;
25  
26  import org.junit.Test;
27  
28  /**
29   * This is a collection of tests that test real world applications command lines.
30   *
31   * <p>
32   * The following applications are tested:
33   * <ul>
34   * <li>ls</li>
35   * <li>Ant</li>
36   * <li>Groovy</li>
37   * <li>man</li>
38   * </ul>
39   * </p>
40   */
41  @SuppressWarnings("deprecation") // tests some deprecated classes
42  public class ApplicationTest {
43      /**
44       * Ant test
45       */
46      @Test
47      public void testAnt() throws Exception {
48          // use the GNU parser
49          final CommandLineParser parser = new GnuParser();
50          final Options options = new Options();
51          options.addOption("help", false, "print this message");
52          options.addOption("projecthelp", false, "print project help information");
53          options.addOption("version", false, "print the version information and exit");
54          options.addOption("quiet", false, "be extra quiet");
55          options.addOption("verbose", false, "be extra verbose");
56          options.addOption("debug", false, "print debug information");
57          options.addOption("logfile", true, "use given file for log");
58          options.addOption("logger", true, "the class which is to perform the logging");
59          options.addOption("listener", true, "add an instance of a class as a project listener");
60          options.addOption("buildfile", true, "use given buildfile");
61          //@formatter:off
62          options.addOption(OptionBuilder.withDescription("use value for given property")
63                                          .hasArgs()
64                                          .withValueSeparator()
65                                          .create('D'));
66                             //, null, true, , false, true);
67          //@formatter:on
68          options.addOption("find", true, "search for buildfile towards the root of the filesystem and use it");
69  
70          final String[] args = {"-buildfile", "mybuild.xml", "-Dproperty=value", "-Dproperty1=value1", "-projecthelp"};
71  
72          final CommandLine line = parser.parse(options, args);
73  
74          // check multiple values
75          final String[] opts = line.getOptionValues("D");
76          assertEquals("property", opts[0]);
77          assertEquals("value", opts[1]);
78          assertEquals("property1", opts[2]);
79          assertEquals("value1", opts[3]);
80  
81          // check single value
82          assertEquals(line.getOptionValue("buildfile"), "mybuild.xml");
83  
84          // check option
85          assertTrue(line.hasOption("projecthelp"));
86      }
87  
88      @Test
89      public void testGroovy() throws Exception {
90          final Options options = new Options();
91  
92          //@formatter:off
93          options.addOption(
94              OptionBuilder.withLongOpt("define").
95                  withDescription("define a system property").
96                  hasArg(true).
97                  withArgName("name=value").
98                  create('D'));
99          options.addOption(
100             OptionBuilder.hasArg(false)
101                 .withDescription("usage information")
102                 .withLongOpt("help")
103                 .create('h'));
104         options.addOption(
105             OptionBuilder.hasArg(false)
106                 .withDescription("debug mode will print out full stack traces")
107                 .withLongOpt("debug")
108                 .create('d'));
109         options.addOption(
110             OptionBuilder.hasArg(false)
111                 .withDescription("display the Groovy and JVM versions")
112                 .withLongOpt("version")
113                 .create('v'));
114         options.addOption(
115             OptionBuilder.withArgName("charset")
116                 .hasArg()
117                 .withDescription("specify the encoding of the files")
118                 .withLongOpt("encoding")
119                 .create('c'));
120         options.addOption(
121             OptionBuilder.withArgName("script")
122                 .hasArg()
123                 .withDescription("specify a command line script")
124                 .create('e'));
125         options.addOption(
126             OptionBuilder.withArgName("extension")
127                 .hasOptionalArg()
128                 .withDescription("modify files in place; create backup if extension is given (e.g. \'.bak\')")
129                 .create('i'));
130         options.addOption(
131             OptionBuilder.hasArg(false)
132                 .withDescription("process files line by line using implicit 'line' variable")
133                 .create('n'));
134         options.addOption(
135             OptionBuilder.hasArg(false)
136                 .withDescription("process files line by line and print result (see also -n)")
137                 .create('p'));
138         options.addOption(
139             OptionBuilder.withArgName("port")
140                 .hasOptionalArg()
141                 .withDescription("listen on a port and process inbound lines")
142                 .create('l'));
143         options.addOption(
144             OptionBuilder.withArgName("splitPattern")
145                 .hasOptionalArg()
146                 .withDescription("split lines using splitPattern (default '\\s') using implicit 'split' variable")
147                 .withLongOpt("autosplit")
148                 .create('a'));
149         //@formatter:on
150 
151         final Parser parser = new PosixParser();
152         final CommandLine line = parser.parse(options, new String[] {"-e", "println 'hello'"}, true);
153 
154         assertTrue(line.hasOption('e'));
155         assertEquals("println 'hello'", line.getOptionValue('e'));
156     }
157 
158     @Test
159     public void testLs() throws Exception {
160         // create the command line parser
161         final CommandLineParser parser = new PosixParser();
162         final Options options = new Options();
163         options.addOption("a", "all", false, "do not hide entries starting with .");
164         options.addOption("A", "almost-all", false, "do not list implied . and ..");
165         options.addOption("b", "escape", false, "print octal escapes for nongraphic characters");
166         //@formatter:off
167         options.addOption(OptionBuilder.withLongOpt("block-size")
168                                         .withDescription("use SIZE-byte blocks")
169                                         .hasArg()
170                                         .withArgName("SIZE")
171                                         .create());
172         //@formatter:on
173         options.addOption("B", "ignore-backups", false, "do not list implied entried ending with ~");
174         options.addOption("c", false, "with -lt: sort by, and show, ctime (time of last modification of file status information) with "
175             + "-l:show ctime and sort by name otherwise: sort by ctime");
176         options.addOption("C", false, "list entries by columns");
177 
178         final String[] args = {"--block-size=10"};
179 
180         final CommandLine line = parser.parse(options, args);
181         assertTrue(line.hasOption("block-size"));
182         assertEquals(line.getOptionValue("block-size"), "10");
183     }
184 
185     /**
186      * author Slawek Zachcial
187      */
188     @Test
189     public void testMan() {
190         final String cmdLine = "man [-c|-f|-k|-w|-tZT device] [-adlhu7V] [-Mpath] [-Ppager] [-Slist] [-msystem] [-pstring] [-Llocale] [-eextension] [section]"
191             + " page ...";
192         //@formatter:off
193         final Options options = new Options().
194                 addOption("a", "all", false, "find all matching manual pages.").
195                 addOption("d", "debug", false, "emit debugging messages.").
196                 addOption("e", "extension", false, "limit search to extension type 'extension'.").
197                 addOption("f", "whatis", false, "equivalent to whatis.").
198                 addOption("k", "apropos", false, "equivalent to apropos.").
199                 addOption("w", "location", false, "print physical location of man page(s).").
200                 addOption("l", "local-file", false, "interpret 'page' argument(s) as local file name(s)").
201                 addOption("u", "update", false, "force a cache consistency check.").
202                 //FIXME - should generate -r,--prompt string
203                 addOption("r", "prompt", true, "provide 'less' pager with prompt.").
204                 addOption("c", "catman", false, "used by catman to reformat out of date cat pages.").
205                 addOption("7", "ascii", false, "display ASCII translation or certain latin1 chars.").
206                 addOption("t", "troff", false, "use troff format pages.").
207                 //FIXME - should generate -T,--troff-device device
208                 addOption("T", "troff-device", true, "use groff with selected device.").
209                 addOption("Z", "ditroff", false, "use groff with selected device.").
210                 addOption("D", "default", false, "reset all options to their default values.").
211                 //FIXME - should generate -M,--manpath path
212                 addOption("M", "manpath", true, "set search path for manual pages to 'path'.").
213                 //FIXME - should generate -P,--pager pager
214                 addOption("P", "pager", true, "use program 'pager' to display output.").
215                 //FIXME - should generate -S,--sections list
216                 addOption("S", "sections", true, "use colon separated section list.").
217                 //FIXME - should generate -m,--systems system
218                 addOption("m", "systems", true, "search for man pages from other Unix system(s).").
219                 //FIXME - should generate -L,--locale locale
220                 addOption("L", "locale", true, "define the locale for this particular man search.").
221                 //FIXME - should generate -p,--preprocessor string
222                 addOption("p", "preprocessor", true, "string indicates which preprocessor to run.\n" +
223                          " e - [n]eqn  p - pic     t - tbl\n" +
224                          " g - grap    r - refer   v - vgrind").
225                 addOption("V", "version", false, "show version.").
226                 addOption("h", "help", false, "show this usage message.");
227         //@formatter:on
228 
229         final HelpFormatter hf = new HelpFormatter();
230         final String eol = System.lineSeparator();
231         final StringWriter out = new StringWriter();
232         hf.printHelp(new PrintWriter(out), 60, cmdLine, null, options, HelpFormatter.DEFAULT_LEFT_PAD, HelpFormatter.DEFAULT_DESC_PAD, null, false);
233         //@formatter:off
234         assertEquals("usage: man [-c|-f|-k|-w|-tZT device] [-adlhu7V] [-Mpath]" + eol +
235                         "           [-Ppager] [-Slist] [-msystem] [-pstring]" + eol +
236                         "           [-Llocale] [-eextension] [section] page ..." + eol +
237                         " -7,--ascii                display ASCII translation or" + eol +
238                         "                           certain latin1 chars." + eol +
239                         " -a,--all                  find all matching manual pages." + eol +
240                         " -c,--catman               used by catman to reformat out of" + eol +
241                         "                           date cat pages." + eol +
242                         " -d,--debug                emit debugging messages." + eol +
243                         " -D,--default              reset all options to their" + eol +
244                         "                           default values." + eol +
245                         " -e,--extension            limit search to extension type" + eol +
246                         "                           'extension'." + eol +
247                         " -f,--whatis               equivalent to whatis." + eol +
248                         " -h,--help                 show this usage message." + eol +
249                         " -k,--apropos              equivalent to apropos." + eol +
250                         " -l,--local-file           interpret 'page' argument(s) as" + eol +
251                         "                           local file name(s)" + eol +
252                         " -L,--locale <arg>         define the locale for this" + eol +
253                         "                           particular man search." + eol +
254                         " -M,--manpath <arg>        set search path for manual pages" + eol +
255                         "                           to 'path'." + eol +
256                         " -m,--systems <arg>        search for man pages from other" + eol +
257                         "                           Unix system(s)." + eol +
258                         " -P,--pager <arg>          use program 'pager' to display" + eol +
259                         "                           output." + eol +
260                         " -p,--preprocessor <arg>   string indicates which" + eol +
261                         "                           preprocessor to run." + eol +
262                         "                           e - [n]eqn  p - pic     t - tbl" + eol +
263                         "                           g - grap    r - refer   v -" + eol +
264                         "                           vgrind" + eol +
265                         " -r,--prompt <arg>         provide 'less' pager with prompt." + eol +
266                         " -S,--sections <arg>       use colon separated section list." + eol +
267                         " -t,--troff                use troff format pages." + eol +
268                         " -T,--troff-device <arg>   use groff with selected device." + eol +
269                         " -u,--update               force a cache consistency check." + eol +
270                         " -V,--version              show version." + eol +
271                         " -w,--location             print physical location of man" + eol +
272                         "                           page(s)." + eol +
273                         " -Z,--ditroff              use groff with selected device." + eol,
274                 out.toString());
275         //@formatter:on
276     }
277 
278     /**
279      * Real world test with long and short options.
280      */
281     @Test
282     public void testNLT() throws Exception {
283         final Option help = new Option("h", "help", false, "print this message");
284         final Option version = new Option("v", "version", false, "print version information");
285         final Option newRun = new Option("n", "new", false, "Create NLT cache entries only for new items");
286         final Option trackerRun = new Option("t", "tracker", false, "Create NLT cache entries only for tracker items");
287 
288         //@formatter:off
289         final Option timeLimit = OptionBuilder.withLongOpt("limit").hasArg()
290                                         .withValueSeparator()
291                                         .withDescription("Set time limit for execution, in minutes")
292                                         .create("l");
293 
294         final Option age = OptionBuilder.withLongOpt("age").hasArg()
295                                   .withValueSeparator()
296                                   .withDescription("Age (in days) of cache item before being recomputed")
297                                   .create("a");
298 
299         final Option server = OptionBuilder.withLongOpt("server").hasArg()
300                                      .withValueSeparator()
301                                      .withDescription("The NLT server address")
302                                      .create("s");
303 
304         final Option numResults = OptionBuilder.withLongOpt("results").hasArg()
305                                          .withValueSeparator()
306                                          .withDescription("Number of results per item")
307                                          .create("r");
308 
309         final Option configFile = OptionBuilder.withLongOpt("file").hasArg()
310                                          .withValueSeparator()
311                                          .withDescription("Use the specified configuration file")
312                                          .create();
313         //@formatter:on
314 
315         final Options options = new Options();
316         options.addOption(help);
317         options.addOption(version);
318         options.addOption(newRun);
319         options.addOption(trackerRun);
320         options.addOption(timeLimit);
321         options.addOption(age);
322         options.addOption(server);
323         options.addOption(numResults);
324         options.addOption(configFile);
325 
326         // create the command line parser
327         final CommandLineParser parser = new PosixParser();
328 
329         final String[] args = {"-v", "-l", "10", "-age", "5", "-file", "filename"};
330 
331         final CommandLine line = parser.parse(options, args);
332         assertTrue(line.hasOption("v"));
333         assertEquals(line.getOptionValue("l"), "10");
334         assertEquals(line.getOptionValue("limit"), "10");
335         assertEquals(line.getOptionValue("a"), "5");
336         assertEquals(line.getOptionValue("age"), "5");
337         assertEquals(line.getOptionValue("file"), "filename");
338     }
339 }