JCommanderTest.java revision f19232f69a08b3fc0242b91ea0095b47f5fad44b
1/** 2 * Copyright (C) 2010 the original author or authors. 3 * See the notice.md file distributed with this work for additional 4 * information regarding copyright ownership. 5 * 6 * Licensed under the Apache License, Version 2.0 (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 */ 18 19package com.beust.jcommander; 20 21import com.beust.jcommander.args.Args1; 22import com.beust.jcommander.args.Args1Setter; 23import com.beust.jcommander.args.Args2; 24import com.beust.jcommander.args.ArgsArityString; 25import com.beust.jcommander.args.ArgsBooleanArity; 26import com.beust.jcommander.args.ArgsBooleanArity0; 27import com.beust.jcommander.args.ArgsConverter; 28import com.beust.jcommander.args.ArgsEnum; 29import com.beust.jcommander.args.ArgsEquals; 30import com.beust.jcommander.args.ArgsHelp; 31import com.beust.jcommander.args.ArgsI18N1; 32import com.beust.jcommander.args.ArgsI18N2; 33import com.beust.jcommander.args.ArgsI18N2New; 34import com.beust.jcommander.args.ArgsInherited; 35import com.beust.jcommander.args.ArgsList; 36import com.beust.jcommander.args.ArgsMainParameter1; 37import com.beust.jcommander.args.ArgsMaster; 38import com.beust.jcommander.args.ArgsMultipleUnparsed; 39import com.beust.jcommander.args.ArgsOutOfMemory; 40import com.beust.jcommander.args.ArgsPrivate; 41import com.beust.jcommander.args.ArgsRequired; 42import com.beust.jcommander.args.ArgsSlave; 43import com.beust.jcommander.args.ArgsSlaveBogus; 44import com.beust.jcommander.args.ArgsValidate1; 45import com.beust.jcommander.args.ArgsWithSet; 46import com.beust.jcommander.args.Arity1; 47import com.beust.jcommander.args.SeparatorColon; 48import com.beust.jcommander.args.SeparatorEqual; 49import com.beust.jcommander.args.SeparatorMixed; 50import com.beust.jcommander.args.SlashSeparator; 51import com.beust.jcommander.args.VariableArity; 52import com.beust.jcommander.command.CommandAdd; 53import com.beust.jcommander.command.CommandCommit; 54import com.beust.jcommander.command.CommandMain; 55 56import org.testng.Assert; 57import org.testng.annotations.DataProvider; 58import org.testng.annotations.Test; 59import org.testng.collections.Lists; 60import org.testng.collections.Maps; 61 62import java.io.ByteArrayInputStream; 63import java.io.File; 64import java.io.FileWriter; 65import java.io.IOException; 66import java.io.InputStream; 67import java.math.BigDecimal; 68import java.text.ParseException; 69import java.text.SimpleDateFormat; 70import java.util.ArrayList; 71import java.util.Arrays; 72import java.util.EnumSet; 73import java.util.Iterator; 74import java.util.List; 75import java.util.Locale; 76import java.util.Map; 77import java.util.ResourceBundle; 78import java.util.TreeSet; 79 80@Test 81public class JCommanderTest { 82 public void simpleArgs() throws ParseException { 83 Args1 args = new Args1(); 84 String[] argv = { "-debug", "-log", "2", "-float", "1.2", "-double", "1.3", "-bigdecimal", "1.4", 85 "-date", "2011-10-26", "-groups", "unit", "a", "b", "c" }; 86 new JCommander(args, argv); 87 88 Assert.assertTrue(args.debug); 89 Assert.assertEquals(args.verbose.intValue(), 2); 90 Assert.assertEquals(args.groups, "unit"); 91 Assert.assertEquals(args.parameters, Arrays.asList("a", "b", "c")); 92 Assert.assertEquals(args.floa, 1.2f, 0.1f); 93 Assert.assertEquals(args.doub, 1.3f, 0.1f); 94 Assert.assertEquals(args.bigd, new BigDecimal("1.4")); 95 Assert.assertEquals(args.date, new SimpleDateFormat("yyyy-MM-dd").parse("2011-10-26")); 96 } 97 98 /** 99 * Make sure that if there are args with multiple names (e.g. "-log" and "-verbose"), 100 * the usage will only display it once. 101 */ 102 public void repeatedArgs() { 103 Args1 args = new Args1(); 104 String[] argv = { "-log", "2" }; 105 JCommander jc = new JCommander(args, argv); 106 Assert.assertEquals(jc.getParameters().size(), 8); 107 } 108 109 /** 110 * Not specifying a required option should throw an exception. 111 */ 112 @Test(expectedExceptions = ParameterException.class) 113 public void requiredFields1Fail() { 114 Args1 args = new Args1(); 115 String[] argv = { "-debug" }; 116 new JCommander(args, argv); 117 } 118 119 /** 120 * Getting the description of a nonexistent command should throw an exception. 121 */ 122 @Test(expectedExceptions = ParameterException.class) 123 public void nonexistentCommandShouldThrow() { 124 String[] argv = { }; 125 JCommander jc = new JCommander(new Object(), argv); 126 jc.getCommandDescription("foo"); 127 } 128 129 /** 130 * Required options with multiple names should work with all names. 131 */ 132 private void multipleNames(String option) { 133 Args1 args = new Args1(); 134 String[] argv = { option, "2" }; 135 new JCommander(args, argv); 136 Assert.assertEquals(args.verbose.intValue(), 2); 137 } 138 139 public void multipleNames1() { 140 multipleNames("-log"); 141 } 142 143 public void multipleNames2() { 144 multipleNames("-verbose"); 145 } 146 147 private void i18n1(String bundleName, Locale locale, String expectedString) { 148 ResourceBundle bundle = locale != null ? ResourceBundle.getBundle(bundleName, locale) 149 : null; 150 151 ArgsI18N1 i18n = new ArgsI18N1(); 152 String[] argv = { "-host", "localhost" }; 153 JCommander jc = new JCommander(i18n, bundle, argv); 154// jc.usage(); 155 156 ParameterDescription pd = jc.getParameters().get(0); 157 Assert.assertEquals(pd.getDescription(), expectedString); 158 } 159 160 public void i18nNoLocale() { 161 i18n1("MessageBundle", null, "Host"); 162 } 163 164 public void i18nUsLocale() { 165 i18n1("MessageBundle", new Locale("en", "US"), "Host"); 166 } 167 168 public void i18nFrLocale() { 169 i18n1("MessageBundle", new Locale("fr", "FR"), "Hôte"); 170 } 171 172 private void i18n2(Object i18n) { 173 String[] argv = { "-host", "localhost" }; 174 Locale.setDefault(new Locale("fr", "FR")); 175 JCommander jc = new JCommander(i18n, argv); 176 ParameterDescription pd = jc.getParameters().get(0); 177 Assert.assertEquals(pd.getDescription(), "Hôte"); 178 } 179 180 public void i18nWithResourceAnnotation() { 181 i18n2(new ArgsI18N2()); 182 } 183 184 public void i18nWithResourceAnnotationNew() { 185 i18n2(new ArgsI18N2New()); 186 } 187 188 public void noParseConstructor() { 189 JCommander jCommander = new JCommander(new ArgsMainParameter1()); 190 jCommander.usage(new StringBuilder()); 191 // Before fix, this parse would throw an exception, because it calls createDescription, which 192 // was already called by usage(), and can only be called once. 193 jCommander.parse(); 194 } 195 196 /** 197 * Test a use case where there are required parameters, but you still want 198 * to interrogate the options which are specified. 199 */ 200 public void usageWithRequiredArgsAndResourceBundle() { 201 ArgsHelp argsHelp = new ArgsHelp(); 202 JCommander jc = new JCommander(new Object[]{argsHelp, new ArgsRequired()}, 203 java.util.ResourceBundle.getBundle("MessageBundle")); 204 // Should be able to display usage without triggering validation 205 jc.usage(new StringBuilder()); 206 try { 207 jc.parse("-h"); 208 Assert.fail("Should have thrown a required parameter exception"); 209 } catch (ParameterException e) { 210 Assert.assertTrue(e.getMessage().contains("are required")); 211 } 212 Assert.assertTrue(argsHelp.help); 213 } 214 215 public void multiObjects() { 216 ArgsMaster m = new ArgsMaster(); 217 ArgsSlave s = new ArgsSlave(); 218 String[] argv = { "-master", "master", "-slave", "slave" }; 219 new JCommander(new Object[] { m , s }, argv); 220 221 Assert.assertEquals(m.master, "master"); 222 Assert.assertEquals(s.slave, "slave"); 223 } 224 225 @Test(expectedExceptions = ParameterException.class) 226 public void multiObjectsWithDuplicatesFail() { 227 ArgsMaster m = new ArgsMaster(); 228 ArgsSlave s = new ArgsSlaveBogus(); 229 String[] argv = { "-master", "master", "-slave", "slave" }; 230 new JCommander(new Object[] { m , s }, argv); 231 } 232 233 public void arityString() { 234 ArgsArityString args = new ArgsArityString(); 235 String[] argv = { "-pairs", "pair0", "pair1", "rest" }; 236 new JCommander(args, argv); 237 238 Assert.assertEquals(args.pairs.size(), 2); 239 Assert.assertEquals(args.pairs.get(0), "pair0"); 240 Assert.assertEquals(args.pairs.get(1), "pair1"); 241 Assert.assertEquals(args.rest.size(), 1); 242 Assert.assertEquals(args.rest.get(0), "rest"); 243 } 244 245 @Test(expectedExceptions = ParameterException.class) 246 public void arity2Fail() { 247 ArgsArityString args = new ArgsArityString(); 248 String[] argv = { "-pairs", "pair0" }; 249 new JCommander(args, argv); 250 } 251 252 @Test(expectedExceptions = ParameterException.class) 253 public void multipleUnparsedFail() { 254 ArgsMultipleUnparsed args = new ArgsMultipleUnparsed(); 255 String[] argv = { }; 256 new JCommander(args, argv); 257 } 258 259 public void privateArgs() { 260 ArgsPrivate args = new ArgsPrivate(); 261 new JCommander(args, "-verbose", "3"); 262 Assert.assertEquals(args.getVerbose().intValue(), 3); 263 } 264 265 public void converterArgs() { 266 ArgsConverter args = new ArgsConverter(); 267 String fileName = "a"; 268 new JCommander(args, "-file", "/tmp/" + fileName, 269 "-listStrings", "Tuesday,Thursday", 270 "-listInts", "-1,8", 271 "-listBigDecimals", "-11.52,100.12"); 272 Assert.assertEquals(args.file.getName(), fileName); 273 Assert.assertEquals(args.listStrings.size(), 2); 274 Assert.assertEquals(args.listStrings.get(0), "Tuesday"); 275 Assert.assertEquals(args.listStrings.get(1), "Thursday"); 276 Assert.assertEquals(args.listInts.size(), 2); 277 Assert.assertEquals(args.listInts.get(0).intValue(), -1); 278 Assert.assertEquals(args.listInts.get(1).intValue(), 8); 279 Assert.assertEquals(args.listBigDecimals.size(), 2); 280 Assert.assertEquals(args.listBigDecimals.get(0), new BigDecimal("-11.52")); 281 Assert.assertEquals(args.listBigDecimals.get(1), new BigDecimal("100.12")); 282 } 283 284 private void argsBoolean1(String[] params, Boolean expected) { 285 ArgsBooleanArity args = new ArgsBooleanArity(); 286 new JCommander(args, params); 287 Assert.assertEquals(args.debug, expected); 288 } 289 290 private void argsBoolean0(String[] params, Boolean expected) { 291 ArgsBooleanArity0 args = new ArgsBooleanArity0(); 292 new JCommander(args, params); 293 Assert.assertEquals(args.debug, expected); 294 } 295 296 public void booleanArity1() { 297 argsBoolean1(new String[] {}, Boolean.FALSE); 298 argsBoolean1(new String[] { "-debug", "true" }, Boolean.TRUE); 299 } 300 301 public void booleanArity0() { 302 argsBoolean0(new String[] {}, Boolean.FALSE); 303 argsBoolean0(new String[] { "-debug"}, Boolean.TRUE); 304 } 305 306 @Test(expectedExceptions = ParameterException.class) 307 public void badParameterShouldThrowParameter1Exception() { 308 Args1 args = new Args1(); 309 String[] argv = { "-log", "foo" }; 310 new JCommander(args, argv); 311 } 312 313 @Test(expectedExceptions = ParameterException.class) 314 public void badParameterShouldThrowParameter2Exception() { 315 Args1 args = new Args1(); 316 String[] argv = { "-long", "foo" }; 317 new JCommander(args, argv); 318 } 319 320 public void listParameters() { 321 Args2 a = new Args2(); 322 String[] argv = {"-log", "2", "-groups", "unit", "a", "b", "c", "-host", "host2"}; 323 new JCommander(a, argv); 324 Assert.assertEquals(a.verbose.intValue(), 2); 325 Assert.assertEquals(a.groups, "unit"); 326 Assert.assertEquals(a.hosts, Arrays.asList("host2")); 327 Assert.assertEquals(a.parameters, Arrays.asList("a", "b", "c")); 328 } 329 330 public void separatorEqual() { 331 SeparatorEqual s = new SeparatorEqual(); 332 String[] argv = { "-log=3", "--longoption=10" }; 333 new JCommander(s, argv); 334 Assert.assertEquals(s.log.intValue(), 3); 335 Assert.assertEquals(s.longOption.intValue(), 10); 336 } 337 338 public void separatorColon() { 339 SeparatorColon s = new SeparatorColon(); 340 String[] argv = { "-verbose:true" }; 341 new JCommander(s, argv); 342 Assert.assertTrue(s.verbose); 343 } 344 345 public void separatorBoth() { 346 SeparatorColon s = new SeparatorColon(); 347 SeparatorEqual s2 = new SeparatorEqual(); 348 String[] argv = { "-verbose:true", "-log=3" }; 349 new JCommander(new Object[] { s, s2 }, argv); 350 Assert.assertTrue(s.verbose); 351 Assert.assertEquals(s2.log.intValue(), 3); 352 } 353 354 public void separatorMixed1() { 355 SeparatorMixed s = new SeparatorMixed(); 356 String[] argv = { "-long:1", "-level=42" }; 357 new JCommander(s, argv); 358 Assert.assertEquals(s.l.longValue(), 1l); 359 Assert.assertEquals(s.level.intValue(), 42); 360 } 361 362 public void slashParameters() { 363 SlashSeparator a = new SlashSeparator(); 364 String[] argv = { "/verbose", "/file", "/tmp/a" }; 365 new JCommander(a, argv); 366 Assert.assertTrue(a.verbose); 367 Assert.assertEquals(a.file, "/tmp/a"); 368 } 369 370 public void inheritance() { 371 ArgsInherited args = new ArgsInherited(); 372 String[] argv = { "-log", "3", "-child", "2" }; 373 new JCommander(args, argv); 374 Assert.assertEquals(args.child.intValue(), 2); 375 Assert.assertEquals(args.log.intValue(), 3); 376 } 377 378 public void negativeNumber() { 379 Args1 a = new Args1(); 380 String[] argv = { "-verbose", "-3" }; 381 new JCommander(a, argv); 382 Assert.assertEquals(a.verbose.intValue(), -3); 383 } 384 385 @Test(expectedExceptions = ParameterException.class) 386 public void requiredMainParameters() { 387 ArgsRequired a = new ArgsRequired(); 388 String[] argv = {}; 389 new JCommander(a, argv); 390 } 391 392 public void usageShouldNotChange() { 393 JCommander jc = new JCommander(new Args1(), new String[]{"-log", "1"}); 394 StringBuilder sb = new StringBuilder(); 395 jc.usage(sb); 396 String expected = sb.toString(); 397 jc = new JCommander(new Args1(), new String[]{"-debug", "-log", "2", "-long", "5"}); 398 sb = new StringBuilder(); 399 jc.usage(sb); 400 String actual = sb.toString(); 401 Assert.assertEquals(actual, expected); 402 } 403 404 private void verifyCommandOrdering(String[] commandNames, Object[] commands) { 405 CommandMain cm = new CommandMain(); 406 JCommander jc = new JCommander(cm); 407 408 for (int i = 0; i < commands.length; i++) { 409 jc.addCommand(commandNames[i], commands[i]); 410 } 411 412 Map<String, JCommander> c = jc.getCommands(); 413 Assert.assertEquals(c.size(), commands.length); 414 415 Iterator<String> it = c.keySet().iterator(); 416 for (int i = 0; i < commands.length; i++) { 417 Assert.assertEquals(it.next(), commandNames[i]); 418 } 419 } 420 421 public void commandsShouldBeShownInOrderOfInsertion() { 422 verifyCommandOrdering(new String[] { "add", "commit" }, 423 new Object[] { new CommandAdd(), new CommandCommit() }); 424 verifyCommandOrdering(new String[] { "commit", "add" }, 425 new Object[] { new CommandCommit(), new CommandAdd() }); 426 } 427 428 @DataProvider 429 public static Object[][] f() { 430 return new Integer[][] { 431 new Integer[] { 3, 5, 1 }, 432 new Integer[] { 3, 8, 1 }, 433 new Integer[] { 3, 12, 2 }, 434 new Integer[] { 8, 12, 2 }, 435 new Integer[] { 9, 10, 1 }, 436 }; 437 } 438 439 @Test(expectedExceptions = ParameterException.class) 440 public void arity1Fail() { 441 final Arity1 arguments = new Arity1(); 442 final JCommander jCommander = new JCommander(arguments); 443 final String[] commands = { 444 "-inspect" 445 }; 446 jCommander.parse(commands); 447 } 448 449 public void arity1Success1() { 450 final Arity1 arguments = new Arity1(); 451 final JCommander jCommander = new JCommander(arguments); 452 final String[] commands = { 453 "-inspect", "true" 454 }; 455 jCommander.parse(commands); 456 Assert.assertTrue(arguments.inspect); 457 } 458 459 public void arity1Success2() { 460 final Arity1 arguments = new Arity1(); 461 final JCommander jCommander = new JCommander(arguments); 462 final String[] commands = { 463 "-inspect", "false" 464 }; 465 jCommander.parse(commands); 466 Assert.assertFalse(arguments.inspect); 467 } 468 469 @Parameters(commandDescription = "Help for the given commands.") 470 public static class Help { 471 public static final String NAME = "help"; 472 473 @Parameter(description = "List of commands.") 474 public List<String> commands=new ArrayList<String>(); 475 } 476 477 @Test(expectedExceptions = ParameterException.class, 478 description = "Verify that the main parameter's type is checked to be a List") 479 public void wrongMainTypeShouldThrow() { 480 JCommander jc = new JCommander(new ArgsRequiredWrongMain()); 481 jc.parse(new String[] { "f1", "f2" }); 482 } 483 484 @Test(description = "This used to run out of memory") 485 public void oom() { 486 JCommander jc = new JCommander(new ArgsOutOfMemory()); 487 jc.usage(new StringBuilder()); 488 } 489 490 @Test 491 public void getParametersShouldNotNpe() { 492 JCommander jc = new JCommander(new Args1()); 493 List<ParameterDescription> parameters = jc.getParameters(); 494 } 495 496 public void validationShouldWork1() { 497 ArgsValidate1 a = new ArgsValidate1(); 498 JCommander jc = new JCommander(a); 499 jc.parse(new String[] { "-age", "2 "}); 500 Assert.assertEquals(a.age, new Integer(2)); 501 } 502 503 @Test(expectedExceptions = ParameterException.class) 504 public void validationShouldWorkWithDefaultValues() { 505 ArgsValidate2 a = new ArgsValidate2(); 506 new JCommander(a); 507 } 508 509 @Test(expectedExceptions = ParameterException.class) 510 public void validationShouldWork2() { 511 ArgsValidate1 a = new ArgsValidate1(); 512 JCommander jc = new JCommander(a); 513 jc.parse(new String[] { "-age", "-2 "}); 514 } 515 516 public void atFileCanContainEmptyLines() throws IOException { 517 File f = File.createTempFile("JCommander", null); 518 f.deleteOnExit(); 519 FileWriter fw = new FileWriter(f); 520 fw.write("-log\n"); 521 fw.write("\n"); 522 fw.write("2\n"); 523 fw.close(); 524 new JCommander(new Args1(), "@" + f.getAbsolutePath()); 525 } 526 527 public void handleEqualSigns() { 528 ArgsEquals a = new ArgsEquals(); 529 JCommander jc = new JCommander(a); 530 jc.parse(new String[] { "-args=a=b,b=c" }); 531 Assert.assertEquals(a.args, "a=b,b=c"); 532 } 533 534 @SuppressWarnings("serial") 535 public void handleSets() { 536 ArgsWithSet a = new ArgsWithSet(); 537 new JCommander(a, new String[] { "-s", "3,1,2" }); 538 Assert.assertEquals(a.set, new TreeSet<Integer>() {{ add(1); add(2); add(3); }}); 539 } 540 541 private static final List<String> V = Arrays.asList("a", "b", "c", "d"); 542 543 @DataProvider 544 public Object[][] variable() { 545 return new Object[][] { 546 new Object[] { 0, V.subList(0, 0), V }, 547 new Object[] { 1, V.subList(0, 1), V.subList(1, 4) }, 548 new Object[] { 2, V.subList(0, 2), V.subList(2, 4) }, 549 new Object[] { 3, V.subList(0, 3), V.subList(3, 4) }, 550 new Object[] { 4, V.subList(0, 4), V.subList(4, 4) }, 551 }; 552 } 553 554 @Test(dataProvider = "variable") 555 public void variableArity(int count, List<String> var, List<String> main) { 556 VariableArity va = new VariableArity(count); 557 new JCommander(va).parse("-variable", "a", "b", "c", "d"); 558 Assert.assertEquals(var, va.var); 559 Assert.assertEquals(main, va.main); 560 } 561 562 public void enumArgs() { 563 ArgsEnum args = new ArgsEnum(); 564 String[] argv = { "-choice", "ONE"}; 565 JCommander jc = new JCommander(args, argv); 566 567 Assert.assertEquals(args.choice, ArgsEnum.ChoiceType.ONE); 568 569 Assert.assertEquals(jc.getParameters().get(0).getDescription(), 570 "Options: " + EnumSet.allOf((Class<? extends Enum>) ArgsEnum.ChoiceType.class)); 571 572 } 573 574 @Test(expectedExceptions = ParameterException.class) 575 public void enumArgsFail() { 576 ArgsEnum args = new ArgsEnum(); 577 String[] argv = { "-choice", "A" }; 578 new JCommander(args, argv); 579 } 580 581 public void testListAndSplitters() { 582 ArgsList al = new ArgsList(); 583 JCommander j = new JCommander(al); 584 j.parse("-groups", "a,b", "-ints", "41,42", "-hp", "localhost:1000;example.com:1001", 585 "-hp2", "localhost:1000,example.com:1001", "-uppercase", "ab,cd"); 586 Assert.assertEquals(al.groups.get(0), "a"); 587 Assert.assertEquals(al.groups.get(1), "b"); 588 Assert.assertEquals(al.ints.get(0).intValue(), 41); 589 Assert.assertEquals(al.ints.get(1).intValue(), 42); 590 Assert.assertEquals(al.hostPorts.get(0).host, "localhost"); 591 Assert.assertEquals(al.hostPorts.get(0).port.intValue(), 1000); 592 Assert.assertEquals(al.hostPorts.get(1).host, "example.com"); 593 Assert.assertEquals(al.hostPorts.get(1).port.intValue(), 1001); 594 Assert.assertEquals(al.hp2.get(1).host, "example.com"); 595 Assert.assertEquals(al.hp2.get(1).port.intValue(), 1001); 596 Assert.assertEquals(al.uppercase.get(0), "AB"); 597 Assert.assertEquals(al.uppercase.get(1), "CD"); 598 } 599 600 @Test(expectedExceptions = ParameterException.class) 601 public void shouldThrowIfUnknownOption() { 602 class A { 603 @Parameter(names = "-long") 604 public long l; 605 } 606 A a = new A(); 607 new JCommander(a).parse("-lon", "32"); 608 } 609 610 @Test(expectedExceptions = ParameterException.class) 611 public void mainParameterShouldBeValidate() { 612 class V implements IParameterValidator { 613 614 @Override 615 public void validate(String name, String value) throws ParameterException { 616 Assert.assertEquals("a", value); 617 } 618 } 619 620 class A { 621 @Parameter(validateWith = V.class) 622 public List<String> m; 623 } 624 625 A a = new A(); 626 new JCommander(a).parse("b"); 627 } 628 629 @Parameters(commandNames = { "--configure" }) 630 public static class ConfigureArgs { 631 } 632 633 public static class BaseArgs { 634 @Parameter(names = { "-h", "--help" }, description = "Show this help screen") 635 private boolean help = false; 636 637 @Parameter(names = { "--version", "-version" }, description = "Show the program version") 638 private boolean version; 639 } 640 641 public void commandsWithSamePrefixAsOptionsShouldWork() { 642 BaseArgs a = new BaseArgs(); 643 ConfigureArgs conf = new ConfigureArgs(); 644 JCommander jc = new JCommander(a); 645 jc.addCommand(conf); 646 jc.parse("--configure"); 647 } 648 649 // Tests: 650 // required unparsed parameter 651 @Test(enabled = false, 652 description = "For some reason, this test still asks the password on stdin") 653 public void askedRequiredPassword() { 654 class A { 655 @Parameter(names = { "--password", "-p" }, description = "Private key password", 656 password = true, required = true) 657 public String password; 658 659 @Parameter(names = { "--port", "-o" }, description = "Port to bind server to", 660 required = true) 661 public int port; 662 } 663 A a = new A(); 664 InputStream stdin = System.in; 665 try { 666 System.setIn(new ByteArrayInputStream("password".getBytes())); 667 new JCommander(a,new String[]{"--port", "7","--password"}); 668 Assert.assertEquals(a.port, 7); 669 Assert.assertEquals(a.password, "password"); 670 } finally { 671 System.setIn(stdin); 672 } 673 } 674 675 public void dynamicParameters() { 676 class Command { 677 @DynamicParameter(names = {"-P"}, description = "Additional command parameters") 678 private Map<String, String> params = Maps.newHashMap(); 679 } 680 JCommander commander = new JCommander(); 681 Command c = new Command(); 682 commander.addCommand("command", c); 683 commander.parse(new String[] { "command", "-Pparam='name=value'" }); 684 Assert.assertEquals(c.params.get("param"), "'name=value'"); 685 } 686 687 public void exeParser() { 688 class Params { 689 @Parameter( names= "-i") 690 private String inputFile; 691 } 692 693 String args[] = { "-i", "" }; 694 Params p = new Params(); 695 new JCommander(p, args); 696 } 697 698 public void multiVariableArityList() { 699 class Params { 700 @Parameter(names = "-paramA", description = "ParamA", variableArity = true) 701 private List<String> paramA = Lists.newArrayList(); 702 703 @Parameter(names = "-paramB", description = "ParamB", variableArity = true) 704 private List<String> paramB = Lists.newArrayList(); 705 } 706 707 { 708 String args[] = { "-paramA", "a1", "a2", "-paramB", "b1", "b2", "b3" }; 709 Params p = new Params(); 710 new JCommander(p, args).parse(); 711 Assert.assertEquals(p.paramA, Arrays.asList(new String[] { "a1", "a2" })); 712 Assert.assertEquals(p.paramB, Arrays.asList(new String[] { "b1", "b2", "b3" })); 713 } 714 715 { 716 String args[] = { "-paramA", "a1", "a2", "-paramB", "b1", "-paramA", "a3" }; 717 Params p = new Params(); 718 new JCommander(p, args).parse(); 719 Assert.assertEquals(p.paramA, Arrays.asList(new String[] { "a1", "a2", "a3" })); 720 Assert.assertEquals(p.paramB, Arrays.asList(new String[] { "b1" })); 721 } 722 } 723 724 @Test(enabled = false, 725 description = "Need to double check that the command description is i18n'ed in the usage") 726 public void commandKey() { 727 @Parameters(resourceBundle = "MessageBundle", commandDescriptionKey = "command") 728 class Args { 729 @Parameter(names="-myoption", descriptionKey="myoption") 730 private boolean option; 731 } 732 JCommander j = new JCommander(); 733 Args a = new Args(); 734 j.addCommand("comm", a); 735 j.usage(); 736 } 737 738 public void tmp() { 739 class A { 740 @Parameter(names = "-b") 741 public String b; 742 } 743 new JCommander(new A()).parse(""); 744 } 745 746 public void unknownOptionWithDifferentPrefix() { 747 @Parameters(optionPrefixes = "/") 748 class SlashSeparator { 749 750 @Parameter(names = "/verbose") 751 public boolean verbose = false; 752 753 @Parameter(names = "/file") 754 public String file; 755 } 756 SlashSeparator ss = new SlashSeparator(); 757 try { 758 new JCommander(ss).parse("/notAParam"); 759 } catch (ParameterException ex) { 760 boolean result = ex.getMessage().contains("Unknown option"); 761 Assert.assertTrue(result); 762 } 763 } 764 765 public void equalSeparator() { 766 @Parameters(separators = "=", commandDescription = "My command") 767 class MyClass { 768 769 @Parameter(names = { "-p", "--param" }, required = true, description = "param desc...") 770 private String param; 771 } 772 MyClass c = new MyClass(); 773 String expected = "\"hello\"world"; 774 new JCommander(c).parse("--param=" + expected); 775 Assert.assertEquals(expected, c.param); 776 } 777 778 public void simpleArgsSetter() throws ParseException { 779 Args1Setter args = new Args1Setter(); 780 String[] argv = { "-debug", "-log", "2", "-float", "1.2", "-double", "1.3", "-bigdecimal", "1.4", 781 "-date", "2011-10-26", "-groups", "unit", "a", "b", "c" }; 782 new JCommander(args, argv); 783 784 Assert.assertTrue(args.debug); 785 Assert.assertEquals(args.verbose.intValue(), 2); 786 Assert.assertEquals(args.groups, "unit"); 787 Assert.assertEquals(args.parameters, Arrays.asList("a", "b", "c")); 788 Assert.assertEquals(args.floa, 1.2f, 0.1f); 789 Assert.assertEquals(args.doub, 1.3f, 0.1f); 790 Assert.assertEquals(args.bigd, new BigDecimal("1.4")); 791 Assert.assertEquals(args.date, new SimpleDateFormat("yyyy-MM-dd").parse("2011-10-26")); 792 } 793 794 public void verifyHelp() { 795 class Arg { 796 @Parameter(names = "--help", help = true) 797 public boolean help = false; 798 799 @Parameter(names = "file", required = true) 800 public String file; 801 } 802 Arg arg = new Arg(); 803 String[] argv = { "--help" }; 804 new JCommander(arg, argv); 805 806 Assert.assertTrue(arg.help); 807 } 808 809 public void helpTest() { 810 class Arg { 811 @Parameter(names = { "?", "-help", "--help" }, description = "Shows help", help = true) 812 private boolean help = false; 813 } 814 Arg arg = new Arg(); 815 JCommander jc = new JCommander(arg); 816 jc.parse(new String[] { "-help" }); 817// System.out.println("helpTest:" + arg.help); 818 } 819 820 @Test(enabled = false, description = "Should only be enable once multiple parameters are allowed") 821 public void duplicateParameterNames() { 822 class ArgBase { 823 @Parameter(names = { "-host" }) 824 protected String host; 825 } 826 827 class Arg1 extends ArgBase {} 828 Arg1 arg1 = new Arg1(); 829 830 class Arg2 extends ArgBase {} 831 Arg2 arg2 = new Arg2(); 832 833 JCommander jc = new JCommander(new Object[] { arg1, arg2}); 834 jc.parse(new String[] { "-host", "foo" }); 835 Assert.assertEquals(arg1.host, "foo"); 836 Assert.assertEquals(arg2.host, "foo"); 837 } 838 839 public void parameterWithOneDoubleQuote() { 840 @Parameters(separators = "=") 841 class Arg { 842 843 @Parameter(names = { "-p", "--param" }) 844 private String param; 845 } 846 847 JCommander jc = new JCommander(new MyClass()); 848 jc.parse("-p=\""); 849 } 850 851 public void emptyStringAsDefault() { 852 class Arg { 853 @Parameter(names = "-x") 854 String s = ""; 855 } 856 Arg a = new Arg(); 857 StringBuilder sb = new StringBuilder(); 858 new JCommander(a).usage(sb); 859 Assert.assertTrue(sb.toString().contains("Default: <empty string>")); 860 } 861 862 public void spaces() { 863 class Arg { 864 @Parameter(names = "-rule", description = "rule") 865 private List<String> rules = new ArrayList<String>(); 866 } 867 Arg a = new Arg(); 868 StringBuilder sb = new StringBuilder(); 869 new JCommander(a, "-rule", "some test"); 870 Assert.assertEquals(a.rules, Arrays.asList("some test")); 871 } 872 873 @Test(enabled = false) 874 public static void main(String[] args) throws Exception { 875 new JCommanderTest().spaces(); 876// class A { 877// @Parameter(names = "-short", required = true) 878// List<String> parameters; 879// 880// @Parameter(names = "-long", required = true) 881// public long l; 882// } 883// A a = new A(); 884// new JCommander(a).parse(); 885// System.out.println(a.l); 886// System.out.println(a.parameters); 887// ArgsList al = new ArgsList(); 888// JCommander j = new JCommander(al); 889// j.setColumnSize(40); 890// j.usage(); 891// new JCommanderTest().testListAndSplitters(); 892// new JCommanderTest().converterArgs(); 893 } 894 895 // Tests: 896 // required unparsed parameter 897} 898