001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *     http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.commons.cli2.option;
018
019import java.util.ArrayList;
020import java.util.HashSet;
021import java.util.Iterator;
022import java.util.List;
023import java.util.ListIterator;
024import java.util.Set;
025
026import org.apache.commons.cli2.DisplaySetting;
027import org.apache.commons.cli2.Group;
028import org.apache.commons.cli2.HelpLine;
029import org.apache.commons.cli2.Option;
030import org.apache.commons.cli2.OptionException;
031import org.apache.commons.cli2.WriteableCommandLine;
032import org.apache.commons.cli2.builder.DefaultOptionBuilder;
033import org.apache.commons.cli2.builder.GroupBuilder;
034import org.apache.commons.cli2.commandline.WriteableCommandLineImpl;
035
036/**
037 * @author Rob Oxspring
038 */
039public class GroupTest
040    extends GroupTestCase {
041    public static final Command COMMAND_START =
042        new Command("start", "Starts the server", null, false, null, null, 0);
043    public static final Command COMMAND_STOP =
044        new Command("stop", "Stops the server", null, false, null, null, 0);
045    public static final Command COMMAND_RESTART =
046        new Command("restart", "Stops and starts the server", null, false, null, null, 0);
047    public static final Command COMMAND_GRACEFUL =
048        new Command("graceful", "Restarts the server without interruption", null, false, null,
049                    null, 0);
050
051    public static Group buildApacheCommandGroup() {
052        final List options = new ArrayList();
053        options.add(COMMAND_GRACEFUL);
054        options.add(COMMAND_RESTART);
055        options.add(COMMAND_START);
056        options.add(COMMAND_STOP);
057
058        return new GroupImpl(options, "httpd-cmds", "The command to pass to the server", 1, 1, true);
059    }
060
061    public static Group buildApachectlGroup() {
062        final List options = new ArrayList();
063        options.add(DefaultOptionTest.buildHelpOption());
064        options.add(ParentTest.buildKParent());
065
066        return new GroupImpl(options, "apachectl", "Controls the apache http deamon", 0,
067                             Integer.MAX_VALUE, true);
068    }
069
070    public static Group buildAntGroup() {
071        final List options = new ArrayList();
072        options.add(DefaultOptionTest.buildHelpOption());
073        options.add(ArgumentTest.buildTargetsArgument());
074
075        return new GroupImpl(options, "ant", "The options for ant", 0, Integer.MAX_VALUE, true);
076    }
077
078    private static Group buildRequiredTestGroup(final boolean required,
079            final int minimum)
080    {
081        final Group group = new GroupImpl(new ArrayList(), "test", null,
082                minimum, Integer.MAX_VALUE, required);
083        final List options = new ArrayList(1);
084        options.add(group);
085        new GroupImpl(options, "parent", null, 0, Integer.MAX_VALUE, false);
086        return group;
087    }
088
089    /*
090     * (non-Javadoc)
091     *
092     * @see org.apache.commons.cli2.GroupTestCase#testProcessAnonymousArguments()
093     */
094    public void testProcessAnonymousArguments()
095        throws OptionException {
096        final Group option = buildAntGroup();
097        final List args = list("compile,test", "dist");
098        final ListIterator iterator = args.listIterator();
099        final WriteableCommandLine commandLine = commandLine(option, args);
100        option.process(commandLine, iterator);
101
102        assertFalse(iterator.hasNext());
103        assertTrue(commandLine.hasOption("target"));
104        assertListContentsEqual(commandLine.getValues("target"), args);
105        assertListContentsEqual(list("compile", "test", "dist"), args);
106    }
107
108    /*
109     * (non-Javadoc)
110     *
111     * @see org.apache.commons.cli2.GroupTestCase#testProcessOptions()
112     */
113    public void testProcessOptions()
114        throws OptionException {
115        final Group option = buildApachectlGroup();
116        final List args = list("-?", "-k");
117        final ListIterator iterator = args.listIterator();
118        final WriteableCommandLine commandLine = commandLine(option, args);
119        option.process(commandLine, iterator);
120
121        assertFalse(iterator.hasNext());
122        assertTrue(commandLine.hasOption("--help"));
123        assertTrue(commandLine.hasOption("-k"));
124        assertFalse(commandLine.hasOption("start"));
125        assertListContentsEqual(list("--help", "-k"), args);
126    }
127
128    /*
129     * (non-Javadoc)
130     *
131     * @see org.apache.commons.cli2.OptionTestCase#testCanProcess()
132     */
133    public void testCanProcess() {
134        final Group option = buildApacheCommandGroup();
135        assertTrue(option.canProcess(new WriteableCommandLineImpl(option, null), "start"));
136    }
137
138    public void testCanProcess_BadMatch() {
139        final Group option = buildApacheCommandGroup();
140        assertFalse(option.canProcess(new WriteableCommandLineImpl(option, null), "begin"));
141    }
142
143    public void testCanProcess_NullMatch() {
144        final Group option = buildApacheCommandGroup();
145        assertFalse(option.canProcess(new WriteableCommandLineImpl(option, null), (String) null));
146    }
147
148    /*
149     * (non-Javadoc)
150     *
151     * @see org.apache.commons.cli2.OptionTestCase#testPrefixes()
152     */
153    public void testPrefixes() {
154        final Group option = buildApachectlGroup();
155        assertContentsEqual(list("-", "--"), option.getPrefixes());
156    }
157
158    /*
159     * (non-Javadoc)
160     *
161     * @see org.apache.commons.cli2.OptionTestCase#testProcess()
162     */
163    public void testProcess()
164        throws OptionException {
165        final Group option = buildAntGroup();
166        final List args = list("--help", "compile,test", "dist");
167        final ListIterator iterator = args.listIterator();
168        final WriteableCommandLine commandLine = commandLine(option, args);
169        option.process(commandLine, iterator);
170
171        assertFalse(iterator.hasNext());
172        assertTrue(commandLine.hasOption("-?"));
173        assertListContentsEqual(list("compile", "test", "dist"), commandLine.getValues("target"));
174    }
175
176    public void testProcess_Nested()
177        throws OptionException {
178        final Group option = buildApachectlGroup();
179        final List args = list("-h", "-k", "graceful");
180        final ListIterator iterator = args.listIterator();
181        final WriteableCommandLine commandLine = commandLine(option, args);
182        option.process(commandLine, iterator);
183
184        assertFalse(iterator.hasNext());
185        assertTrue(commandLine.hasOption("-?"));
186        assertTrue(commandLine.hasOption("-k"));
187        assertTrue(commandLine.hasOption("graceful"));
188        assertFalse(commandLine.hasOption("stop"));
189        assertTrue(commandLine.getValues("start").isEmpty());
190        assertListContentsEqual(list("--help", "-k", "graceful"), args);
191    }
192
193    /*
194     * (non-Javadoc)
195     *
196     * @see org.apache.commons.cli2.OptionTestCase#testTriggers()
197     */
198    public void testTriggers() {
199        final Group option = buildApachectlGroup();
200        assertContentsEqual(list("--help", "-?", "-h", "-k"), option.getTriggers());
201    }
202
203    /*
204     * (non-Javadoc)
205     *
206     * @see org.apache.commons.cli2.OptionTestCase#testValidate()
207     */
208    public void testValidate()
209        throws OptionException {
210        final Group option = buildApacheCommandGroup();
211        final WriteableCommandLine commandLine = commandLine(option, list());
212
213        commandLine.addOption(COMMAND_RESTART);
214
215        option.validate(commandLine);
216    }
217
218    public void testValidate_UnexpectedOption() {
219        final Group option = buildApacheCommandGroup();
220        final WriteableCommandLine commandLine = commandLine(option, list());
221
222        commandLine.addOption(COMMAND_RESTART);
223        commandLine.addOption(COMMAND_GRACEFUL);
224
225        try {
226            option.validate(commandLine);
227            fail("Too many options");
228        } catch (OptionException uoe) {
229            assertEquals(option, uoe.getOption());
230        }
231    }
232
233    public void testValidate_MissingOption() {
234        final Group option = buildApacheCommandGroup();
235        final WriteableCommandLine commandLine = commandLine(option, list());
236
237        try {
238            option.validate(commandLine);
239            fail("Missing an option");
240        } catch (OptionException moe) {
241            assertEquals(option, moe.getOption());
242        }
243    }
244
245    public void testValidate_RequiredChild()
246        throws OptionException {
247        final Option required =
248            new DefaultOptionBuilder().withLongName("required").withRequired(true).create();
249        final Option optional =
250            new DefaultOptionBuilder().withLongName("optional").withRequired(false).create();
251        final Group group =
252            new GroupBuilder().withOption(required).withOption(optional).withMinimum(1).create();
253
254        WriteableCommandLine commandLine;
255
256        commandLine = commandLine(group, list());
257
258        try {
259            group.validate(commandLine);
260            fail("Missing option 'required'");
261        } catch (OptionException moe) {
262            assertEquals(required, moe.getOption());
263        }
264
265        commandLine = commandLine(group, list());
266        commandLine.addOption(optional);
267
268        try {
269            group.validate(commandLine);
270            fail("Missing option 'required'");
271        } catch (OptionException moe) {
272            assertEquals(required, moe.getOption());
273        }
274
275        commandLine = commandLine(group, list());
276        commandLine.addOption(required);
277        group.validate(commandLine);
278    }
279
280    /*
281     * (non-Javadoc)
282     *
283     * @see org.apache.commons.cli2.OptionTestCase#testAppendUsage()
284     */
285    public void testAppendUsage() {
286        final Option option = buildApacheCommandGroup();
287        final StringBuffer buffer = new StringBuffer();
288        final Set settings = new HashSet(DisplaySetting.ALL);
289
290        //settings.remove(DisplaySetting.DISPLAY_ARGUMENT_NUMBERED);
291        option.appendUsage(buffer, settings, null);
292
293        assertEquals("httpd-cmds (graceful|restart|start|stop)", buffer.toString());
294    }
295
296    public void testAppendUsage_NoOptional() {
297        final Option option = buildApacheCommandGroup();
298        final StringBuffer buffer = new StringBuffer();
299        final Set settings = new HashSet(DisplaySetting.ALL);
300        settings.remove(DisplaySetting.DISPLAY_OPTIONAL);
301        option.appendUsage(buffer, settings, null);
302
303        assertEquals("httpd-cmds (graceful|restart|start|stop)", buffer.toString());
304    }
305
306    public void testAppendUsage_NoExpand() {
307        final Option option = buildApacheCommandGroup();
308        final StringBuffer buffer = new StringBuffer();
309        final Set settings = new HashSet(DisplaySetting.ALL);
310        settings.remove(DisplaySetting.DISPLAY_GROUP_EXPANDED);
311        option.appendUsage(buffer, settings, null);
312
313        assertEquals("httpd-cmds", buffer.toString());
314    }
315
316    public void testAppendUsage_NoExpandOrName() {
317        final Option option = buildApacheCommandGroup();
318        final StringBuffer buffer = new StringBuffer();
319        final Set settings = new HashSet(DisplaySetting.ALL);
320        settings.remove(DisplaySetting.DISPLAY_GROUP_EXPANDED);
321        settings.remove(DisplaySetting.DISPLAY_GROUP_NAME);
322        option.appendUsage(buffer, settings, null);
323
324        assertEquals("httpd-cmds", buffer.toString());
325    }
326
327    public void testAppendUsage_NoName() {
328        final Option option = buildApacheCommandGroup();
329        final StringBuffer buffer = new StringBuffer();
330        final Set settings = new HashSet(DisplaySetting.ALL);
331        settings.remove(DisplaySetting.DISPLAY_GROUP_NAME);
332        option.appendUsage(buffer, settings, null);
333
334        assertEquals("graceful|restart|start|stop", buffer.toString());
335    }
336
337    public void testAppendUsage_WithArgs() {
338        final Option option = buildAntGroup();
339        final StringBuffer buffer = new StringBuffer();
340        final Set settings = new HashSet(DisplaySetting.ALL);
341        settings.remove(DisplaySetting.DISPLAY_GROUP_OUTER);
342        option.appendUsage(buffer, settings, null);
343
344        assertEquals("[ant (--help (-?,-h)) [<target1> [<target2> ...]]]", buffer.toString());
345    }
346
347    public void testAppendUsage_OptionalChildGroup() {
348        final Option option = buildRequiredTestGroup(false, 2).getParent();
349        final StringBuffer buffer = new StringBuffer();
350        final Set settings = new HashSet(DisplaySetting.ALL);
351        option.appendUsage(buffer, settings, null);
352
353        assertEquals("[parent ([test ()])]", buffer.toString());
354    }
355
356    public void testAppendUsage_OptionalChildGroupNoSetting() {
357        final Option option = buildRequiredTestGroup(false, 2).getParent();
358        final StringBuffer buffer = new StringBuffer();
359        final Set settings = new HashSet(DisplaySetting.ALL);
360        settings.remove(DisplaySetting.DISPLAY_OPTIONAL_CHILD_GROUP);
361        option.appendUsage(buffer, settings, null);
362
363        assertEquals("[parent (test ())]", buffer.toString());
364    }
365
366    public void testAppendUsage_RequiredChildGroup() {
367        final Option option = buildRequiredTestGroup(true, 2).getParent();
368        final StringBuffer buffer = new StringBuffer();
369        final Set settings = new HashSet(DisplaySetting.ALL);
370        option.appendUsage(buffer, settings, null);
371
372        assertEquals("[parent (test ())]", buffer.toString());
373    }
374
375    /*
376     * (non-Javadoc)
377     *
378     * @see org.apache.commons.cli2.OptionTestCase#testGetPreferredName()
379     */
380    public void testGetPreferredName() {
381        final Option option = buildAntGroup();
382        assertEquals("ant", option.getPreferredName());
383    }
384
385    /*
386     * (non-Javadoc)
387     *
388     * @see org.apache.commons.cli2.OptionTestCase#testGetDescription()
389     */
390    public void testGetDescription() {
391        final Option option = buildApachectlGroup();
392        assertEquals("Controls the apache http deamon", option.getDescription());
393    }
394
395    /*
396     * (non-Javadoc)
397     *
398     * @see org.apache.commons.cli2.OptionTestCase#testHelpLines()
399     */
400    public void testHelpLines() {
401        final Option option = buildApacheCommandGroup();
402        final List lines = option.helpLines(0, DisplaySetting.ALL, null);
403        final Iterator i = lines.iterator();
404
405        final HelpLine line1 = (HelpLine) i.next();
406        assertEquals(0, line1.getIndent());
407        assertEquals(option, line1.getOption());
408
409        final HelpLine line2 = (HelpLine) i.next();
410        assertEquals(1, line2.getIndent());
411        assertEquals(COMMAND_GRACEFUL, line2.getOption());
412
413        final HelpLine line3 = (HelpLine) i.next();
414        assertEquals(1, line3.getIndent());
415        assertEquals(COMMAND_RESTART, line3.getOption());
416
417        final HelpLine line4 = (HelpLine) i.next();
418        assertEquals(1, line4.getIndent());
419        assertEquals(COMMAND_START, line4.getOption());
420
421        final HelpLine line5 = (HelpLine) i.next();
422        assertEquals(1, line5.getIndent());
423        assertEquals(COMMAND_STOP, line5.getOption());
424
425        assertFalse(i.hasNext());
426    }
427
428    /*
429     * (non-Javadoc)
430     *
431     * @see org.apache.commons.cli2.OptionTestCase#testHelpLines()
432     */
433    public void testHelpLines_NoExpanded() {
434        final Option option = buildApacheCommandGroup();
435        final Set settings = new HashSet(DisplaySetting.ALL);
436        settings.remove(DisplaySetting.DISPLAY_GROUP_EXPANDED);
437
438        final List lines = option.helpLines(0, settings, null);
439        final Iterator i = lines.iterator();
440
441        final HelpLine line1 = (HelpLine) i.next();
442        assertEquals(0, line1.getIndent());
443        assertEquals(option, line1.getOption());
444
445        assertFalse(i.hasNext());
446    }
447
448    /*
449     * (non-Javadoc)
450     *
451     * @see org.apache.commons.cli2.OptionTestCase#testHelpLines()
452     */
453    public void testHelpLines_NoName() {
454        final Option option = buildApacheCommandGroup();
455        final Set settings = new HashSet(DisplaySetting.ALL);
456        settings.remove(DisplaySetting.DISPLAY_GROUP_NAME);
457
458        final List lines = option.helpLines(0, settings, null);
459        final Iterator i = lines.iterator();
460
461        final HelpLine line2 = (HelpLine) i.next();
462        assertEquals(1, line2.getIndent());
463        assertEquals(COMMAND_GRACEFUL, line2.getOption());
464
465        final HelpLine line3 = (HelpLine) i.next();
466        assertEquals(1, line3.getIndent());
467        assertEquals(COMMAND_RESTART, line3.getOption());
468
469        final HelpLine line4 = (HelpLine) i.next();
470        assertEquals(1, line4.getIndent());
471        assertEquals(COMMAND_START, line4.getOption());
472
473        final HelpLine line5 = (HelpLine) i.next();
474        assertEquals(1, line5.getIndent());
475        assertEquals(COMMAND_STOP, line5.getOption());
476
477        assertFalse(i.hasNext());
478    }
479
480    /**
481     * Tests isRequired() for a child group if neither the required flag nor a
482     * minimum constraint is set.
483     */
484    public void testIsRequired_ChildNoFlagNoMinimum()
485    {
486        final Group group = buildRequiredTestGroup(false, 0);
487        assertFalse("Group is required", group.isRequired());
488    }
489
490    /**
491     * Tests isRequired() for a child group that has a minimum constraint, but
492     * the required flag is not set.
493     */
494    public void testIsRequired_ChildNoFlagMinimum()
495    {
496        final Group group = buildRequiredTestGroup(false, 10);
497        assertFalse("Group is required", group.isRequired());
498    }
499
500    /**
501     * Tests isRequired() for a child group that has the required flag set, but
502     * no minimum constraint. In this constellation the group is de facto not
503     * required.
504     */
505    public void testIsRequired_ChildFlagNoMinimum()
506    {
507        final Group group = buildRequiredTestGroup(true, 0);
508        assertFalse("Group is required", group.isRequired());
509    }
510
511    /**
512     * Tests isRequired() for a child group that has both the required flag and
513     * a minimum constraint set. This is indeed a required group.
514     */
515    public void testIsRequired_ChildFlagMinimum()
516    {
517        final Group group = buildRequiredTestGroup(true, 10);
518        assertTrue("Group is not required", group.isRequired());
519    }
520
521    /**
522     * Tests isRequired() for the root group when no minimum constraint is set.
523     */
524    public void testIsRequired_ParentNoMinimum()
525    {
526        final Group parent = (Group) buildRequiredTestGroup(false, 0)
527                .getParent();
528        assertFalse("Group is required", parent.isRequired());
529    }
530
531    /**
532     * Tests isRequired() for the root group with a minimum constraint.
533     */
534    public void testIsRequired_ParentMiminum()
535    {
536        final Group parent = new GroupImpl(new ArrayList(), "test", null, 10,
537                Integer.MAX_VALUE, false);
538        assertTrue("Group not required", parent.isRequired());
539    }
540}