source: josm/trunk/test/unit/org/openstreetmap/josm/tools/OptionParserTest.java@ 17360

Last change on this file since 17360 was 17275, checked in by Don-vip, 3 years ago

see #16567 - upgrade almost all tests to JUnit 5, except those depending on WiremockRule

See https://github.com/tomakehurst/wiremock/issues/684

File size: 17.2 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.tools;
3
4import static org.junit.jupiter.api.Assertions.assertEquals;
5import static org.junit.jupiter.api.Assertions.assertFalse;
6import static org.junit.jupiter.api.Assertions.assertTrue;
7import static org.junit.jupiter.api.Assertions.assertThrows;
8
9import java.util.ArrayList;
10import java.util.Arrays;
11import java.util.List;
12import java.util.concurrent.atomic.AtomicBoolean;
13import java.util.concurrent.atomic.AtomicReference;
14
15import org.junit.jupiter.api.extension.RegisterExtension;
16import org.junit.jupiter.api.Test;
17import org.openstreetmap.josm.testutils.JOSMTestRules;
18import org.openstreetmap.josm.tools.OptionParser.OptionCount;
19import org.openstreetmap.josm.tools.OptionParser.OptionParseException;
20
21import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
22
23/**
24 * Test for {@link OptionParser}
25 * @author Michael Zangl
26 */
27class OptionParserTest {
28 /**
29 * Setup test.
30 */
31 @RegisterExtension
32 @SuppressFBWarnings(value = "URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD")
33 public JOSMTestRules test = new JOSMTestRules().i18n();
34
35 // A reason for moving to jupiter...
36 @Test
37 void testEmptyParserRejectsLongopt() {
38 Exception e = assertThrows(OptionParseException.class, () ->
39 new OptionParser("test").parseOptions(Arrays.asList("--long")));
40 assertEquals("test: unrecognized option '--long'", e.getMessage());
41 }
42
43 @Test
44 void testEmptyParserRejectsShortopt() {
45 Exception e = assertThrows(OptionParseException.class, () ->
46 new OptionParser("test").parseOptions(Arrays.asList("-s")));
47 assertEquals("test: unrecognized option '-s'", e.getMessage());
48 }
49
50 @Test
51 void testParserRejectsWrongShortopt() {
52 Exception e = assertThrows(OptionParseException.class, () ->
53 new OptionParser("test").addFlagParameter("test", this::nop).addShortAlias("test", "t")
54 .parseOptions(Arrays.asList("-s")));
55 assertEquals("test: unrecognized option '-s'", e.getMessage());
56 }
57
58 @Test
59 void testParserRejectsWrongLongopt() {
60 Exception e = assertThrows(OptionParseException.class, () ->
61 new OptionParser("test").addFlagParameter("test", this::nop).parseOptions(Arrays.asList("--wrong")));
62 assertEquals("test: unrecognized option '--wrong'", e.getMessage());
63 }
64
65 @Test
66 void testParserOption() {
67 AtomicReference<String> argFound = new AtomicReference<>();
68 OptionParser parser = new OptionParser("test")
69 .addArgumentParameter("test", OptionCount.REQUIRED, argFound::set);
70
71 parser.parseOptions(Arrays.asList("--test", "arg"));
72 assertEquals("arg", argFound.get());
73 }
74
75 @Test
76 void testParserOptionFailsIfMissing() {
77 AtomicReference<String> argFound = new AtomicReference<>();
78 OptionParser parser = new OptionParser("test")
79 .addArgumentParameter("test", OptionCount.REQUIRED, argFound::set);
80
81 Exception e = assertThrows(OptionParseException.class, () -> parser.parseOptions(Arrays.asList("--test2", "arg")));
82 assertEquals("test: unrecognized option '--test2'", e.getMessage());
83 }
84
85 @Test
86 void testParserOptionFailsIfMissingArgument() {
87 AtomicReference<String> argFound = new AtomicReference<>();
88 OptionParser parser = new OptionParser("test")
89 .addArgumentParameter("test", OptionCount.REQUIRED, argFound::set);
90
91 Exception e = assertThrows(OptionParseException.class, () -> parser.parseOptions(Arrays.asList("--test2", "--other")));
92 assertEquals("test: unrecognized option '--test2'", e.getMessage());
93 }
94
95 @Test
96 void testParserOptionFailsIfMissing2() {
97 AtomicReference<String> argFound = new AtomicReference<>();
98 OptionParser parser = new OptionParser("test")
99 .addArgumentParameter("test", OptionCount.REQUIRED, argFound::set);
100
101 Exception e = assertThrows(OptionParseException.class, () -> parser.parseOptions(Arrays.asList("--", "--test", "arg")));
102 assertEquals("test: option '--test' is required", e.getMessage());
103 }
104
105 @Test
106 void testParserOptionFailsIfTwice() {
107 AtomicReference<String> argFound = new AtomicReference<>();
108 OptionParser parser = new OptionParser("test")
109 .addArgumentParameter("test", OptionCount.REQUIRED, argFound::set);
110
111 Exception e = assertThrows(OptionParseException.class, () -> parser.parseOptions(Arrays.asList("--test", "arg", "--test", "arg")));
112 assertEquals("test: option '--test' may not appear multiple times", e.getMessage());
113 }
114
115 @Test
116 void testParserOptionFailsIfTwiceForAlias() {
117 AtomicReference<String> argFound = new AtomicReference<>();
118 OptionParser parser = new OptionParser("test")
119 .addArgumentParameter("test", OptionCount.REQUIRED, argFound::set)
120 .addShortAlias("test", "t");
121
122 Exception e = assertThrows(OptionParseException.class, () -> parser.parseOptions(Arrays.asList("--test", "arg", "-t", "arg")));
123 assertEquals("test: option '-t' may not appear multiple times", e.getMessage());
124 }
125
126 @Test
127 void testOptionalOptionFailsIfTwice() {
128 OptionParser parser = new OptionParser("test")
129 .addFlagParameter("test", this::nop);
130 Exception e = assertThrows(OptionParseException.class, () -> parser.parseOptions(Arrays.asList("--test", "--test")));
131 assertEquals("test: option '--test' may not appear multiple times", e.getMessage());
132 }
133
134 @Test
135 void testOptionalOptionFailsIfTwiceForAlias() {
136 OptionParser parser = new OptionParser("test")
137 .addFlagParameter("test", this::nop)
138 .addShortAlias("test", "t");
139 Exception e = assertThrows(OptionParseException.class, () -> parser.parseOptions(Arrays.asList("-t", "-t")));
140 assertEquals("test: option '-t' may not appear multiple times", e.getMessage());
141 }
142
143 @Test
144 void testOptionalOptionFailsIfTwiceForAlias2() {
145 OptionParser parser = new OptionParser("test")
146 .addFlagParameter("test", this::nop)
147 .addShortAlias("test", "t");
148 Exception e = assertThrows(OptionParseException.class, () -> parser.parseOptions(Arrays.asList("-tt")));
149 assertEquals("test: option '-t' may not appear multiple times", e.getMessage());
150 }
151
152 @Test
153 void testLongArgumentsUsingEqualSign() {
154 AtomicReference<String> argFound = new AtomicReference<>();
155 OptionParser parser = new OptionParser("test")
156 .addArgumentParameter("test", OptionCount.REQUIRED, argFound::set);
157
158 List<String> remaining = parser.parseOptions(Arrays.asList("--test=arg", "value"));
159
160 assertEquals(Arrays.asList("value"), remaining);
161 assertEquals("arg", argFound.get());
162
163 remaining = parser.parseOptions(Arrays.asList("--test=", "value"));
164
165 assertEquals(Arrays.asList("value"), remaining);
166 assertEquals("", argFound.get());
167
168 remaining = parser.parseOptions(Arrays.asList("--test=with space and=equals", "value"));
169
170 assertEquals(Arrays.asList("value"), remaining);
171 assertEquals("with space and=equals", argFound.get());
172 }
173
174 @Test
175 void testLongArgumentsMissingOption() {
176 OptionParser parser = new OptionParser("test")
177 .addArgumentParameter("test", OptionCount.REQUIRED, this::nop);
178
179 Exception e = assertThrows(OptionParseException.class, () -> parser.parseOptions(Arrays.asList("--test")));
180 assertEquals("test: option '--test' requires an argument", e.getMessage());
181 }
182
183 @Test
184 void testLongArgumentsMissingOption2() {
185 OptionParser parser = new OptionParser("test")
186 .addArgumentParameter("test", OptionCount.REQUIRED, this::nop);
187
188 Exception e = assertThrows(OptionParseException.class, () -> parser.parseOptions(Arrays.asList("--test", "--", "x")));
189 assertEquals("test: option '--test' requires an argument", e.getMessage());
190 }
191
192 @Test
193 void testShortArgumentsMissingOption() {
194 OptionParser parser = new OptionParser("test")
195 .addArgumentParameter("test", OptionCount.REQUIRED, this::nop)
196 .addShortAlias("test", "t");
197
198 Exception e = assertThrows(OptionParseException.class, () -> parser.parseOptions(Arrays.asList("-t")));
199 assertEquals("test: option '-t' requires an argument", e.getMessage());
200 }
201
202 @Test
203 void testShortArgumentsMissingOption2() {
204 OptionParser parser = new OptionParser("test")
205 .addArgumentParameter("test", OptionCount.REQUIRED, this::nop)
206 .addShortAlias("test", "t");
207
208 Exception e = assertThrows(OptionParseException.class, () -> parser.parseOptions(Arrays.asList("-t", "--", "x")));
209 assertEquals("test: option '-t' requires an argument", e.getMessage());
210 }
211
212 @Test
213 void testLongFlagHasOption() {
214 OptionParser parser = new OptionParser("test")
215 .addFlagParameter("test", this::nop);
216
217 Exception e = assertThrows(OptionParseException.class, () -> parser.parseOptions(Arrays.asList("--test=arg")));
218 assertEquals("test: option '--test' does not allow an argument", e.getMessage());
219 }
220
221 @Test
222 void testShortFlagHasOption() {
223 OptionParser parser = new OptionParser("test")
224 .addFlagParameter("test", this::nop)
225 .addShortAlias("test", "t");
226
227 Exception e = assertThrows(OptionParseException.class, () -> parser.parseOptions(Arrays.asList("-t=arg")));
228 assertEquals("test: option '-t' does not allow an argument", e.getMessage());
229 }
230
231 @Test
232 void testShortArgumentsUsingEqualSign() {
233 AtomicReference<String> argFound = new AtomicReference<>();
234 OptionParser parser = new OptionParser("test")
235 .addArgumentParameter("test", OptionCount.REQUIRED, argFound::set)
236 .addShortAlias("test", "t");
237
238 List<String> remaining = parser.parseOptions(Arrays.asList("-t=arg", "value"));
239
240 assertEquals(Arrays.asList("value"), remaining);
241 assertEquals("arg", argFound.get());
242 }
243
244 @Test
245 void testMultipleArguments() {
246 AtomicReference<String> argFound = new AtomicReference<>();
247 List<String> multiFound = new ArrayList<>();
248 AtomicBoolean usedFlag = new AtomicBoolean();
249 AtomicBoolean unusedFlag = new AtomicBoolean();
250 OptionParser parser = new OptionParser("test")
251 .addArgumentParameter("test", OptionCount.REQUIRED, argFound::set)
252 .addShortAlias("test", "t")
253 .addArgumentParameter("multi", OptionCount.MULTIPLE, multiFound::add)
254 .addFlagParameter("flag", () -> usedFlag.set(true))
255 .addFlagParameter("flag2", () -> unusedFlag.set(true));
256
257 List<String> remaining = parser.parseOptions(Arrays.asList(
258 "-t=arg", "--multi", "m1", "x1", "--flag", "--multi", "m2", "x2", "--", "x3", "--x4", "x5"));
259
260 assertEquals(Arrays.asList("x1", "x2", "x3", "--x4", "x5"), remaining);
261 assertEquals("arg", argFound.get());
262 assertEquals(Arrays.asList("m1", "m2"), multiFound);
263 assertTrue(usedFlag.get());
264 assertFalse(unusedFlag.get());
265 }
266
267 @Test
268 void testUseAlternatives() {
269 AtomicReference<String> argFound = new AtomicReference<>();
270 AtomicBoolean usedFlag = new AtomicBoolean();
271 AtomicBoolean unusedFlag = new AtomicBoolean();
272
273 OptionParser parser = new OptionParser("test")
274 .addArgumentParameter("test", OptionCount.REQUIRED, argFound::set)
275 .addFlagParameter("flag", () -> usedFlag.set(true))
276 .addFlagParameter("fleg", () -> unusedFlag.set(true));
277
278 List<String> remaining = parser.parseOptions(Arrays.asList("--te=arg", "--fla"));
279
280 assertEquals(Arrays.asList(), remaining);
281 assertEquals("arg", argFound.get());
282 assertTrue(usedFlag.get());
283 assertFalse(unusedFlag.get());
284 }
285
286 @Test
287 void testAmbiguousAlternatives() {
288 AtomicReference<String> argFound = new AtomicReference<>();
289 AtomicBoolean usedFlag = new AtomicBoolean();
290 AtomicBoolean unusedFlag = new AtomicBoolean();
291
292 OptionParser parser = new OptionParser("test")
293 .addArgumentParameter("test", OptionCount.REQUIRED, argFound::set)
294 .addFlagParameter("flag", () -> usedFlag.set(true))
295 .addFlagParameter("fleg", () -> unusedFlag.set(true));
296
297 Exception e = assertThrows(OptionParseException.class, () -> parser.parseOptions(Arrays.asList("--te=arg", "--fl")));
298 assertEquals("test: option '--fl' is ambiguous", e.getMessage());
299 }
300
301 @Test
302 void testMultipleShort() {
303 AtomicReference<String> argFound = new AtomicReference<>();
304 AtomicBoolean usedFlag = new AtomicBoolean();
305 AtomicBoolean unusedFlag = new AtomicBoolean();
306
307 OptionParser parser = new OptionParser("test")
308 .addArgumentParameter("test", OptionCount.REQUIRED, argFound::set)
309 .addShortAlias("test", "t")
310 .addFlagParameter("flag", () -> usedFlag.set(true))
311 .addShortAlias("flag", "f")
312 .addFlagParameter("fleg", () -> unusedFlag.set(true));
313
314 List<String> remaining = parser.parseOptions(Arrays.asList("-ft", "arg", "x"));
315
316 assertEquals(Arrays.asList("x"), remaining);
317 assertEquals("arg", argFound.get());
318 assertTrue(usedFlag.get());
319 assertFalse(unusedFlag.get());
320
321 remaining = parser.parseOptions(Arrays.asList("-f", "-t=arg", "x"));
322
323 assertEquals(Arrays.asList("x"), remaining);
324 assertEquals("arg", argFound.get());
325 assertTrue(usedFlag.get());
326 assertFalse(unusedFlag.get());
327 }
328
329 @Test
330 void testIllegalOptionName() {
331 Exception e = assertThrows(IllegalArgumentException.class, () ->
332 new OptionParser("test").addFlagParameter("", this::nop));
333 assertEquals("Illegal option name: ''", e.getMessage());
334 }
335
336 @Test
337 void testIllegalOptionName2() {
338 Exception e = assertThrows(IllegalArgumentException.class, () ->
339 new OptionParser("test").addFlagParameter("-", this::nop));
340 assertEquals("Illegal option name: '-'", e.getMessage());
341 }
342
343 @Test
344 void testIllegalOptionName3() {
345 Exception e = assertThrows(IllegalArgumentException.class, () ->
346 new OptionParser("test").addFlagParameter("-test", this::nop));
347 assertEquals("Illegal option name: '-test'", e.getMessage());
348 }
349
350 @Test
351 void testIllegalOptionName4() {
352 Exception e = assertThrows(IllegalArgumentException.class, () ->
353 new OptionParser("test").addFlagParameter("$", this::nop));
354 assertEquals("Illegal option name: '$'", e.getMessage());
355 }
356
357 @Test
358 void testDuplicateOptionName() {
359 Exception e = assertThrows(IllegalArgumentException.class, () ->
360 new OptionParser("test").addFlagParameter("test", this::nop).addFlagParameter("test", this::nop));
361 assertEquals("The option '--test' is already registered", e.getMessage());
362 }
363
364 @Test
365 void testDuplicateOptionName2() {
366 Exception e = assertThrows(IllegalArgumentException.class, () ->
367 new OptionParser("test").addFlagParameter("test", this::nop)
368 .addArgumentParameter("test", OptionCount.OPTIONAL, this::nop));
369 assertEquals("The option '--test' is already registered", e.getMessage());
370 }
371
372 @Test
373 void testInvalidShortAlias() {
374 Exception e = assertThrows(IllegalArgumentException.class, () ->
375 new OptionParser("test").addFlagParameter("test", this::nop).addShortAlias("test", "$"));
376 assertEquals("Short name '$' must be one character", e.getMessage());
377 }
378
379 @Test
380 void testInvalidShortAlias2() {
381 Exception e = assertThrows(IllegalArgumentException.class, () ->
382 new OptionParser("test").addFlagParameter("test", this::nop).addShortAlias("test", ""));
383 assertEquals("Short name '' must be one character", e.getMessage());
384 }
385
386 @Test
387 void testInvalidShortAlias3() {
388 Exception e = assertThrows(IllegalArgumentException.class, () ->
389 new OptionParser("test").addFlagParameter("test", this::nop).addShortAlias("test", "xx"));
390 assertEquals("Short name 'xx' must be one character", e.getMessage());
391 }
392
393 @Test
394 void testDuplicateShortAlias() {
395 Exception e = assertThrows(IllegalArgumentException.class, () ->
396 new OptionParser("test").addFlagParameter("test", this::nop)
397 .addFlagParameter("test2", this::nop)
398 .addShortAlias("test", "t")
399 .addShortAlias("test2", "t"));
400 assertEquals("Short name 't' is already used", e.getMessage());
401 }
402
403 @Test
404 void testInvalidShortNoLong() {
405 Exception e = assertThrows(IllegalArgumentException.class, () ->
406 new OptionParser("test").addFlagParameter("test", this::nop).addShortAlias("test2", "t"));
407 assertEquals("No long definition for test2 was defined. " +
408 "Define the long definition first before creating a short definition for it.", e.getMessage());
409 }
410
411 private void nop() {
412 // nop
413 }
414
415 private void nop(String arg) {
416 // nop
417 }
418}
Note: See TracBrowser for help on using the repository browser.