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         https://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.jupiter.api.Assertions.assertArrayEquals;
21  import static org.junit.jupiter.api.Assertions.assertEquals;
22  import static org.junit.jupiter.api.Assertions.assertFalse;
23  import static org.junit.jupiter.api.Assertions.assertNotNull;
24  import static org.junit.jupiter.api.Assertions.assertThrows;
25  import static org.junit.jupiter.api.Assertions.assertTrue;
26  
27  import java.util.ArrayList;
28  import java.util.Arrays;
29  import java.util.Collection;
30  import java.util.HashSet;
31  import java.util.List;
32  import java.util.Set;
33  
34  import org.junit.jupiter.api.Test;
35  
36  @SuppressWarnings("deprecation") // tests some deprecated classes
37  class OptionsTest {
38  
39      private void assertToStrings(final Option option) {
40          // Should never throw.
41          // Should return a String, not null.
42          assertNotNull(option.toString());
43          assertNotNull(option.toDeprecatedString());
44      }
45  
46      @Test
47      void testAddConflictingOptions() {
48          final Options options1 = new Options();
49          final OptionGroup optionGroup1 = new OptionGroup();
50          optionGroup1.addOption(Option.builder("a").get());
51          optionGroup1.addOption(Option.builder("b").get());
52          options1.addOptionGroup(optionGroup1);
53          options1.addOption(Option.builder("x").get());
54          options1.addOption(Option.builder("y").get());
55          final Options options2 = new Options();
56          final OptionGroup optionGroup2 = new OptionGroup();
57          optionGroup2.addOption(Option.builder("x").type(Integer.class).get());
58          optionGroup2.addOption(Option.builder("b").type(Integer.class).get());
59          options2.addOptionGroup(optionGroup2);
60          options2.addOption(Option.builder("c").get());
61          assertThrows(IllegalArgumentException.class, () -> options1.addOptions(options2));
62      }
63  
64      @Test
65      void testAddNonConflictingOptions() {
66          final Options options1 = new Options();
67          final OptionGroup optionGroup1 = new OptionGroup();
68          optionGroup1.addOption(Option.builder("a").get());
69          optionGroup1.addOption(Option.builder("b").get());
70          options1.addOptionGroup(optionGroup1);
71          options1.addOption(Option.builder("x").get());
72          options1.addOption(Option.builder("y").get());
73  
74          final Options options2 = new Options();
75          final OptionGroup group2 = new OptionGroup();
76          group2.addOption(Option.builder("c").type(Integer.class).get());
77          group2.addOption(Option.builder("d").type(Integer.class).get());
78          options2.addOptionGroup(group2);
79          options1.addOption(Option.builder("e").get());
80          options1.addOption(Option.builder("f").get());
81  
82          final Options underTest = new Options();
83          underTest.addOptions(options1);
84          underTest.addOptions(options2);
85  
86          final List<OptionGroup> expected = Arrays.asList(optionGroup1, group2);
87          assertTrue(expected.size() == underTest.getOptionGroups().size() && expected.containsAll(underTest.getOptionGroups()));
88          final Set<Option> expectOpt = new HashSet<>(options1.getOptions());
89          expectOpt.addAll(options2.getOptions());
90          assertEquals(8, expectOpt.size());
91          assertTrue(expectOpt.size() == underTest.getOptions().size() && expectOpt.containsAll(underTest.getOptions()));
92      }
93  
94      @Test
95      void testAddOptions() {
96          final Options options = new Options();
97  
98          final OptionGroup optionGroup1 = new OptionGroup();
99          optionGroup1.addOption(Option.builder("a").get());
100         optionGroup1.addOption(Option.builder("b").get());
101 
102         options.addOptionGroup(optionGroup1);
103 
104         options.addOption(Option.builder("X").get());
105         options.addOption(Option.builder("y").get());
106 
107         final Options underTest = new Options();
108         underTest.addOptions(options);
109 
110         assertEquals(options.getOptionGroups(), underTest.getOptionGroups());
111         assertArrayEquals(options.getOptions().toArray(), underTest.getOptions().toArray());
112     }
113 
114     @Test
115     void testAddOptions2X() {
116         final Options options = new Options();
117 
118         final OptionGroup optionGroup1 = new OptionGroup();
119         optionGroup1.addOption(Option.builder("a").get());
120         optionGroup1.addOption(Option.builder("b").get());
121 
122         options.addOptionGroup(optionGroup1);
123 
124         options.addOption(Option.builder("X").get());
125         options.addOption(Option.builder("y").get());
126 
127         assertThrows(IllegalArgumentException.class, () -> options.addOptions(options));
128     }
129 
130     @Test
131     void testDeprecated() {
132         final Options options = new Options();
133         options.addOption(Option.builder().option("a").get());
134         options.addOption(Option.builder().option("b").deprecated().get());
135         options.addOption(Option.builder().option("c")
136         .deprecated(DeprecatedAttributes.builder().setForRemoval(true).setSince("2.0").setDescription("Use X.").get()).get());
137         options.addOption(Option.builder().option("d").deprecated().longOpt("longD").hasArgs().get());
138         // toString()
139         assertTrue(options.getOption("a").toString().startsWith("[ Option a"));
140         assertTrue(options.getOption("b").toString().startsWith("[ Option b"));
141         assertTrue(options.getOption("c").toString().startsWith("[ Option c"));
142         // toDeprecatedString()
143         assertFalse(options.getOption("a").toDeprecatedString().startsWith("Option a"));
144         assertEquals("Option 'b': Deprecated", options.getOption("b").toDeprecatedString());
145         assertEquals("Option 'c': Deprecated for removal since 2.0: Use X.", options.getOption("c").toDeprecatedString());
146         assertToStrings(options.getOption("a"));
147         assertToStrings(options.getOption("b"));
148         assertToStrings(options.getOption("c"));
149         assertToStrings(options.getOption("d"));
150     }
151 
152     @Test
153     void testDuplicateLong() {
154         final Options options = new Options();
155         options.addOption("a", "--a", false, "toggle -a");
156         options.addOption("a", "--a", false, "toggle -a*");
157         assertEquals("toggle -a*", options.getOption("a").getDescription(), "last one in wins");
158         assertToStrings(options.getOption("a"));
159     }
160 
161     @Test
162     void testDuplicateSimple() {
163         final Options options = new Options();
164         options.addOption("a", false, "toggle -a");
165         assertToStrings(options.getOption("a"));
166         options.addOption("a", true, "toggle -a*");
167         assertEquals("toggle -a*", options.getOption("a").getDescription(), "last one in wins");
168         assertToStrings(options.getOption("a"));
169     }
170 
171     @Test
172     void testGetMatchingOpts() {
173         final Options options = new Options();
174         OptionBuilder.withLongOpt("version");
175         options.addOption(OptionBuilder.create());
176         OptionBuilder.withLongOpt("verbose");
177         options.addOption(OptionBuilder.create());
178         assertTrue(options.getMatchingOptions("foo").isEmpty());
179         assertEquals(1, options.getMatchingOptions("version").size());
180         assertEquals(2, options.getMatchingOptions("ver").size());
181         assertToStrings(options.getOption("version"));
182         assertToStrings(options.getOption("verbose"));
183     }
184 
185     @Test
186     void testGetOptionsGroups() {
187         final Options options = new Options();
188 
189         final OptionGroup optionGroup1 = new OptionGroup();
190         optionGroup1.addOption(OptionBuilder.create('a'));
191         optionGroup1.addOption(OptionBuilder.create('b'));
192 
193         final OptionGroup optionGroup2 = new OptionGroup();
194         optionGroup2.addOption(OptionBuilder.create('x'));
195         optionGroup2.addOption(OptionBuilder.create('y'));
196 
197         options.addOptionGroup(optionGroup1);
198         options.addOptionGroup(optionGroup2);
199 
200         assertNotNull(options.getOptionGroups());
201         assertEquals(2, options.getOptionGroups().size());
202     }
203 
204     @Test
205     void testHelpOptions() {
206         OptionBuilder.withLongOpt("long-only1");
207         final Option longOnly1 = OptionBuilder.create();
208         OptionBuilder.withLongOpt("long-only2");
209         final Option longOnly2 = OptionBuilder.create();
210         final Option shortOnly1 = OptionBuilder.create("1");
211         final Option shortOnly2 = OptionBuilder.create("2");
212         OptionBuilder.withLongOpt("bothA");
213         final Option bothA = OptionBuilder.create("a");
214         OptionBuilder.withLongOpt("bothB");
215         final Option bothB = OptionBuilder.create("b");
216 
217         final Options options = new Options();
218         options.addOption(longOnly1);
219         options.addOption(longOnly2);
220         options.addOption(shortOnly1);
221         options.addOption(shortOnly2);
222         options.addOption(bothA);
223         options.addOption(bothB);
224 
225         final Collection<Option> allOptions = new ArrayList<>();
226         allOptions.add(longOnly1);
227         allOptions.add(longOnly2);
228         allOptions.add(shortOnly1);
229         allOptions.add(shortOnly2);
230         allOptions.add(bothA);
231         allOptions.add(bothB);
232 
233         final Collection<Option> helpOptions = options.helpOptions();
234 
235         assertTrue(helpOptions.containsAll(allOptions), "Everything in all should be in help");
236         assertTrue(allOptions.containsAll(helpOptions), "Everything in help should be in all");
237     }
238 
239     @Test
240     void testLong() {
241         final Options options = new Options();
242         options.addOption("a", "--a", false, "toggle -a");
243         options.addOption("b", "--b", true, "set -b");
244         assertTrue(options.hasOption("a"));
245         assertTrue(options.hasOption("b"));
246     }
247 
248     @Test
249     void testMissingOptionException() throws ParseException {
250         final Options options = new Options();
251         OptionBuilder.isRequired();
252         options.addOption(OptionBuilder.create("f"));
253         final MissingOptionException e = assertThrows(MissingOptionException.class, () -> new PosixParser().parse(options, new String[0]));
254         assertEquals("Missing required option: f", e.getMessage());
255     }
256 
257     @Test
258     void testMissingOptionsException() throws ParseException {
259         final Options options = new Options();
260         OptionBuilder.isRequired();
261         options.addOption(OptionBuilder.create("f"));
262         OptionBuilder.isRequired();
263         options.addOption(OptionBuilder.create("x"));
264         final MissingOptionException e = assertThrows(MissingOptionException.class, () -> new PosixParser().parse(options, new String[0]));
265         assertEquals("Missing required options: f, x", e.getMessage());
266     }
267 
268     @Test
269     void testRequiredOptionInGroupShouldNotBeInRequiredList() {
270         final String key = "a";
271         final Option option = new Option(key, "along", false, "Option A");
272         option.setRequired(true);
273         final Options options = new Options();
274         options.addOption(option);
275         assertTrue(options.getRequiredOptions().contains(key));
276         final OptionGroup optionGroup = new OptionGroup();
277         optionGroup.addOption(option);
278         options.addOptionGroup(optionGroup);
279         assertFalse(options.getOption(key).isRequired());
280         assertFalse(options.getRequiredOptions().contains(key), "Option in group shouldn't be in required options list.");
281     }
282 
283     @Test
284     void testSimple() {
285         final Options options = new Options();
286         options.addOption("a", false, "toggle -a");
287         options.addOption("b", true, "toggle -b");
288         assertTrue(options.hasOption("a"));
289         assertTrue(options.hasOption("b"));
290     }
291 
292     @Test
293     void testToString() {
294         final Options options = new Options();
295         options.addOption("f", "foo", true, "Foo");
296         options.addOption("b", "bar", false, "Bar");
297         final String s = options.toString();
298         assertNotNull(s, "null string returned");
299         assertTrue(s.toLowerCase().contains("foo"), "foo option missing");
300         assertTrue(s.toLowerCase().contains("bar"), "bar option missing");
301     }
302 }