001/*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 * http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing,
013 * software distributed under the License is distributed on an
014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 * KIND, either express or implied.  See the License for the
016 * specific language governing permissions and limitations
017 * under the License.
018 */
019package org.apache.commons.cli2.util;
020
021import java.io.BufferedReader;
022import java.io.IOException;
023import java.io.PrintWriter;
024import java.io.StringReader;
025import java.io.StringWriter;
026
027import java.util.Collections;
028import java.util.Comparator;
029import java.util.HashSet;
030import java.util.Iterator;
031import java.util.List;
032import java.util.Set;
033
034import junit.framework.TestCase;
035
036import org.apache.commons.cli2.DisplaySetting;
037import org.apache.commons.cli2.Group;
038import org.apache.commons.cli2.Option;
039import org.apache.commons.cli2.OptionException;
040import org.apache.commons.cli2.builder.DefaultOptionBuilder;
041import org.apache.commons.cli2.builder.GroupBuilder;
042import org.apache.commons.cli2.option.ArgumentTest;
043import org.apache.commons.cli2.option.DefaultOptionTest;
044import org.apache.commons.cli2.resource.ResourceConstants;
045import org.apache.commons.cli2.resource.ResourceHelper;
046
047public class HelpFormatterTest
048    extends TestCase {
049    private ResourceHelper resources = ResourceHelper.getResourceHelper();
050    private HelpFormatter helpFormatter;
051    private Option verbose;
052    private Group options;
053
054    public void setUp() {
055        helpFormatter = new HelpFormatter("|*", "*-*", "*|", 80);
056        helpFormatter.setDivider("+------------------------------------------------------------------------------+");
057        helpFormatter.setHeader("Apache Commons CLI");
058        helpFormatter.setFooter("Copyright 2003\nApache Software Foundation");
059        helpFormatter.setShellCommand("ant");
060
061        verbose =
062            new DefaultOptionBuilder().withLongName("verbose")
063                                      .withDescription("print the version information and exit")
064                                      .create();
065
066        options =
067            new GroupBuilder().withName("options").withOption(DefaultOptionTest.buildHelpOption())
068                              .withOption(ArgumentTest.buildTargetsArgument())
069                              .withOption(new DefaultOptionBuilder().withLongName("diagnostics")
070                                                                    .withDescription("print information that might be helpful to diagnose or report problems.")
071                                                                    .create())
072                              .withOption(new DefaultOptionBuilder().withLongName("projecthelp")
073                                                                    .withDescription("print project help information")
074                                                                    .create()).withOption(verbose)
075                              .create();
076
077        helpFormatter.setGroup(options);
078    }
079
080    public void testPrint()
081        throws IOException {
082        final StringWriter writer = new StringWriter();
083        final PrintWriter pw = new PrintWriter(writer);
084        helpFormatter.setPrintWriter(pw);
085        helpFormatter.print();
086
087        // test shell
088        assertEquals("incorrect shell command", "ant", helpFormatter.getShellCommand());
089
090        // test group
091        assertEquals("incorrect group", this.options, helpFormatter.getGroup());
092
093        // test pagewidth
094        assertEquals("incorrect page width", 76, helpFormatter.getPageWidth());
095
096        // test pw
097        assertEquals("incorrect print writer", pw, helpFormatter.getPrintWriter());
098
099        // test divider
100        assertEquals("incorrect divider",
101                     "+------------------------------------------------------------------------------+",
102                     helpFormatter.getDivider());
103
104        // test header
105        assertEquals("incorrect header", "Apache Commons CLI", helpFormatter.getHeader());
106
107        // test footer
108        assertEquals("incorrect footer", "Copyright 2003\nApache Software Foundation",
109                     helpFormatter.getFooter());
110
111        // test gutters
112        assertEquals("incorrect left gutter", "|*", helpFormatter.getGutterLeft());
113        assertEquals("incorrect right gutter", "*|", helpFormatter.getGutterRight());
114        assertEquals("incorrect center gutter", "*-*", helpFormatter.getGutterCenter());
115
116        final BufferedReader reader = new BufferedReader(new StringReader(writer.toString()));
117        assertEquals("+------------------------------------------------------------------------------+",
118                     reader.readLine());
119        assertEquals("|*Apache Commons CLI                                                          *|",
120                     reader.readLine());
121        assertEquals("+------------------------------------------------------------------------------+",
122                     reader.readLine());
123        assertEquals("|*Usage:                                                                      *|",
124                     reader.readLine());
125        assertEquals("|*ant [--help --diagnostics --projecthelp --verbose] [<target1> [<target2>    *|",
126                     reader.readLine());
127        assertEquals("|*...]]                                                                       *|",
128                     reader.readLine());
129        assertEquals("+------------------------------------------------------------------------------+",
130                     reader.readLine());
131        assertEquals("|*options              *-*                                                    *|",
132                     reader.readLine());
133        assertEquals("|*  --help (-?,-h)     *-*Displays the help                                   *|",
134                     reader.readLine());
135        assertEquals("|*  --diagnostics      *-*print information that might be helpful to diagnose *|",
136                     reader.readLine());
137        assertEquals("|*                     *-*or report problems.                                 *|",
138                     reader.readLine());
139        assertEquals("|*  --projecthelp      *-*print project help information                      *|",
140                     reader.readLine());
141        assertEquals("|*  --verbose          *-*print the version information and exit              *|",
142                     reader.readLine());
143        assertEquals("|*  target [target ...]*-*The targets ant should build                        *|",
144                     reader.readLine());
145        assertEquals("+------------------------------------------------------------------------------+",
146                     reader.readLine());
147        assertEquals("|*Copyright 2003                                                              *|",
148                     reader.readLine());
149        assertEquals("|*Apache Software Foundation                                                  *|",
150                     reader.readLine());
151        assertEquals("+------------------------------------------------------------------------------+",
152                     reader.readLine());
153        assertNull(reader.readLine());
154    }
155
156    public void testComparator()
157        throws IOException {
158        final StringWriter writer = new StringWriter();
159        final PrintWriter pw = new PrintWriter(writer);
160        helpFormatter.setPrintWriter(pw);
161
162        final Comparator comparator = new OptionComparator();
163        helpFormatter.setComparator(comparator);
164        helpFormatter.print();
165
166        // test comparator
167        assertEquals("invalid comparator", comparator, helpFormatter.getComparator());
168
169        final BufferedReader reader = new BufferedReader(new StringReader(writer.toString()));
170        assertEquals("+------------------------------------------------------------------------------+",
171                     reader.readLine());
172        assertEquals("|*Apache Commons CLI                                                          *|",
173                     reader.readLine());
174        assertEquals("+------------------------------------------------------------------------------+",
175                     reader.readLine());
176        assertEquals("|*Usage:                                                                      *|",
177                     reader.readLine());
178        assertEquals("|*ant [--verbose --projecthelp --help --diagnostics] [<target1> [<target2>    *|",
179                     reader.readLine());
180        assertEquals("|*...]]                                                                       *|",
181                     reader.readLine());
182        assertEquals("+------------------------------------------------------------------------------+",
183                     reader.readLine());
184        assertEquals("|*options              *-*                                                    *|",
185                     reader.readLine());
186        assertEquals("|*  --verbose          *-*print the version information and exit              *|",
187                     reader.readLine());
188        assertEquals("|*  --projecthelp      *-*print project help information                      *|",
189                     reader.readLine());
190        assertEquals("|*  --help (-?,-h)     *-*Displays the help                                   *|",
191                     reader.readLine());
192        assertEquals("|*  --diagnostics      *-*print information that might be helpful to diagnose *|",
193                     reader.readLine());
194        assertEquals("|*                     *-*or report problems.                                 *|",
195                     reader.readLine());
196        assertEquals("|*  target [target ...]*-*The targets ant should build                        *|",
197                     reader.readLine());
198        assertEquals("+------------------------------------------------------------------------------+",
199                     reader.readLine());
200        assertEquals("|*Copyright 2003                                                              *|",
201                     reader.readLine());
202        assertEquals("|*Apache Software Foundation                                                  *|",
203                     reader.readLine());
204        assertEquals("+------------------------------------------------------------------------------+",
205                     reader.readLine());
206        assertNull(reader.readLine());
207    }
208
209    public void testPrintHelp()
210        throws IOException {
211        final StringWriter writer = new StringWriter();
212        helpFormatter.setPrintWriter(new PrintWriter(writer));
213        helpFormatter.printHelp();
214
215        final BufferedReader reader = new BufferedReader(new StringReader(writer.toString()));
216        assertEquals("+------------------------------------------------------------------------------+",
217                     reader.readLine());
218        assertEquals("|*options              *-*                                                    *|",
219                     reader.readLine());
220        assertEquals("|*  --help (-?,-h)     *-*Displays the help                                   *|",
221                     reader.readLine());
222        assertEquals("|*  --diagnostics      *-*print information that might be helpful to diagnose *|",
223                     reader.readLine());
224        assertEquals("|*                     *-*or report problems.                                 *|",
225                     reader.readLine());
226        assertEquals("|*  --projecthelp      *-*print project help information                      *|",
227                     reader.readLine());
228        assertEquals("|*  --verbose          *-*print the version information and exit              *|",
229                     reader.readLine());
230        assertEquals("|*  target [target ...]*-*The targets ant should build                        *|",
231                     reader.readLine());
232        assertEquals("+------------------------------------------------------------------------------+",
233                     reader.readLine());
234        assertNull(reader.readLine());
235    }
236
237    public void testPrintHelp_WithException()
238        throws IOException {
239        final StringWriter writer = new StringWriter();
240        helpFormatter.setPrintWriter(new PrintWriter(writer));
241        helpFormatter.setException(new OptionException(verbose));
242        helpFormatter.printHelp();
243
244        //System.out.println(writer);
245        final BufferedReader reader = new BufferedReader(new StringReader(writer.toString()));
246        assertEquals("+------------------------------------------------------------------------------+",
247                     reader.readLine());
248        assertEquals("|*--verbose*-*print the version information and exit                          *|",
249                     reader.readLine());
250        assertEquals("+------------------------------------------------------------------------------+",
251                     reader.readLine());
252        assertNull(reader.readLine());
253    }
254
255    public void testPrintHelp_TooNarrow()
256        throws IOException {
257        final StringWriter writer = new StringWriter();
258        helpFormatter = new HelpFormatter("<", "=", ">", 4);
259        helpFormatter.setGroup(options);
260        helpFormatter.setPrintWriter(new PrintWriter(writer));
261        helpFormatter.printHelp();
262
263        final BufferedReader reader = new BufferedReader(new StringReader(writer.toString()));
264        assertEquals("<options              = >", reader.readLine());
265        assertEquals("<  --help (-?,-h)     =D>", reader.readLine());
266        assertEquals("<                     =i>", reader.readLine());
267
268        // lots more lines unchecked
269    }
270
271    public void testPrintException()
272        throws IOException {
273        final StringWriter writer = new StringWriter();
274        helpFormatter.setPrintWriter(new PrintWriter(writer));
275        helpFormatter.setException(new OptionException(verbose, ResourceConstants.MISSING_OPTION));
276        helpFormatter.printException();
277
278        //System.out.println(writer);
279        final BufferedReader reader = new BufferedReader(new StringReader(writer.toString()));
280        assertEquals("+------------------------------------------------------------------------------+",
281                     reader.readLine());
282        assertEquals("|*Missing option --verbose                                                    *|",
283                     reader.readLine());
284        assertNull(reader.readLine());
285    }
286
287    public void testPrintUsage()
288        throws IOException {
289        final StringWriter writer = new StringWriter();
290        helpFormatter.setPrintWriter(new PrintWriter(writer));
291        helpFormatter.printUsage();
292
293        final BufferedReader reader = new BufferedReader(new StringReader(writer.toString()));
294        assertEquals("+------------------------------------------------------------------------------+",
295                     reader.readLine());
296        assertEquals("|*Usage:                                                                      *|",
297                     reader.readLine());
298        assertEquals("|*ant [--help --diagnostics --projecthelp --verbose] [<target1> [<target2>    *|",
299                     reader.readLine());
300        assertEquals("|*...]]                                                                       *|",
301                     reader.readLine());
302        assertNull(reader.readLine());
303    }
304
305    public void testPrintHeader()
306        throws IOException {
307        final StringWriter writer = new StringWriter();
308        helpFormatter.setPrintWriter(new PrintWriter(writer));
309        helpFormatter.printHeader();
310
311        final BufferedReader reader = new BufferedReader(new StringReader(writer.toString()));
312        assertEquals("+------------------------------------------------------------------------------+",
313                     reader.readLine());
314        assertEquals("|*Apache Commons CLI                                                          *|",
315                     reader.readLine());
316        assertNull(reader.readLine());
317    }
318
319    public void testPrintFooter()
320        throws IOException {
321        final StringWriter writer = new StringWriter();
322        helpFormatter.setPrintWriter(new PrintWriter(writer));
323        helpFormatter.printFooter();
324
325        final BufferedReader reader = new BufferedReader(new StringReader(writer.toString()));
326        assertEquals("|*Copyright 2003                                                              *|",
327                     reader.readLine());
328        assertEquals("|*Apache Software Foundation                                                  *|",
329                     reader.readLine());
330        assertEquals("+------------------------------------------------------------------------------+",
331                     reader.readLine());
332        assertNull(reader.readLine());
333    }
334
335    public void testPrintDivider()
336        throws IOException {
337        final StringWriter writer = new StringWriter();
338        helpFormatter.setPrintWriter(new PrintWriter(writer));
339        helpFormatter.printDivider();
340
341        final BufferedReader reader = new BufferedReader(new StringReader(writer.toString()));
342        assertEquals("+------------------------------------------------------------------------------+",
343                     reader.readLine());
344        assertNull(reader.readLine());
345    }
346
347    public void testWrap() {
348        final Iterator i = HelpFormatter.wrap("Apache Software Foundation", 30).iterator();
349        assertEquals("Apache Software Foundation", i.next());
350        assertFalse(i.hasNext());
351    }
352
353    public void testWrap_WrapNeeded() {
354        final Iterator i = HelpFormatter.wrap("Apache Software Foundation", 20).iterator();
355        assertEquals("Apache Software", i.next());
356        assertEquals("Foundation", i.next());
357        assertFalse(i.hasNext());
358    }
359
360    public void testWrap_BeforeSpace() {
361        final Iterator i = HelpFormatter.wrap("Apache Software Foundation", 16).iterator();
362        assertEquals("Apache Software", i.next());
363        assertEquals("Foundation", i.next());
364        assertFalse(i.hasNext());
365    }
366
367    public void testWrap_AfterSpace() {
368        final Iterator i = HelpFormatter.wrap("Apache Software Foundation", 17).iterator();
369        assertEquals("Apache Software", i.next());
370        assertEquals("Foundation", i.next());
371        assertFalse(i.hasNext());
372    }
373
374    public void testWrap_InWord() {
375        final Iterator i = HelpFormatter.wrap("Apache Software Foundation", 8).iterator();
376        assertEquals("Apache", i.next());
377        assertEquals("Software", i.next());
378        assertEquals("Foundati", i.next());
379        assertEquals("on", i.next());
380        assertFalse(i.hasNext());
381    }
382
383    public void testWrap_NewLine() {
384        final Iterator i = HelpFormatter.wrap("\nApache Software Foundation\n", 30).iterator();
385        assertEquals("", i.next());
386        assertEquals("Apache Software Foundation", i.next());
387        assertEquals("", i.next());
388        assertFalse(i.hasNext());
389    }
390
391    public void testWrap_NewLine2() {
392        List wrapped =
393            HelpFormatter.wrap("A really quite long general description of the option with specific alternatives documented:\n" +
394                               "  Indented special case\n" + "  Alternative scenario", 30);
395
396        final Iterator i = wrapped.iterator();
397
398        assertEquals("A really quite long general", i.next());
399        assertEquals("description of the option", i.next());
400        assertEquals("with specific alternatives", i.next());
401        assertEquals("documented:", i.next());
402        assertEquals("  Indented special case", i.next());
403        assertEquals("  Alternative scenario", i.next());
404        assertFalse(i.hasNext());
405    }
406
407    public void testWrap_Below1Length() {
408        try {
409            HelpFormatter.wrap("Apache Software Foundation", -1);
410            fail("IllegalArgumentException");
411        } catch (IllegalArgumentException e) {
412            assertEquals(resources.getMessage(ResourceConstants.HELPFORMATTER_WIDTH_TOO_NARROW,
413                                              new Object[] { new Integer(-1) }), e.getMessage());
414        }
415    }
416
417    public void testPad()
418        throws IOException {
419        final StringWriter writer = new StringWriter();
420        HelpFormatter.pad("hello", 10, new PrintWriter(writer));
421        assertEquals("hello     ", writer.toString());
422    }
423
424    public void testPad_Null()
425        throws IOException {
426        final StringWriter writer = new StringWriter();
427        HelpFormatter.pad(null, 10, new PrintWriter(writer));
428        assertEquals("          ", writer.toString());
429    }
430
431    public void testPad_TooLong()
432        throws IOException {
433        final StringWriter writer = new StringWriter();
434        HelpFormatter.pad("hello world", 10, new PrintWriter(writer));
435        assertEquals("hello world", writer.toString());
436    }
437
438    public void testPad_TooShort()
439        throws IOException {
440        final StringWriter writer = new StringWriter();
441        HelpFormatter.pad("hello world", -5, new PrintWriter(writer));
442        assertEquals("hello world", writer.toString());
443    }
444
445    public void testGutters()
446        throws IOException {
447        helpFormatter = new HelpFormatter(null, null, null, 80);
448        helpFormatter.setShellCommand("ant");
449
450        final Set lusage = new HashSet();
451        lusage.add(DisplaySetting.DISPLAY_ALIASES);
452        lusage.add(DisplaySetting.DISPLAY_GROUP_NAME);
453        helpFormatter.setLineUsageSettings(lusage);
454
455        // test line usage
456        assertEquals("incorrect line usage", lusage, helpFormatter.getLineUsageSettings());
457
458        final Set fusage = new HashSet();
459        fusage.add(DisplaySetting.DISPLAY_PARENT_CHILDREN);
460        fusage.add(DisplaySetting.DISPLAY_GROUP_ARGUMENT);
461        fusage.add(DisplaySetting.DISPLAY_GROUP_OUTER);
462        fusage.add(DisplaySetting.DISPLAY_GROUP_EXPANDED);
463        fusage.add(DisplaySetting.DISPLAY_ARGUMENT_BRACKETED);
464        fusage.add(DisplaySetting.DISPLAY_ARGUMENT_NUMBERED);
465        fusage.add(DisplaySetting.DISPLAY_SWITCH_ENABLED);
466        fusage.add(DisplaySetting.DISPLAY_SWITCH_DISABLED);
467        fusage.add(DisplaySetting.DISPLAY_PROPERTY_OPTION);
468        fusage.add(DisplaySetting.DISPLAY_PARENT_CHILDREN);
469        fusage.add(DisplaySetting.DISPLAY_PARENT_ARGUMENT);
470        fusage.add(DisplaySetting.DISPLAY_OPTIONAL);
471        helpFormatter.setFullUsageSettings(fusage);
472
473        // test line usage
474        assertEquals("incorrect full usage", fusage, helpFormatter.getFullUsageSettings());
475
476        final Set dsettings = new HashSet();
477        dsettings.add(DisplaySetting.DISPLAY_GROUP_NAME);
478        dsettings.add(DisplaySetting.DISPLAY_GROUP_EXPANDED);
479        dsettings.add(DisplaySetting.DISPLAY_GROUP_ARGUMENT);
480
481        helpFormatter.setDisplaySettings(dsettings);
482
483        verbose =
484            new DefaultOptionBuilder().withLongName("verbose")
485                                      .withDescription("print the version information and exit")
486                                      .create();
487
488        options =
489            new GroupBuilder().withName("options").withOption(DefaultOptionTest.buildHelpOption())
490                              .withOption(ArgumentTest.buildTargetsArgument())
491                              .withOption(new DefaultOptionBuilder().withLongName("diagnostics")
492                                                                    .withDescription("print information that might be helpful to diagnose or report problems.")
493                                                                    .create())
494                              .withOption(new DefaultOptionBuilder().withLongName("projecthelp")
495                                                                    .withDescription("print project help information")
496                                                                    .create()).withOption(verbose)
497                              .create();
498
499        helpFormatter.setGroup(options);
500
501        // test default gutters
502        assertEquals("incorrect left gutter", HelpFormatter.DEFAULT_GUTTER_LEFT,
503                     helpFormatter.getGutterLeft());
504        assertEquals("incorrect right gutter", HelpFormatter.DEFAULT_GUTTER_RIGHT,
505                     helpFormatter.getGutterRight());
506        assertEquals("incorrect center gutter", HelpFormatter.DEFAULT_GUTTER_CENTER,
507                     helpFormatter.getGutterCenter());
508
509        final StringWriter writer = new StringWriter();
510        helpFormatter.setPrintWriter(new PrintWriter(writer));
511        helpFormatter.print();
512
513        final BufferedReader reader = new BufferedReader(new StringReader(writer.toString()));
514        assertEquals("Usage:                                                                          ",
515                     reader.readLine());
516        assertEquals("ant [--help --diagnostics --projecthelp --verbose] [<target1> [<target2> ...]]  ",
517                     reader.readLine());
518        assertEquals("options                                                                         ",
519                     reader.readLine());
520        assertEquals("  --help (-?,-h)         Displays the help                                      ",
521                     reader.readLine());
522        assertEquals("  --diagnostics          print information that might be helpful to diagnose or ",
523                     reader.readLine());
524        assertEquals("                         report problems.                                       ",
525                     reader.readLine());
526        assertEquals("  --projecthelp          print project help information                         ",
527                     reader.readLine());
528        assertEquals("  --verbose              print the version information and exit                 ",
529                     reader.readLine());
530        assertEquals("  target [target ...]    The targets ant should build                           ",
531                     reader.readLine());
532        assertNull(reader.readLine());
533    }
534}
535
536
537class OptionComparator implements Comparator {
538    public int compare(Object o1,
539                       Object o2) {
540        Option opt1 = (Option) o1;
541        Option opt2 = (Option) o2;
542
543        return -opt1.getPreferredName().compareTo(opt2.getPreferredName());
544    }
545}