@@ -19,6 +19,7 @@ Licensed to the Apache Software Foundation (ASF) under one or more
1919
2020import static org .junit .jupiter .api .Assertions .assertEquals ;
2121import static org .junit .jupiter .api .Assertions .assertFalse ;
22+ import static org .junit .jupiter .api .Assertions .assertThrows ;
2223import static org .junit .jupiter .api .Assertions .assertTrue ;
2324
2425import java .util .HashSet ;
@@ -157,6 +158,184 @@ public void setUp() {
157158 parser = new DefaultParser ();
158159 }
159160
161+ @ Test
162+ void chainingParsersSkipHappyPath () throws ParseException {
163+ Option a = Option .builder ().option ("a" ).longOpt ("first-letter" ).build ();
164+ Option b = Option .builder ().option ("b" ).longOpt ("second-letter" ).build ();
165+ Option c = Option .builder ().option ("c" ).longOpt ("third-letter" ).build ();
166+ Option d = Option .builder ().option ("d" ).longOpt ("fourth-letter" ).build ();
167+
168+ Options baseOptions = new Options ();
169+ baseOptions .addOption (a );
170+ baseOptions .addOption (b );
171+ Options specificOptions = new Options ();
172+ specificOptions .addOption (a );
173+ specificOptions .addOption (b );
174+ specificOptions .addOption (c );
175+ specificOptions .addOption (d );
176+
177+ String [] args = {"-a" , "-b" , "-c" , "-d" , "arg1" , "arg2" };
178+
179+ DefaultParser parser = new DefaultParser ();
180+
181+ CommandLine baseCommandLine = parser .parse (baseOptions , null , DefaultParser .NonOptionAction .SKIP , args );
182+ assertEquals (2 , baseCommandLine .getOptions ().length );
183+ assertEquals (4 , baseCommandLine .getArgs ().length );
184+ assertTrue (baseCommandLine .hasOption ("a" ));
185+ assertTrue (baseCommandLine .hasOption ("b" ));
186+ assertFalse (baseCommandLine .hasOption ("c" ));
187+ assertFalse (baseCommandLine .hasOption ("d" ));
188+ assertFalse (baseCommandLine .getArgList ().contains ("-a" ));
189+ assertFalse (baseCommandLine .getArgList ().contains ("-b" ));
190+ assertTrue (baseCommandLine .getArgList ().contains ("-c" ));
191+ assertTrue (baseCommandLine .getArgList ().contains ("-d" ));
192+ assertTrue (baseCommandLine .getArgList ().contains ("arg1" ));
193+ assertTrue (baseCommandLine .getArgList ().contains ("arg2" ));
194+
195+ CommandLine specificCommandLine = parser .parse (specificOptions , null , DefaultParser .NonOptionAction .THROW , args );
196+ assertEquals (4 , specificCommandLine .getOptions ().length );
197+ assertEquals (2 , specificCommandLine .getArgs ().length );
198+ assertTrue (specificCommandLine .hasOption ("a" ));
199+ assertTrue (specificCommandLine .hasOption ("b" ));
200+ assertTrue (specificCommandLine .hasOption ("c" ));
201+ assertTrue (specificCommandLine .hasOption ("d" ));
202+ assertFalse (specificCommandLine .getArgList ().contains ("-a" ));
203+ assertFalse (specificCommandLine .getArgList ().contains ("-b" ));
204+ assertFalse (specificCommandLine .getArgList ().contains ("-c" ));
205+ assertFalse (specificCommandLine .getArgList ().contains ("-d" ));
206+ assertTrue (specificCommandLine .getArgList ().contains ("arg1" ));
207+ assertTrue (specificCommandLine .getArgList ().contains ("arg2" ));
208+ }
209+
210+ @ Test
211+ void chainingParsersSkipNonHappyPath () throws ParseException {
212+ Option a = Option .builder ().option ("a" ).longOpt ("first-letter" ).build ();
213+ Option b = Option .builder ().option ("b" ).longOpt ("second-letter" ).build ();
214+ Option c = Option .builder ().option ("c" ).longOpt ("third-letter" ).build ();
215+
216+ Options baseOptions = new Options ();
217+ baseOptions .addOption (a );
218+ baseOptions .addOption (b );
219+ Options specificOptions = new Options ();
220+ specificOptions .addOption (a );
221+ specificOptions .addOption (b );
222+ specificOptions .addOption (c );
223+
224+ String [] args = {"-a" , "-b" , "-c" , "-d" , "arg1" , "arg2" }; // -d is rogue option
225+
226+ DefaultParser parser = new DefaultParser ();
227+
228+ CommandLine baseCommandLine = parser .parse (baseOptions , null , DefaultParser .NonOptionAction .SKIP , args );
229+ assertEquals (2 , baseCommandLine .getOptions ().length );
230+ assertEquals (4 , baseCommandLine .getArgs ().length );
231+
232+ UnrecognizedOptionException e = assertThrows (UnrecognizedOptionException .class ,
233+ () -> parser .parse (specificOptions , null , DefaultParser .NonOptionAction .THROW , args ));
234+ assertTrue (e .getMessage ().contains ("-d" ));
235+ }
236+
237+ @ Test
238+ void chainingParsersIgnoreHappyPath () throws ParseException {
239+ Option a = Option .builder ().option ("a" ).longOpt ("first-letter" ).build ();
240+ Option b = Option .builder ().option ("b" ).longOpt ("second-letter" ).build ();
241+ Option c = Option .builder ().option ("c" ).longOpt ("third-letter" ).build ();
242+ Option d = Option .builder ().option ("d" ).longOpt ("fourth-letter" ).build ();
243+
244+ Options baseOptions = new Options ();
245+ baseOptions .addOption (a );
246+ baseOptions .addOption (b );
247+ Options specificOptions = new Options ();
248+ specificOptions .addOption (a );
249+ specificOptions .addOption (b );
250+ specificOptions .addOption (c );
251+ specificOptions .addOption (d );
252+
253+ String [] args = {"-a" , "-b" , "-c" , "-d" , "arg1" , "arg2" };
254+
255+ DefaultParser parser = new DefaultParser ();
256+
257+ CommandLine baseCommandLine = parser .parse (baseOptions , null , DefaultParser .NonOptionAction .IGNORE , args );
258+ assertEquals (2 , baseCommandLine .getOptions ().length );
259+ assertEquals (2 , baseCommandLine .getArgs ().length );
260+ assertTrue (baseCommandLine .hasOption ("a" ));
261+ assertTrue (baseCommandLine .hasOption ("b" ));
262+ assertFalse (baseCommandLine .hasOption ("c" ));
263+ assertFalse (baseCommandLine .hasOption ("d" ));
264+ assertFalse (baseCommandLine .getArgList ().contains ("-a" ));
265+ assertFalse (baseCommandLine .getArgList ().contains ("-b" ));
266+ assertFalse (baseCommandLine .getArgList ().contains ("-c" ));
267+ assertFalse (baseCommandLine .getArgList ().contains ("-d" ));
268+ assertTrue (baseCommandLine .getArgList ().contains ("arg1" ));
269+ assertTrue (baseCommandLine .getArgList ().contains ("arg2" ));
270+
271+ CommandLine specificCommandLine = parser .parse (specificOptions , null , DefaultParser .NonOptionAction .THROW , args );
272+ assertEquals (4 , specificCommandLine .getOptions ().length );
273+ assertEquals (2 , specificCommandLine .getArgs ().length );
274+ assertTrue (specificCommandLine .hasOption ("a" ));
275+ assertTrue (specificCommandLine .hasOption ("b" ));
276+ assertTrue (specificCommandLine .hasOption ("c" ));
277+ assertTrue (specificCommandLine .hasOption ("d" ));
278+ assertFalse (specificCommandLine .getArgList ().contains ("-a" ));
279+ assertFalse (specificCommandLine .getArgList ().contains ("-b" ));
280+ assertFalse (specificCommandLine .getArgList ().contains ("-c" ));
281+ assertFalse (specificCommandLine .getArgList ().contains ("-d" ));
282+ assertTrue (specificCommandLine .getArgList ().contains ("arg1" ));
283+ assertTrue (specificCommandLine .getArgList ().contains ("arg2" ));
284+ }
285+
286+ @ Test
287+ void chainingParsersIgnoreNonHappyPath () throws ParseException {
288+ Option a = Option .builder ().option ("a" ).longOpt ("first-letter" ).build ();
289+ Option b = Option .builder ().option ("b" ).longOpt ("second-letter" ).build ();
290+ Option c = Option .builder ().option ("c" ).longOpt ("third-letter" ).build ();
291+
292+ Options baseOptions = new Options ();
293+ baseOptions .addOption (a );
294+ baseOptions .addOption (b );
295+ Options specificOptions = new Options ();
296+ specificOptions .addOption (a );
297+ specificOptions .addOption (b );
298+ specificOptions .addOption (c );
299+
300+ String [] args = {"-a" , "-b" , "-c" , "-d" , "arg1" , "arg2" }; // -d is rogue option
301+
302+ DefaultParser parser = new DefaultParser ();
303+
304+ CommandLine baseCommandLine = parser .parse (baseOptions , null , DefaultParser .NonOptionAction .IGNORE , args );
305+ assertEquals (2 , baseCommandLine .getOptions ().length );
306+ assertEquals (2 , baseCommandLine .getArgs ().length );
307+
308+ UnrecognizedOptionException e = assertThrows (UnrecognizedOptionException .class ,
309+ () -> parser .parse (specificOptions , null , DefaultParser .NonOptionAction .THROW , args ));
310+ assertTrue (e .getMessage ().contains ("-d" ));
311+ }
312+
313+ @ Test
314+ void legacyStopAtNonOption () throws ParseException {
315+ Option a = Option .builder ().option ("a" ).longOpt ("first-letter" ).build ();
316+ Option b = Option .builder ().option ("b" ).longOpt ("second-letter" ).build ();
317+ Option c = Option .builder ().option ("c" ).longOpt ("third-letter" ).build ();
318+
319+ Options options = new Options ();
320+ options .addOption (a );
321+ options .addOption (b );
322+ options .addOption (c );
323+
324+ String [] args = {"-a" , "-b" , "-c" , "-d" , "arg1" , "arg2" }; // -d is rogue option
325+
326+ DefaultParser parser = new DefaultParser ();
327+
328+ CommandLine commandLine = parser .parse (options , args , null , true );
329+ assertEquals (3 , commandLine .getOptions ().length );
330+ assertEquals (3 , commandLine .getArgs ().length );
331+ assertTrue (commandLine .getArgList ().contains ("-d" ));
332+ assertTrue (commandLine .getArgList ().contains ("arg1" ));
333+ assertTrue (commandLine .getArgList ().contains ("arg2" ));
334+
335+ UnrecognizedOptionException e = assertThrows (UnrecognizedOptionException .class , () -> parser .parse (options , args , null , false ));
336+ assertTrue (e .getMessage ().contains ("-d" ));
337+ }
338+
160339 @ Test
161340 void testBuilder () {
162341 // @formatter:off
0 commit comments