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