private void addHierarchy(CommandLine cmd, TextTable textTable, String indent) { // create comma-separated list of command name and aliases String names = cmd.getCommandSpec().names().toString(); names = names.substring(1, names.length() - 1); // remove leading '[' and trailing ']' // command description is taken from header or description String description = description(cmd.getCommandSpec().usageMessage()); // add a line for this command to the layout textTable.addRowValues(indent + names, description); // add its subcommands (if any) for (CommandLine sub : cmd.getSubcommands().values()) { addHierarchy(sub, textTable, indent + " "); } }
@Test public void testCommandAliasRegistrationByAnnotation() { CommandLine commandLine = new CommandLine(new TopLevelCommand()); assertEquals(setOf("sub", "s", "sb", "sub2", "s2", "sb2"), commandLine.getSubcommands().keySet()); CommandLine sub1 = commandLine.getSubcommands().get("sub"); assertEquals(setOf("subsub", "ss", "sbsb"), sub1.getSubcommands().keySet()); CommandLine sub2 = commandLine.getSubcommands().get("sub2"); assertEquals(setOf("subsub", "ss", "sbsb"), sub2.getSubcommands().keySet()); }
@Test public void testDeclarativelyAddSubcommands() { CommandLine main = new CommandLine(new MainCommand_testDeclarativelyAddSubcommands()); assertEquals(1, main.getSubcommands().size()); CommandLine sub1 = main.getSubcommands().get("sub1"); assertEquals(Sub1_testDeclarativelyAddSubcommands.class, sub1.getCommand().getClass()); assertEquals(1, sub1.getSubcommands().size()); CommandLine subsub1 = sub1.getSubcommands().get("subsub1"); assertEquals(SubSub1_testDeclarativelyAddSubcommands.class, subsub1.getCommand().getClass()); } @Test
@Test public void testDeclarativelyAddSubcommandsSucceedsWithDefaultConstructorForDefaultFactory() { @Command(subcommands = {SubSub1_testDeclarativelyAddSubcommands.class}) class MainCommand {} CommandLine cmdLine = new CommandLine(new MainCommand()); assertEquals(SubSub1_testDeclarativelyAddSubcommands.class.getName(), cmdLine.getSubcommands().get("subsub1").getCommand().getClass().getName()); } @Test
@Test public void testCommandMethodsFromSuperclassAddedToSubcommands() throws Exception { CommandLine cmd = new CommandLine(MethodApp.class); assertEquals("method", cmd.getCommandName()); assertEquals(3, cmd.getSubcommands().size()); assertEquals(0, cmd.getSubcommands().get("run-0").getCommandSpec().args().size()); assertEquals(1, cmd.getSubcommands().get("run-1").getCommandSpec().args().size()); assertEquals(2, cmd.getSubcommands().get("run-2").getCommandSpec().args().size()); //CommandLine.usage(cmd.getSubcommands().get("run-2"), System.out); }
@Test public void testGetParentForProgrammaticallyAddedSubcommands() { CommandLine main = createNestedCommand(); for (CommandLine child : main.getSubcommands().values()) { assertSame(main, child.getParent()); for (CommandLine grandChild : child.getSubcommands().values()) { assertSame(child, grandChild.getParent()); } } }
@Test public void testGetParentForDeclarativelyAddedSubcommands() { CommandLine main = new CommandLine(new MainCommand_testDeclarativelyAddSubcommands()); assertEquals(1, main.getSubcommands().size()); CommandLine sub1 = main.getSubcommands().get("sub1"); assertSame(main, sub1.getParent()); assertEquals(Sub1_testDeclarativelyAddSubcommands.class, sub1.getCommand().getClass()); assertEquals(1, sub1.getSubcommands().size()); CommandLine subsub1 = sub1.getSubcommands().get("subsub1"); assertSame(sub1, subsub1.getParent()); assertEquals(SubSub1_testDeclarativelyAddSubcommands.class, subsub1.getCommand().getClass()); } @Test
@Test public void testDeclarativelyAddSubcommandsSucceedsWithDefaultConstructor() { @Command(name = "sub1") class ABCD {} @Command(subcommands = {ABCD.class}) class MainCommand {} CommandLine cmdLine = new CommandLine(new MainCommand(), new InnerClassFactory(this)); assertEquals("picocli.SubcommandTests$1ABCD", cmdLine.getSubcommands().get("sub1").getCommand().getClass().getName()); } @Test
@Test public void testCommandListReturnsOnlyCommandsRegisteredOnInstance() { CommandLine commandLine = createNestedCommand(); Map<String, CommandLine> commandMap = commandLine.getSubcommands(); assertEquals(2, commandMap.size()); assertTrue("cmd1", commandMap.get("cmd1").getCommand() instanceof ChildCommand1); assertTrue("cmd2", commandMap.get("cmd2").getCommand() instanceof ChildCommand2); }
@Test public void testCommandAliasAnnotationSubcommandUsageHelp() { CommandLine commandLine = new CommandLine(new TopLevelCommand()); ByteArrayOutputStream baos = new ByteArrayOutputStream(); commandLine.getSubcommands().get("sub").usage(new PrintStream(baos), CommandLine.Help.defaultColorScheme(Help.Ansi.ON).commands(Help.Ansi.Style.underline)); // add underline String expected = Help.Ansi.ON.new Text(String.format("" + "Usage: @|bold,underline top sub|@ [COMMAND]%n" + "I'm subcommand No. 1!%n" + "Commands:%n" + " @|bold,underline subsub|@, @|bold,underline ss|@, @|bold,underline sbsb|@ I'm like a 3rd rate command but great bang for your buck%n")).toString(); assertEquals(expected, baos.toString()); } }
@Test public void testMethodCommandsAreNotAddedAsSubcommandsIfAnnotationSaysSo() { CommandLine cmd = new CommandLine(new SwitchedOff()); assertEquals(0, cmd.getSubcommands().size()); String expected = String.format("" + "Usage: <main class>%n"); assertEquals(expected, cmd.getUsageMessage()); }
@Test public void testMethodCommandsAreSubcommandsOfAnnotatedClass() { CommandLine cmd = new CommandLine(new AnnotatedClassWithoutAnnotatedFields()); assertNull(cmd.getCommandSpec().findOption('x')); assertEquals(2, cmd.getSubcommands().size()); assertEquals(set("cmd1", "cmd2"), cmd.getSubcommands().keySet()); String expected = String.format("" + "Usage: <main class> [COMMAND]%n" + "Commands:%n" + " cmd1%n" + " cmd2%n"); assertEquals(expected, cmd.getUsageMessage()); }
@Test public void testParamIndexAnnotatedAndUnAnnotated() { CommandLine git = new CommandLine(new AnnotatedParams()); CommandLine method = git.getSubcommands().get("method"); List<Model.PositionalParamSpec> positionals = method.getCommandSpec().positionalParameters(); for (int i = 0; i < positionals.size(); i++) { assertEquals(CommandLine.Range.valueOf("" + i), positionals.get(i).index()); } }
@Test public void testCommandListReturnsRegisteredCommands() { @Command class MainCommand {} @Command class Command1 {} @Command class Command2 {} CommandLine commandLine = new CommandLine(new MainCommand()); commandLine.addSubcommand("cmd1", new Command1()).addSubcommand("cmd2", new Command2()); Map<String, CommandLine> commandMap = commandLine.getSubcommands(); assertEquals(2, commandMap.size()); assertTrue("cmd1", commandMap.get("cmd1").getCommand() instanceof Command1); assertTrue("cmd2", commandMap.get("cmd2").getCommand() instanceof Command2); }
@Test public void testCommandSpecQualifiedName_topLevelCommand() { CommandLine cmd = new CommandLine(new I18nCommand()); assertEquals("i18n-top", cmd.getCommandSpec().qualifiedName(".")); Map<String, CommandLine> subcommands = cmd.getSubcommands(); assertEquals("i18n-top.help", subcommands.get("help").getCommandSpec().qualifiedName(".")); CommandLine sub = subcommands.get("i18n-sub"); assertEquals("i18n-top.i18n-sub", sub.getCommandSpec().qualifiedName(".")); assertEquals("i18n-top.i18n-sub.help", sub.getSubcommands().get("help").getCommandSpec().qualifiedName(".")); }
@Test public void testParamIndex() { CommandLine git = new CommandLine(new Git()); CommandLine clone = git.getSubcommands().get("clone"); Model.PositionalParamSpec repo = clone.getCommandSpec().positionalParameters().get(0); assertEquals(CommandLine.Range.valueOf("0"), repo.index()); }
@Test public void testIssue444SubcommandWithDuplicateAliases() { Issue443TopLevelCommand top = new Issue443TopLevelCommand(); SubCommandWithAlias sub = new SubCommandWithAlias(); CommandLine cmd = new CommandLine(top).addSubcommand("task", sub, "t", "t"); CommandSpec subSpec = cmd.getSubcommands().get("task").getCommandSpec(); String expected = String.format("" + "Usage: cb [COMMAND]%n" + "Commands:%n" + " task, t subcommand with alias%n"); assertEquals(expected, cmd.getUsageMessage()); assertArrayEquals(new String[]{"t"}, subSpec.aliases()); }
@Test public void testDefaultProviderPropagatedToSubCommand() { CommandLine cmd = new CommandLine(App.class); cmd.addSubcommand("sub", new CommandLine(Sub.class)); CommandLine subCommandLine = cmd.getSubcommands().get("sub"); cmd.setDefaultValueProvider(new TestDefaultProvider()); assertNotNull(subCommandLine.getCommandSpec().defaultValueProvider()); assertEquals(TestDefaultProvider.class, subCommandLine.getCommandSpec().defaultValueProvider().getClass()); }
@Test public void testMethodCommandsAreNotSubcommandsOfNonAnnotatedClassWithAnnotatedFields() { CommandLine cmd = new CommandLine(new UnAnnotatedClassWithAnnotatedField()); assertNotNull(cmd.getCommandSpec().findOption('y')); assertTrue(cmd.getSubcommands().isEmpty()); assertNull(cmd.getCommandSpec().findOption('x')); }
@Test public void testSubcommandWithoutAnnotationName() { CommandLine top = new CommandLine(new Top563()); top.addSubcommand("subname", new Sub563()); CommandLine sub = top.getSubcommands().get("subname"); assertEquals("subname", sub.getCommandName()); assertEquals("subname", sub.getCommandSpec().name()); assertEquals("<main class> subname", sub.getCommandSpec().qualifiedName()); String expected = String.format("" + "Usage: <main class> subname [-hV]%n" + " -h, --help Show this help message and exit.%n" + " -V, --version Print version information and exit.%n"); sub.usage(System.out); assertEquals(expected, systemOutRule.getLog()); }