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.HashSet;
020import java.util.Iterator;
021import java.util.List;
022import java.util.ListIterator;
023import java.util.Set;
024
025import org.apache.commons.cli2.Argument;
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.Parent;
032import org.apache.commons.cli2.WriteableCommandLine;
033import org.apache.commons.cli2.builder.ArgumentBuilder;
034import org.apache.commons.cli2.builder.CommandBuilder;
035import org.apache.commons.cli2.builder.DefaultOptionBuilder;
036import org.apache.commons.cli2.builder.GroupBuilder;
037import org.apache.commons.cli2.commandline.WriteableCommandLineImpl;
038import org.apache.commons.cli2.resource.ResourceConstants;
039import org.apache.commons.cli2.resource.ResourceHelper;
040
041/**
042 * @author Rob Oxspring
043 */
044public class ParentTest
045    extends ParentTestCase {
046    public static final Argument COMPLEX_ARGUMENT =
047        new ArgumentBuilder().withName("username").withMinimum(1).withMaximum(1).create();
048    public static final Option COMPLEX_CHILD_SSL =
049        new DefaultOptionBuilder().withLongName("ssl").withShortName("s").create();
050    public static final Option COMPLEX_CHILD_BASIC =
051        new DefaultOptionBuilder().withLongName("basic").withShortName("b").create();
052    public static final Option COMPLEX_CHILD_DIGEST =
053        new DefaultOptionBuilder().withLongName("digest").withShortName("d").create();
054    public static final Group COMPLEX_CHILDREN =
055        new GroupBuilder().withName("login-opts").withOption(COMPLEX_CHILD_BASIC)
056                          .withOption(COMPLEX_CHILD_DIGEST).withOption(COMPLEX_CHILD_SSL).create();
057
058    public static Parent buildLibParent() {
059        final Argument argument = ArgumentTest.buildPathArgument();
060
061        return new DefaultOption("-", "--", false, "--lib", "Specifies library search path", null,
062                                 null, false, argument, null, 'l');
063    }
064
065    public static Parent buildKParent() {
066        final Group children = GroupTest.buildApacheCommandGroup();
067
068        return new DefaultOption("-", "--", false, "-k", "desc", null, null, false, null, children,
069                                 'k');
070    }
071
072    public static Parent buildComplexParent() {
073        return new CommandBuilder().withName("login").withName("lo").withName("l")
074                                   .withArgument(COMPLEX_ARGUMENT).withChildren(COMPLEX_CHILDREN)
075                                   .create();
076    }
077
078    /* (non-Javadoc)
079     * @see org.apache.commons.cli2.ParentTestCase#testProcessParent()
080     */
081    public void testProcessParent()
082        throws OptionException {
083        final Parent option = buildKParent();
084        final List args = list("-k", "start");
085        final WriteableCommandLine commandLine = commandLine(option, args);
086        final ListIterator iterator = args.listIterator();
087        option.processParent(commandLine, iterator);
088
089        assertEquals("start", iterator.next());
090        assertFalse(iterator.hasNext());
091        assertTrue(commandLine.hasOption(option));
092        assertTrue(commandLine.hasOption("-k"));
093        assertTrue(commandLine.getValues(option).isEmpty());
094    }
095
096    /* (non-Javadoc)
097     * @see org.apache.commons.cli2.OptionTestCase#testCanProcess()
098     */
099    public void testCanProcess() {
100        final Parent option = buildKParent();
101        assertTrue(option.canProcess(new WriteableCommandLineImpl(option, null), "-k"));
102    }
103
104    public void testCanProcess_BadMatch() {
105        final Parent option = buildKParent();
106        assertFalse(option.canProcess(new WriteableCommandLineImpl(option, null), "-K"));
107    }
108
109    public void testCanProcess_ContractedArgument() {
110        final Parent option = buildLibParent();
111        assertTrue(option.canProcess(new WriteableCommandLineImpl(option, null), "--lib=/usr/lib"));
112    }
113
114    /* (non-Javadoc)
115     * @see org.apache.commons.cli2.OptionTestCase#testPrefixes()
116     */
117    public void testPrefixes() {
118        final Parent option = buildKParent();
119        assertContentsEqual(list("-", "--"), option.getPrefixes());
120    }
121
122    /* (non-Javadoc)
123     * @see org.apache.commons.cli2.OptionTestCase#testProcess()
124     */
125    public void testProcess()
126        throws OptionException {
127        final Parent option = CommandTest.buildStartCommand();
128        final List args = list("start");
129        final WriteableCommandLine commandLine = commandLine(option, args);
130        final ListIterator iterator = args.listIterator();
131        option.process(commandLine, iterator);
132
133        assertFalse(iterator.hasNext());
134        assertTrue(commandLine.hasOption(option));
135        assertTrue(commandLine.hasOption("start"));
136        assertFalse(commandLine.hasOption("stop"));
137        assertTrue(commandLine.getValues(option).isEmpty());
138    }
139
140    public void testProcess_NoMatch()
141        throws OptionException {
142        final Parent option = CommandTest.buildStartCommand();
143        final List args = list("whatever");
144        final WriteableCommandLine commandLine = commandLine(option, args);
145        final ListIterator iterator = args.listIterator();
146
147        try {
148            option.process(commandLine, iterator);
149            fail("unexpected token not thrown");
150        } catch (OptionException exp) {
151            OptionException e =
152                new OptionException(option, ResourceConstants.UNEXPECTED_TOKEN, "whatever");
153            assertEquals("wrong exception message", e.getMessage(), exp.getMessage());
154        }
155    }
156
157    public void testProcess_Children()
158        throws OptionException {
159        final Parent option = buildKParent();
160        final List args = list("-k", "start");
161        final WriteableCommandLine commandLine = commandLine(option, args);
162        final ListIterator iterator = args.listIterator();
163        option.process(commandLine, iterator);
164
165        assertNull(option.findOption("whatever"));
166        assertNotNull(option.findOption("start"));
167
168        assertFalse(iterator.hasNext());
169        assertTrue(commandLine.hasOption(option));
170        assertTrue(commandLine.hasOption("-k"));
171        assertTrue(commandLine.hasOption("start"));
172        assertFalse(commandLine.hasOption("stop"));
173        assertTrue(commandLine.getValues(option).isEmpty());
174    }
175
176    public void testProcess_Argument()
177        throws OptionException {
178        final Parent option = buildLibParent();
179        final List args = list("--lib=C:\\WINDOWS;C:\\WINNT;C:\\");
180        final WriteableCommandLine commandLine = commandLine(option, args);
181        final ListIterator iterator = args.listIterator();
182        option.process(commandLine, iterator);
183
184        assertFalse(iterator.hasNext());
185        assertTrue(commandLine.hasOption(option));
186        assertTrue(commandLine.hasOption("--lib"));
187        assertContentsEqual(list("C:\\WINDOWS", "C:\\WINNT", "C:\\"), commandLine.getValues(option));
188    }
189
190    /* (non-Javadoc)
191     * @see org.apache.commons.cli2.OptionTestCase#testTriggers()
192     */
193    public void testTriggers() {
194        final Parent option = buildKParent();
195        assertContentsEqual(list("-k"), option.getTriggers());
196    }
197
198    /* (non-Javadoc)
199     * @see org.apache.commons.cli2.OptionTestCase#testValidate()
200     */
201    public void testValidate()
202        throws OptionException {
203        final Parent option = CommandTest.buildStartCommand();
204        final WriteableCommandLine commandLine = commandLine(option, list());
205
206        option.validate(commandLine);
207
208        commandLine.addOption(option);
209
210        option.validate(commandLine);
211    }
212
213    public void testValidate_Children()
214        throws OptionException {
215        final Parent option = buildKParent();
216        final WriteableCommandLine commandLine = commandLine(option, list());
217
218        option.validate(commandLine);
219        commandLine.addOption(option);
220
221        try {
222            option.validate(commandLine);
223            fail("Missing a command");
224        } catch (OptionException moe) {
225            assertNotNull(moe.getOption());
226            assertNotSame(option, moe.getOption());
227        }
228    }
229
230    public void testValidate_Argument()
231        throws OptionException {
232        final Command option = CommandTest.buildLoginCommand();
233        final WriteableCommandLine commandLine = commandLine(option, list());
234
235        option.validate(commandLine);
236
237        commandLine.addOption(option);
238
239        try {
240            option.validate(commandLine);
241            fail("Missing a value");
242        } catch (OptionException moe) {
243            assertSame(option, moe.getOption());
244        }
245    }
246
247    /* (non-Javadoc)
248     * @see org.apache.commons.cli2.OptionTestCase#testAppendUsage()
249     */
250    public void testAppendUsage() {
251        final Option option = buildComplexParent();
252        final StringBuffer buffer = new StringBuffer();
253        final Set settings = new HashSet(DisplaySetting.ALL);
254        settings.remove(DisplaySetting.DISPLAY_GROUP_OUTER);
255        option.appendUsage(buffer, settings, null);
256
257        assertEquals("[login (l,lo) <username> [login-opts (--basic (-b)|--digest (-d)|--ssl (-s))]]",
258                     buffer.toString());
259    }
260
261    public void testAppendUsage_NoArguments() {
262        final Option option = buildComplexParent();
263        final StringBuffer buffer = new StringBuffer();
264        final Set settings = new HashSet(DisplaySetting.ALL);
265        settings.remove(DisplaySetting.DISPLAY_PARENT_ARGUMENT);
266        settings.remove(DisplaySetting.DISPLAY_GROUP_OUTER);
267        option.appendUsage(buffer, settings, null);
268
269        assertEquals("[login (l,lo) [login-opts (--basic (-b)|--digest (-d)|--ssl (-s))]]",
270                     buffer.toString());
271    }
272
273    public void testAppendUsage_NoChildren() {
274        final Option option = buildComplexParent();
275        final StringBuffer buffer = new StringBuffer();
276        final Set settings = new HashSet(DisplaySetting.ALL);
277        settings.remove(DisplaySetting.DISPLAY_PARENT_CHILDREN);
278        option.appendUsage(buffer, settings, null);
279
280        assertEquals("[login (l,lo) <username>]", buffer.toString());
281    }
282
283    public void testAppendUsage_NoArgumentsOrChildren() {
284        final Option option = buildComplexParent();
285        final StringBuffer buffer = new StringBuffer();
286        final Set settings = new HashSet(DisplaySetting.ALL);
287        settings.remove(DisplaySetting.DISPLAY_PARENT_CHILDREN);
288        settings.remove(DisplaySetting.DISPLAY_PARENT_ARGUMENT);
289        option.appendUsage(buffer, settings, null);
290
291        assertEquals("[login (l,lo)]", buffer.toString());
292    }
293
294    /* (non-Javadoc)
295     * @see org.apache.commons.cli2.OptionTestCase#testGetPreferredName()
296     */
297    public void testGetPreferredName() {
298        final Option option = buildLibParent();
299        assertEquals("--lib", option.getPreferredName());
300    }
301
302    /* (non-Javadoc)
303     * @see org.apache.commons.cli2.OptionTestCase#testGetDescription()
304     */
305    public void testGetDescription() {
306        final Option option = buildLibParent();
307        assertEquals("Specifies library search path", option.getDescription());
308    }
309
310    /* (non-Javadoc)
311     * @see org.apache.commons.cli2.OptionTestCase#testHelpLines()
312     */
313    public void testHelpLines() {
314        final Option option = buildComplexParent();
315        final List lines = option.helpLines(0, DisplaySetting.ALL, null);
316        final Iterator i = lines.iterator();
317
318        final HelpLine line1 = (HelpLine) i.next();
319        assertEquals(0, line1.getIndent());
320        assertEquals(option, line1.getOption());
321
322        final HelpLine line2 = (HelpLine) i.next();
323        assertEquals(1, line2.getIndent());
324        assertEquals(COMPLEX_ARGUMENT, line2.getOption());
325
326        final HelpLine line3 = (HelpLine) i.next();
327        assertEquals(1, line3.getIndent());
328        assertEquals(COMPLEX_CHILDREN, line3.getOption());
329
330        final HelpLine line4 = (HelpLine) i.next();
331        assertEquals(2, line4.getIndent());
332        assertEquals(COMPLEX_CHILD_BASIC, line4.getOption());
333
334        final HelpLine line5 = (HelpLine) i.next();
335        assertEquals(2, line5.getIndent());
336        assertEquals(COMPLEX_CHILD_DIGEST, line5.getOption());
337
338        final HelpLine line6 = (HelpLine) i.next();
339        assertEquals(2, line6.getIndent());
340        assertEquals(COMPLEX_CHILD_SSL, line6.getOption());
341
342        assertFalse(i.hasNext());
343    }
344
345    public void testHelpLines_NoArgument() {
346        final Option option = buildComplexParent();
347        final Set settings = new HashSet(DisplaySetting.ALL);
348        settings.remove(DisplaySetting.DISPLAY_PARENT_ARGUMENT);
349
350        final List lines = option.helpLines(0, settings, null);
351        final Iterator i = lines.iterator();
352
353        final HelpLine line1 = (HelpLine) i.next();
354        assertEquals(0, line1.getIndent());
355        assertEquals(option, line1.getOption());
356
357        final HelpLine line3 = (HelpLine) i.next();
358        assertEquals(1, line3.getIndent());
359        assertEquals(COMPLEX_CHILDREN, line3.getOption());
360
361        final HelpLine line4 = (HelpLine) i.next();
362        assertEquals(2, line4.getIndent());
363        assertEquals(COMPLEX_CHILD_BASIC, line4.getOption());
364
365        final HelpLine line5 = (HelpLine) i.next();
366        assertEquals(2, line5.getIndent());
367        assertEquals(COMPLEX_CHILD_DIGEST, line5.getOption());
368
369        final HelpLine line6 = (HelpLine) i.next();
370        assertEquals(2, line6.getIndent());
371        assertEquals(COMPLEX_CHILD_SSL, line6.getOption());
372
373        assertFalse(i.hasNext());
374    }
375
376    public void testHelpLines_NoChildren() {
377        final Option option = buildComplexParent();
378        final Set settings = new HashSet(DisplaySetting.ALL);
379        settings.remove(DisplaySetting.DISPLAY_PARENT_CHILDREN);
380
381        final List lines = option.helpLines(0, settings, null);
382        final Iterator i = lines.iterator();
383
384        final HelpLine line1 = (HelpLine) i.next();
385        assertEquals(0, line1.getIndent());
386        assertEquals(option, line1.getOption());
387
388        final HelpLine line2 = (HelpLine) i.next();
389        assertEquals(1, line2.getIndent());
390        assertEquals(COMPLEX_ARGUMENT, line2.getOption());
391
392        assertFalse(i.hasNext());
393    }
394
395    public void testNullPreferredName() {
396        try {
397                new CommandBuilder().create();
398        } catch (IllegalStateException exp) {
399                assertEquals(ResourceHelper.getResourceHelper().getMessage(ResourceConstants.OPTION_NO_NAME), exp.getMessage());
400        }
401    }
402
403    public void testRequired() {
404        Command cmd = new CommandBuilder().withRequired(true).withName("blah").create();
405        assertTrue("cmd is not required", cmd.isRequired());
406        assertEquals("id is incorrect", 0, cmd.getId());
407    }
408
409    public void testID() {
410        Command cmd = new CommandBuilder().withId('c').withName("blah").create();
411        assertEquals("id is incorrect", 'c', cmd.getId());
412    }
413
414    public void testGetId() {
415        assertEquals('h', DefaultOptionTest.buildHelpOption().getId());
416        assertEquals('X', DefaultOptionTest.buildXOption().getId());
417        assertEquals(0, CommandTest.buildStartCommand().getId());
418    }
419}