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.text.ParseException; 020 021import java.util.ArrayList; 022import java.util.Arrays; 023import java.util.Collections; 024import java.util.HashSet; 025import java.util.Iterator; 026import java.util.List; 027import java.util.ListIterator; 028import java.util.Set; 029 030import org.apache.commons.cli2.Argument; 031import org.apache.commons.cli2.DisplaySetting; 032import org.apache.commons.cli2.HelpLine; 033import org.apache.commons.cli2.Option; 034import org.apache.commons.cli2.OptionException; 035import org.apache.commons.cli2.WriteableCommandLine; 036import org.apache.commons.cli2.builder.ArgumentBuilder; 037import org.apache.commons.cli2.builder.GroupBuilder; 038import org.apache.commons.cli2.commandline.WriteableCommandLineImpl; 039import org.apache.commons.cli2.resource.ResourceConstants; 040import org.apache.commons.cli2.resource.ResourceHelper; 041import org.apache.commons.cli2.validation.DateValidator; 042import org.apache.commons.cli2.validation.DateValidatorTest; 043 044/** 045 * @author Rob Oxspring 046 */ 047public class ArgumentTest 048 extends ArgumentTestCase { 049 private ResourceHelper resources = ResourceHelper.getResourceHelper(); 050 051 public static Argument buildUsernameArgument() { 052 return new ArgumentImpl("username", "The user to connect as", 1, 1, '\0', '\0', null, 053 ArgumentImpl.DEFAULT_CONSUME_REMAINING, null, 0); 054 } 055 056 public static Argument buildHostArgument() { 057 return new ArgumentImpl("host", "The host name", 2, 3, '\0', ',', null, null, null, 0); 058 } 059 060 public static Argument buildPathArgument() { 061 return new ArgumentImpl("path", "The place to look for files", 1, Integer.MAX_VALUE, '=', 062 ';', null, ArgumentImpl.DEFAULT_CONSUME_REMAINING, null, 0); 063 } 064 065 public static Argument buildDateLimitArgument() { 066 return new ArgumentImpl("limit", "the last acceptable date", 0, 1, '=', '\0', 067 new DateValidator(DateValidatorTest.YYYY_MM_DD), null, null, 0); 068 } 069 070 public static Argument buildTargetsArgument() { 071 return new ArgumentImpl("target", "The targets ant should build", 0, Integer.MAX_VALUE, 072 '\0', ',', null, null, null, 0); 073 } 074 075 public static Argument buildSizeArgument() { 076 List defaults = new ArrayList(); 077 defaults.add("10"); 078 079 return new ArgumentImpl("size", "The number of units", 1, 1, '\0', '\0', null, 080 ArgumentImpl.DEFAULT_CONSUME_REMAINING, defaults, 0); 081 } 082 083 public static Argument buildBoundsArgument() { 084 List defaults = new ArrayList(); 085 defaults.add("5"); 086 defaults.add("10"); 087 088 return new ArgumentImpl("size", "The number of units", 2, 2, '\0', '\0', null, 089 ArgumentImpl.DEFAULT_CONSUME_REMAINING, defaults, 0); 090 } 091 092 public void testNew() { 093 try { 094 new ArgumentImpl("limit", "the last acceptable date", 10, 5, '=', '\0', 095 new DateValidator(DateValidatorTest.YYYY_MM_DD), null, null, 0); 096 } catch (IllegalArgumentException e) { 097 assertEquals(resources.getMessage("Argument.minimum.exceeds.maximum"), e.getMessage()); 098 } 099 100 { 101 ArgumentImpl arg = 102 new ArgumentImpl(null, "the last acceptable date", 5, 5, '=', '\0', 103 new DateValidator(DateValidatorTest.YYYY_MM_DD), null, null, 0); 104 assertEquals("wrong arg name", "arg", arg.getPreferredName()); 105 } 106 107 { 108 List defaults = new ArrayList(); 109 110 try { 111 new ArgumentImpl(null, "the last acceptable date", 1, 1, '=', '\0', 112 new DateValidator(DateValidatorTest.YYYY_MM_DD), null, defaults, 0); 113 } catch (IllegalArgumentException exp) { 114 assertEquals(resources.getMessage("Argument.too.few.defaults"), exp.getMessage()); 115 } 116 } 117 118 try { 119 List defaults = new ArrayList(); 120 defaults.add("1"); 121 defaults.add("2"); 122 123 new ArgumentImpl(null, "the last acceptable date", 1, 1, '=', '\0', 124 new DateValidator(DateValidatorTest.YYYY_MM_DD), null, defaults, 0); 125 } catch (IllegalArgumentException exp) { 126 assertEquals(resources.getMessage("Argument.too.many.defaults"), exp.getMessage()); 127 } 128 } 129 130 /* 131 * (non-Javadoc) 132 * 133 * @see org.apache.commons.cli2.ArgumentTestCase#testProcessValues() 134 */ 135 public void testProcessValues() 136 throws OptionException { 137 final Argument option = buildUsernameArgument(); 138 final List args = list("rob"); 139 final WriteableCommandLine commandLine = commandLine(option, args); 140 final ListIterator iterator = args.listIterator(); 141 option.processValues(commandLine, iterator, option); 142 143 assertFalse(iterator.hasNext()); 144 assertTrue(commandLine.hasOption(option)); 145 assertTrue(commandLine.hasOption("username")); 146 assertEquals("rob", commandLine.getValue(option)); 147 } 148 149 public void testProcessValues_BoundaryQuotes() 150 throws OptionException { 151 final Argument option = buildUsernameArgument(); 152 final List args = list("\"rob\""); 153 final WriteableCommandLine commandLine = commandLine(option, args); 154 final ListIterator iterator = args.listIterator(); 155 option.processValues(commandLine, iterator, option); 156 157 assertFalse(iterator.hasNext()); 158 assertTrue(commandLine.hasOption(option)); 159 assertTrue(commandLine.hasOption("username")); 160 assertEquals("rob", commandLine.getValue(option)); 161 } 162 163 public void testProcessValues_SpareValues() 164 throws OptionException { 165 final Argument option = buildUsernameArgument(); 166 final List args = list("rob", "secret"); 167 final WriteableCommandLine commandLine = commandLine(option, args); 168 final ListIterator iterator = args.listIterator(); 169 option.processValues(commandLine, iterator, option); 170 171 assertTrue(iterator.hasNext()); 172 assertTrue(commandLine.hasOption(option)); 173 assertTrue(commandLine.hasOption("username")); 174 assertEquals("rob", commandLine.getValue(option)); 175 } 176 177 public void testProcessValues_Optional() { 178 final Argument option = buildTargetsArgument(); 179 final List args = list(); 180 final WriteableCommandLine commandLine = commandLine(option, args); 181 final ListIterator iterator = args.listIterator(); 182 183 try { 184 option.processValues(commandLine, iterator, option); 185 } catch (final OptionException mve) { 186 assertEquals(option, mve.getOption()); 187 assertEquals("Missing value(s) target [target ...]", mve.getMessage()); 188 } 189 190 assertFalse(iterator.hasNext()); 191 assertFalse(commandLine.hasOption(option)); 192 assertFalse(commandLine.hasOption("username")); 193 assertTrue(commandLine.getValues(option).isEmpty()); 194 } 195 196 public void testProcessValues_Multiple() 197 throws OptionException { 198 final Argument option = buildTargetsArgument(); 199 final List args = list("compile", "test", "docs"); 200 final WriteableCommandLine commandLine = commandLine(option, args); 201 final ListIterator iterator = args.listIterator(); 202 option.processValues(commandLine, iterator, option); 203 204 assertFalse(iterator.hasNext()); 205 assertTrue(commandLine.hasOption(option)); 206 assertTrue(commandLine.hasOption("target")); 207 assertFalse(commandLine.getValues(option).isEmpty()); 208 assertListContentsEqual(args, commandLine.getValues(option)); 209 } 210 211 public void testProcessValues_Contracted() 212 throws OptionException { 213 final Argument option = buildTargetsArgument(); 214 final List args = list("compile,test,javadoc", "checkstyle,jdepend"); 215 final WriteableCommandLine commandLine = commandLine(option, args); 216 final ListIterator iterator = args.listIterator(); 217 option.processValues(commandLine, iterator, option); 218 219 assertFalse(iterator.hasNext()); 220 assertTrue(commandLine.hasOption(option)); 221 assertTrue(commandLine.hasOption("target")); 222 assertListContentsEqual(list("compile", "test", "javadoc", "checkstyle", "jdepend"), 223 commandLine.getValues(option)); 224 } 225 226 public void testProcessValues_ContractedTooFew() { 227 final Argument option = buildHostArgument(); 228 final List args = list("box1"); 229 final WriteableCommandLine commandLine = commandLine(option, args); 230 final ListIterator iterator = args.listIterator(); 231 232 try { 233 option.processValues(commandLine, iterator, option); 234 option.validate(commandLine); 235 fail("Expected MissingValueException"); 236 } catch (OptionException mve) { 237 assertSame(option, mve.getOption()); 238 } 239 } 240 241 public void testProcessValues_ContractedTooMany() { 242 final Argument option = buildHostArgument(); 243 final List args = list("box1,box2,box3,box4"); 244 final WriteableCommandLine commandLine = commandLine(option, args); 245 final ListIterator iterator = args.listIterator(); 246 247 try { 248 option.processValues(commandLine, iterator, option); 249 option.validate(commandLine); 250 fail("Expected MissingValueException"); 251 } catch (OptionException mve) { 252 assertSame(option, mve.getOption()); 253 } 254 } 255 256 /* 257 * (non-Javadoc) 258 * 259 * @see org.apache.commons.cli2.OptionTestCase#testCanProcess() 260 */ 261 public void testCanProcess() { 262 final Argument option = buildTargetsArgument(); 263 assertTrue(option.canProcess(new WriteableCommandLineImpl(option, null), "any value")); 264 } 265 266 /* 267 * (non-Javadoc) 268 * 269 * @see org.apache.commons.cli2.OptionTestCase#testPrefixes() 270 */ 271 public void testPrefixes() { 272 final Argument option = buildTargetsArgument(); 273 assertTrue(option.getPrefixes().isEmpty()); 274 } 275 276 /* 277 * (non-Javadoc) 278 * 279 * @see org.apache.commons.cli2.OptionTestCase#testProcess() 280 */ 281 public void testProcess() 282 throws OptionException { 283 final Argument option = buildPathArgument(); 284 final List args = list("-path=/lib;/usr/lib;/usr/local/lib"); 285 final WriteableCommandLine commandLine = commandLine(option, args); 286 final ListIterator iterator = args.listIterator(); 287 option.process(commandLine, iterator); 288 289 assertFalse(iterator.hasNext()); 290 assertTrue(commandLine.hasOption(option)); 291 assertTrue(commandLine.hasOption("path")); 292 assertListContentsEqual(list("-path=/lib", "/usr/lib", "/usr/local/lib"), 293 commandLine.getValues(option)); 294 } 295 296 /* 297 * (non-Javadoc) 298 * 299 * @see org.apache.commons.cli2.OptionTestCase#testTriggers() 300 */ 301 public void testTriggers() { 302 final Argument option = buildTargetsArgument(); 303 assertTrue(option.getTriggers().isEmpty()); 304 } 305 306 /* 307 * (non-Javadoc) 308 * 309 * @see org.apache.commons.cli2.OptionTestCase#testValidate() 310 */ 311 public void testValidate() 312 throws OptionException { 313 final Argument option = buildUsernameArgument(); 314 final WriteableCommandLine commandLine = commandLine(option, list()); 315 316 commandLine.addValue(option, "rob"); 317 318 option.validate(commandLine); 319 } 320 321 public void testValidate_Minimum() { 322 final Argument option = buildUsernameArgument(); 323 final WriteableCommandLine commandLine = commandLine(option, list()); 324 325 try { 326 option.validate(commandLine); 327 fail("UnexpectedValue"); 328 } catch (OptionException mve) { 329 assertEquals(option, mve.getOption()); 330 } 331 } 332 333 public void testRequired() { 334 { 335 final Argument arg = buildBoundsArgument(); 336 337 assertTrue("not required", arg.isRequired()); 338 } 339 340 { 341 final Argument arg = buildTargetsArgument(); 342 343 assertFalse("should not be required", arg.isRequired()); 344 } 345 } 346 347 public void testValidate_Maximum() { 348 final Argument option = buildUsernameArgument(); 349 final WriteableCommandLine commandLine = commandLine(option, list()); 350 351 commandLine.addValue(option, "rob"); 352 commandLine.addValue(option, "oxspring"); 353 354 try { 355 option.validate(commandLine); 356 fail("UnexpectedValue"); 357 } catch (OptionException uve) { 358 assertEquals(option, uve.getOption()); 359 } 360 } 361 362 public void testValidate_Validator() 363 throws OptionException, ParseException { 364 final Argument option = buildDateLimitArgument(); 365 final WriteableCommandLine commandLine = commandLine(option, list()); 366 367 commandLine.addValue(option, "2004-01-01"); 368 369 option.validate(commandLine, option); 370 assertContentsEqual(Arrays.asList(new Object[] { 371 DateValidatorTest.YYYY_MM_DD.parse("2004-01-01") 372 }), commandLine.getValues(option)); 373 } 374 375 public void testValidate_ValidatorInvalidDate() 376 throws OptionException, ParseException { 377 final Argument option = buildDateLimitArgument(); 378 final WriteableCommandLine commandLine = commandLine(option, list()); 379 380 commandLine.addValue(option, "12-12-2004"); 381 382 try { 383 option.validate(commandLine, option); 384 } catch (OptionException exp) { 385 OptionException e = 386 new OptionException(option, ResourceConstants.ARGUMENT_UNEXPECTED_VALUE, 387 "12-12-2004"); 388 assertEquals("wrong exception message", e.getMessage(), exp.getMessage()); 389 } 390 } 391 392 /* 393 * (non-Javadoc) 394 * 395 * @see org.apache.commons.cli2.OptionTestCase#testAppendUsage() 396 */ 397 public void testAppendUsage() { 398 final Option option = buildUsernameArgument(); 399 final StringBuffer buffer = new StringBuffer(); 400 option.appendUsage(buffer, DisplaySetting.ALL, null); 401 402 assertEquals("<username>", buffer.toString()); 403 } 404 405 public void testAppendUsage_Infinite() { 406 final Option option = buildTargetsArgument(); 407 final StringBuffer buffer = new StringBuffer(); 408 option.appendUsage(buffer, DisplaySetting.ALL, null); 409 410 assertEquals("[<target1> [<target2> ...]]", buffer.toString()); 411 } 412 413 public void testAppendUsage_InfiniteNoOptional() { 414 final Option option = buildTargetsArgument(); 415 final StringBuffer buffer = new StringBuffer(); 416 final Set settings = new HashSet(DisplaySetting.ALL); 417 settings.remove(DisplaySetting.DISPLAY_OPTIONAL); 418 option.appendUsage(buffer, settings, null); 419 420 assertEquals("<target1> [<target2> ...]", buffer.toString()); 421 } 422 423 public void testAppendUsage_InfiniteNoNumbering() { 424 final Option option = buildTargetsArgument(); 425 final StringBuffer buffer = new StringBuffer(); 426 final Set settings = new HashSet(DisplaySetting.ALL); 427 settings.remove(DisplaySetting.DISPLAY_ARGUMENT_NUMBERED); 428 option.appendUsage(buffer, settings, null); 429 430 assertEquals("[<target> [<target> ...]]", buffer.toString()); 431 } 432 433 public void testAppendUsage_Minimum() { 434 final Option option = buildHostArgument(); 435 final StringBuffer buffer = new StringBuffer(); 436 option.appendUsage(buffer, DisplaySetting.ALL, null); 437 438 assertEquals("<host1> <host2> [<host3>]", buffer.toString()); 439 } 440 441 /* 442 * (non-Javadoc) 443 * 444 * @see org.apache.commons.cli2.OptionTestCase#testGetPreferredName() 445 */ 446 public void testGetPreferredName() { 447 final Option option = buildPathArgument(); 448 assertEquals("path", option.getPreferredName()); 449 } 450 451 /* 452 * (non-Javadoc) 453 * 454 * @see org.apache.commons.cli2.OptionTestCase#testGetDescription() 455 */ 456 public void testGetDescription() { 457 final Option option = buildHostArgument(); 458 assertEquals("The host name", option.getDescription()); 459 } 460 461 /* 462 * (non-Javadoc) 463 * 464 * @see org.apache.commons.cli2.OptionTestCase#testHelpLines() 465 */ 466 public void testHelpLines() { 467 final Option option = buildHostArgument(); 468 final List lines = option.helpLines(0, DisplaySetting.ALL, null); 469 final Iterator i = lines.iterator(); 470 471 final HelpLine line1 = (HelpLine) i.next(); 472 assertEquals(0, line1.getIndent()); 473 assertEquals(option, line1.getOption()); 474 475 assertFalse(i.hasNext()); 476 } 477 478 public void testCanProcess_ConsumeRemaining() { 479 final Option option = buildUsernameArgument(); 480 481 assertTrue(option.canProcess(new WriteableCommandLineImpl(option, null), "--")); 482 } 483 484 public void testProcess_ConsumeRemaining() 485 throws OptionException { 486 final Option option = buildPathArgument(); 487 final List args = list("options", "--", "--ignored", "-Dprop=val"); 488 final WriteableCommandLine commandLine = commandLine(option, args); 489 final ListIterator iterator = args.listIterator(); 490 491 option.process(commandLine, iterator); 492 493 final List values = commandLine.getValues(option); 494 assertTrue(values.contains("options")); 495 assertTrue(values.contains("--ignored")); 496 assertTrue(values.contains("-Dprop=val")); 497 assertEquals(3, values.size()); 498 assertFalse(iterator.hasNext()); 499 } 500 501 public void testProcess_ConsumeNothing() { 502 final Option option = buildPathArgument(); 503 final List args = list("--"); 504 final WriteableCommandLine commandLine = commandLine(option, args); 505 final ListIterator iterator = args.listIterator(); 506 507 try { 508 option.process(commandLine, iterator); 509 option.validate(commandLine); 510 fail("Missing Value!"); 511 } catch (OptionException mve) { 512 assertEquals(option, mve.getOption()); 513 assertEquals("Missing value(s) path [path ...]", mve.getMessage()); 514 } 515 516 assertTrue(commandLine.getValues(option).isEmpty()); 517 assertFalse(iterator.hasNext()); 518 } 519 520 // public void testProcess_DefinedDefaultValue() throws OptionException { 521 // final Option size = buildSizeArgument(); 522 // final List args = list(); 523 // final WriteableCommandLine commandLine = commandLine(size, args); 524 // final ListIterator iterator = args.listIterator(); 525 // 526 // size.process(commandLine, iterator); 527 // 528 // assertEquals("10", commandLine.getValue(size)); 529 // } 530 // 531 // public void testProcess_DefinedDefaultValues() throws OptionException { 532 // final Option bounds = buildBoundsArgument(); 533 // final List args = list(); 534 // final WriteableCommandLine commandLine = commandLine(bounds, args); 535 // final ListIterator iterator = args.listIterator(); 536 // 537 // bounds.process(commandLine, iterator); 538 // 539 // List values = new ArrayList(); 540 // values.add("5"); 541 // values.add("10"); 542 // assertEquals(values, commandLine.getValues(bounds)); 543 // } 544 public void testProcess_InterrogatedDefaultValue() 545 throws OptionException { 546 final Option size = buildSizeArgument(); 547 final List args = list(); 548 final WriteableCommandLine commandLine = commandLine(size, args); 549 final ListIterator iterator = args.listIterator(); 550 551 size.process(commandLine, iterator); 552 553 assertEquals(new Integer(20), commandLine.getValue(size, new Integer(20))); 554 } 555 556 public void testTooFewDefaults() { 557 List defaults = new ArrayList(); 558 defaults.add("5"); 559 560 try { 561 new ArgumentImpl("size", "The number of units", 2, 2, '\0', '\0', null, 562 ArgumentImpl.DEFAULT_CONSUME_REMAINING, defaults, 0); 563 } catch (IllegalArgumentException exp) { 564 assertEquals("wrong exception message", 565 ResourceHelper.getResourceHelper().getMessage(ResourceConstants.ARGUMENT_TOO_FEW_DEFAULTS), 566 exp.getMessage()); 567 } 568 } 569 570 public void testTooManyDefaults() { 571 List defaults = new ArrayList(); 572 defaults.add("5"); 573 defaults.add("10"); 574 defaults.add("15"); 575 576 try { 577 new ArgumentImpl("size", "The number of units", 2, 2, '\0', '\0', null, 578 ArgumentImpl.DEFAULT_CONSUME_REMAINING, defaults, 0); 579 } catch (IllegalArgumentException exp) { 580 assertEquals("wrong exception message", 581 ResourceHelper.getResourceHelper().getMessage(ResourceConstants.ARGUMENT_TOO_MANY_DEFAULTS), 582 exp.getMessage()); 583 } 584 } 585 586 public void testProcess_InterrogatedDefaultValues() 587 throws OptionException { 588 final Option bounds = buildBoundsArgument(); 589 final List args = list(); 590 final WriteableCommandLine commandLine = commandLine(bounds, args); 591 final ListIterator iterator = args.listIterator(); 592 593 bounds.process(commandLine, iterator); 594 595 // test with values 596 List values = new ArrayList(); 597 values.add("50"); 598 values.add("100"); 599 assertEquals(values, commandLine.getValues(bounds, values)); 600 601 // test without values 602 assertEquals(Collections.EMPTY_LIST, commandLine.getValues(bounds, null)); 603 } 604 605 public void testProcess_StripBoundaryQuotes() 606 throws OptionException { 607 final Option bounds = buildBoundsArgument(); 608 final List args = list(); 609 final WriteableCommandLine commandLine = commandLine(bounds, args); 610 final ListIterator iterator = args.listIterator(); 611 612 bounds.process(commandLine, iterator); 613 614 List values = new ArrayList(); 615 values.add("50\""); 616 values.add("\"100"); 617 assertEquals(values, commandLine.getValues(bounds, values)); 618 } 619 620 public void testSourceDestArgument() { 621 final ArgumentBuilder abuilder = new ArgumentBuilder(); 622 final GroupBuilder gbuilder = new GroupBuilder(); 623 final Argument inputfiles = 624 abuilder.withName("input").withMinimum(0).withMaximum(0).create(); 625 final Argument bad_outputfile = 626 abuilder.withName("output").withMinimum(1).withMaximum(2).create(); 627 628 try { 629 final Argument targets = new SourceDestArgument(inputfiles, bad_outputfile); 630 } catch (final IllegalArgumentException exp) { 631 assertEquals("wrong exception message", 632 ResourceHelper.getResourceHelper().getMessage(ResourceConstants.SOURCE_DEST_MUST_ENFORCE_VALUES), 633 exp.getMessage()); 634 } 635 636 final Argument outputfile = 637 abuilder.withName("output").withMinimum(1).withMaximum(1).create(); 638 639 final Argument targets = new SourceDestArgument(inputfiles, outputfile); 640 final StringBuffer buffer = new StringBuffer("test content"); 641 targets.appendUsage(buffer, Collections.EMPTY_SET, null); 642 643 assertTrue("buffer not added", buffer.toString().startsWith("test content")); 644 assertFalse("space added", buffer.charAt(12) == ' '); 645 } 646}