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.bug;
018
019import junit.framework.TestCase;
020
021import org.apache.commons.cli2.CommandLine;
022import org.apache.commons.cli2.Group;
023import org.apache.commons.cli2.Option;
024import org.apache.commons.cli2.OptionException;
025import org.apache.commons.cli2.builder.DefaultOptionBuilder;
026import org.apache.commons.cli2.builder.GroupBuilder;
027import org.apache.commons.cli2.commandline.Parser;
028
029/**
030 * Inconsistent handling of minimum and maximum constraints for groups and their
031 * child groups.
032 *
033 * @author Oliver Heger
034 * @version $Id: BugCLI159Test.java 680178 2008-07-27 20:32:14Z oheger $
035 */
036public class BugCLI159Test extends TestCase
037{
038    /** The parent group. */
039    private Group parent;
040
041    /** The child group. */
042    private Group child;
043
044    /** The parser. */
045    private Parser parser;
046
047    /**
048     * Creates some test options, including a group with a child group.
049     *
050     * @param childGroupRequired a flag whether the child group is required
051     */
052    private void setUpOptions(boolean childGroupRequired)
053    {
054        final DefaultOptionBuilder obuilder = new DefaultOptionBuilder();
055        final GroupBuilder gbuilder = new GroupBuilder();
056        Option parentOpt = obuilder.withLongName("parent").withShortName("p")
057                .create();
058        Option childOpt1 = obuilder.withLongName("child").withShortName("c")
059                .create();
060        Option childOpt2 = obuilder.withLongName("sub").withShortName("s")
061                .create();
062        Option childOpt3 = obuilder.withLongName("test").withShortName("t")
063                .create();
064        child = gbuilder.withName("childOptions").withOption(childOpt1)
065                .withOption(childOpt2).withOption(childOpt3).withMinimum(2)
066                .withRequired(childGroupRequired).create();
067        parent = gbuilder.withName("options").withOption(parentOpt).withOption(
068                child).withMinimum(0).create();
069        parser = new Parser();
070        parser.setGroup(parent);
071    }
072
073    /**
074     * Tests whether the child group can be omitted.
075     */
076    public void testNoChildGroup() throws OptionException
077    {
078        setUpOptions(false);
079        CommandLine cl = parser.parse(new String[] {
080            "--parent"
081        });
082        assertNotNull("No command line parsed", cl);
083        assertFalse("Child group found", cl.hasOption(child));
084    }
085
086    /**
087     * Tests whether a required child groupd can be omitted.
088     */
089    public void testNoChildGroupRequired()
090    {
091        setUpOptions(true);
092        try
093        {
094            parser.parse(new String[] {
095                "--parent"
096            });
097            fail("Missing child group not detected!");
098        }
099        catch (OptionException oex)
100        {
101            // ok
102        }
103    }
104
105    /**
106     * Tests parsing an empty command line. Because the parent group is optional
107     * this should be possible.
108     */
109    public void testNoOptions() throws OptionException
110    {
111        setUpOptions(false);
112        CommandLine cl = parser.parse(new String[0]);
113        assertFalse("Found parent option", cl.hasOption("--parent"));
114        assertFalse("Found child option", cl.hasOption("--child"));
115    }
116
117    /**
118     * Tests parsing a command line with options of the child group.
119     */
120    public void testWithChildOptions() throws OptionException
121    {
122        setUpOptions(false);
123        CommandLine cl = parser.parse(new String[] {
124            "-ct"
125        });
126        assertTrue("child option not found", cl.hasOption("--child"));
127        assertTrue("test option not found", cl.hasOption("--test"));
128    }
129
130    /**
131     * Tests a command line containing options of the child group, but the
132     * minimum constraint is violated.
133     */
134    public void testWithChildOptionsMissing()
135    {
136        setUpOptions(false);
137        try
138        {
139            parser.parse(new String[] {
140                    "--parent", "--sub"
141            });
142            fail("Missing options of child group not detected!");
143        }
144        catch (OptionException oex)
145        {
146            // ok
147        }
148    }
149
150    /**
151     * Tests whether the root group is always validated.
152     */
153    public void testRequiredRootGroup()
154    {
155        setUpOptions(false);
156        parser.setGroup(child);
157        try
158        {
159            parser.parse(new String[] {
160                "--test"
161            });
162            fail("Missing options not detected!");
163        }
164        catch (OptionException oex)
165        {
166            // ok
167        }
168    }
169}