Text optionText = ansi().new Text(0); List<OptionSpec> options = new ArrayList<OptionSpec>(commandSpec.options()); // iterate in declaration order if (optionSort != null) { if (!option.hidden()) { Text name = colorScheme.optionText(option.shortestName()); Text param = parameterLabelRenderer().renderParameterLabel(option, colorScheme.ansi(), colorScheme.optionParamStyles); if (option.required()) { // e.g., -x=VAL optionText = optionText.concat(" ").concat(name).concat(param).concat("");
@Test public void testDefaultParameterRenderer_hideParamSyntax_on() { class App { @Parameters(index = "0") String single; @Parameters(index = "1", arity = "2") String[] multi; @Parameters(index = "2", hideParamSyntax = true) String singleHide; @Parameters(index = "3", hideParamSyntax = true, arity = "2") String[] multiHide; @Parameters(index = "4", hideParamSyntax = false, arity = "*", split = ",") String[] multiSplit; @Parameters(index = "5", hideParamSyntax = true, arity = "*", split = ",") String[] multiHideSplit; } Help withLabel = new Help(new App(), Help.Ansi.OFF); withLabel.commandSpec().parser().separator("="); Help.IParamLabelRenderer equals = withLabel.createDefaultParamLabelRenderer(); withLabel.commandSpec().parser().separator(" "); Help.IParamLabelRenderer spaced = withLabel.createDefaultParamLabelRenderer(); String[] expected = new String[] { "<single>", // "<multi> <multi>", // "<singleHide>", // "<multiHide>", // "[<multiSplit>[,<multiSplit>...]...]", // "<multiHideSplit>", // }; for (int i = 0; i < expected.length; i++) { Text withEquals = equals.renderParameterLabel(withLabel.positionalParameters().get(i), withLabel.ansi(), Collections.<IStyle>emptyList()); Text withSpace = spaced.renderParameterLabel(withLabel.positionalParameters().get(i), withLabel.ansi(), Collections.<IStyle>emptyList()); assertEquals(withEquals.toString(), expected[i], withEquals.toString()); assertEquals(withSpace.toString(), expected[i], withSpace.toString()); } }
@Test public void testAddAllSubcommands() { Help help = new Help(CommandSpec.create(), new Help.ColorScheme(Help.Ansi.OFF)); help.addAllSubcommands(null); assertTrue(help.subcommands().isEmpty()); } @SuppressWarnings("deprecation")
sortOptions = false, synopsisHeading = "abcd", subcommands = Sub.class) class FullBase extends EmptyBase{ } Help help = new Help(new FullBase()); assertEquals("base", help.commandName()); assertEquals(String.format("cust%n"), help.synopsis(0)); assertEquals(String.format("cust%n"), help.customSynopsis()); assertEquals(String.format("base [COMMAND]%n"), help.abbreviatedSynopsis()); assertEquals(String.format("base [COMMAND]%n"), help.detailedSynopsis(0, null, true)); assertEquals("abcd", help.synopsisHeading()); assertEquals(String.format(" sub This is a subcommand%n"), help.commandList()); assertEquals("c o m m a n d s", help.commandListHeading()); assertEquals(String.format("base description%n"), help.description()); assertEquals("base descr heading", help.descriptionHeading()); assertEquals(String.format("base footer%n"), help.footer()); assertEquals("base footer heading", help.footerHeading()); assertEquals(String.format("base header%n"), help.header()); assertEquals("base header heading", help.headerHeading()); assertEquals("", help.optionList()); assertEquals("base option heading", help.commandSpec().usageMessage().optionListHeading()); assertEquals("", help.optionListHeading()); // because no options assertEquals("", help.parameterList()); assertEquals("base param heading", help.commandSpec().usageMessage().parameterListHeading()); assertEquals("", help.parameterListHeading()); // because no parameters assertTrue(help.commandSpec().usageMessage().abbreviateSynopsis()); assertTrue(help.commandSpec().usageMessage().showDefaultValues()); assertFalse(help.commandSpec().usageMessage().sortOptions()); assertEquals(";", help.commandSpec().parser().separator()); assertEquals('&', help.commandSpec().usageMessage().requiredOptionMarker());
sortOptions = true, synopsisHeading = "xyz") class FullSub extends Base{ } Help help = new Help(new FullSub()); assertEquals("sub", help.commandName()); assertEquals(String.format("subcust%n"), help.synopsis(0)); assertEquals(String.format("subcust%n"), help.customSynopsis()); assertEquals(String.format("sub%n"), help.abbreviatedSynopsis()); assertEquals(String.format("sub%n"), help.detailedSynopsis(0,null, true)); assertEquals("xyz", help.synopsisHeading()); assertEquals("", help.commandList()); assertEquals("", help.commandListHeading()); // empty: no commands assertEquals("subc o m m a n d s", help.commandSpec().usageMessage().commandListHeading()); assertEquals(String.format("sub description%n"), help.description()); assertEquals("sub descr heading", help.descriptionHeading()); assertEquals(String.format("sub footer%n"), help.footer()); assertEquals("sub footer heading", help.footerHeading()); assertEquals(String.format("sub header%n"), help.header()); assertEquals("sub header heading", help.headerHeading()); assertEquals("", help.optionList()); assertEquals("", help.optionListHeading()); assertEquals("sub option heading", help.commandSpec().usageMessage().optionListHeading()); assertEquals("", help.parameterList()); assertEquals("", help.parameterListHeading()); assertEquals("sub param heading", help.commandSpec().usageMessage().parameterListHeading()); assertTrue(help.commandSpec().usageMessage().abbreviateSynopsis()); assertTrue(help.commandSpec().usageMessage().showDefaultValues()); assertFalse(help.commandSpec().usageMessage().sortOptions()); assertEquals(":", help.commandSpec().parser().separator()); assertEquals('%', help.commandSpec().usageMessage().requiredOptionMarker());
List<String> aliases = done.remove(entry.getValue()); if (aliases != null) { // otherwise we already processed this command by another alias addSubcommand(aliases, entry.getValue());
@Option(names = {"-b", "--beta"}, description = "combi") int combiField = 123; Help help = new Help(new Example()); Help.IOptionRenderer renderer = help.createDefaultOptionRenderer(); Help.IParamLabelRenderer parameterRenderer = help.createDefaultParamLabelRenderer(); int i = -1; int rowIndex = 0; for (OptionSpec option : help.options()) { Text[][] row = renderer.render(option, parameterRenderer, help.colorScheme()); assertEquals(rowCount[++i], row.length); assertArrayEquals(Arrays.toString(row[0]), textArray(help, expected[rowIndex]), row[0]);
@CommandLine.Option(names = {"--include", "-i"}, paramLabel = "<includePattern>") String pattern; CommandLine.Help help = new CommandLine.Help(new App(), Ansi.OFF); String expected = "" + "Usage: small-test-program [-!?acorv] [--version] [-h <number>] [-i" + LINESEP + " <includePattern>] [-p <file>|<folder>] [-d <folder>" + LINESEP + " [<folder>]]..." + LINESEP; assertEquals(expected, help.synopsisHeading() + help.synopsis(help.synopsisHeadingLength())); help.commandSpec().usageMessage().synopsisHeading("Usage:%n"); expected = "" + "Usage:" + LINESEP + "small-test-program [-!?acorv] [--version] [-h <number>] [-i <includePattern>]" + LINESEP + " [-p <file>|<folder>] [-d <folder> [<folder>]]..." + LINESEP; assertEquals(expected, help.synopsisHeading() + help.synopsis(help.synopsisHeadingLength()));
@Test public void testDefaultParameterRenderer_hideParamSyntax_on() { class App { @Parameters(index = "0") String single; @Parameters(index = "1", arity = "2") String[] multi; @Parameters(index = "2", hideParamSyntax = true) String singleHide; @Parameters(index = "3", hideParamSyntax = true, arity = "2") String[] multiHide; @Parameters(index = "4", hideParamSyntax = false, arity = "*", split = ",") String[] multiSplit; @Parameters(index = "5", hideParamSyntax = true, arity = "*", split = ",") String[] multiHideSplit; } Help withLabel = new Help(new App(), Help.Ansi.OFF); withLabel.commandSpec().parser().separator("="); Help.IParamLabelRenderer equals = withLabel.createDefaultParamLabelRenderer(); withLabel.commandSpec().parser().separator(" "); Help.IParamLabelRenderer spaced = withLabel.createDefaultParamLabelRenderer(); String[] expected = new String[] { "<single>", // "<multi> <multi>", // "<singleHide>", // "<multiHide>", // "[<multiSplit>[,<multiSplit>...]...]", // "<multiHideSplit>", // }; for (int i = 0; i < expected.length; i++) { Text withEquals = equals.renderParameterLabel(withLabel.positionalParameters().get(i), withLabel.ansi(), Collections.<IStyle>emptyList()); Text withSpace = spaced.renderParameterLabel(withLabel.positionalParameters().get(i), withLabel.ansi(), Collections.<IStyle>emptyList()); assertEquals(withEquals.toString(), expected[i], withEquals.toString()); assertEquals(withSpace.toString(), expected[i], withSpace.toString()); } }
@Command class EmptySub extends Base {} Help help = new Help(new EmptySub()); assertEquals("base", help.commandName()); assertEquals(String.format("cust%n"), help.synopsis(0)); assertEquals(String.format("cust%n"), help.customSynopsis()); assertEquals(String.format("base%n"), help.abbreviatedSynopsis()); assertEquals(String.format("base%n"), help.detailedSynopsis(0,null, true)); assertEquals("abcd", help.synopsisHeading()); assertEquals("", help.commandList()); assertEquals("", help.commandListHeading()); assertEquals("c o m m a n d s", help.commandSpec().usageMessage().commandListHeading()); assertEquals(String.format("base description%n"), help.description()); assertEquals("base descr heading", help.descriptionHeading()); assertEquals(String.format("base footer%n"), help.footer()); assertEquals("base footer heading", help.footerHeading()); assertEquals(String.format("base header%n"), help.header()); assertEquals("base header heading", help.headerHeading()); assertEquals("", help.optionList()); assertEquals("", help.optionListHeading()); assertEquals("base option heading", help.commandSpec().usageMessage().optionListHeading()); assertEquals("", help.parameterList()); assertEquals("", help.parameterListHeading()); assertEquals("base param heading", help.commandSpec().usageMessage().parameterListHeading()); assertEquals(";", help.commandSpec().parser().separator()); assertEquals('&', help.commandSpec().usageMessage().requiredOptionMarker()); assertTrue(help.commandSpec().usageMessage().abbreviateSynopsis()); assertTrue(help.commandSpec().usageMessage().showDefaultValues());
@Test public void testDefaultOptionRenderer_rendersCommaOnlyIfBothShortAndLongOptionNamesExist() { class Example { @Option(names = {"-v"}, description = "shortBool") boolean shortBoolean; @Option(names = {"--verbose"}, description = "longBool") boolean longBoolean; @Option(names = {"-x", "--xeno"}, description = "combiBool") boolean combiBoolean; @Option(names = {"-s"}, description = "shortOnly") String shortOnlyField; @Option(names = {"--long"}, description = "longOnly") String longOnlyField; @Option(names = {"-b", "--beta"}, description = "combi") String combiField; } Help help = new Help(new Example()); help.commandSpec().usageMessage().showDefaultValues(false); // omit default values from description column Help.IOptionRenderer renderer = help.createDefaultOptionRenderer(); Help.IParamLabelRenderer parameterRenderer = help.createDefaultParamLabelRenderer(); String[][] expected = new String[][] { {"", "-v", "", "", "shortBool"}, {"", "", "", "--verbose", "longBool"}, {"", "-x", ",", "--xeno", "combiBool"}, {"", "-s", "=", "<shortOnlyField>", "shortOnly"}, {"", "", "", "--long=<longOnlyField>", "longOnly"}, {"", "-b", ",", "--beta=<combiField>", "combi"}, }; int i = -1; for (OptionSpec option : help.options()) { Text[][] row = renderer.render(option, parameterRenderer, help.colorScheme()); assertEquals(1, row.length); assertArrayEquals(Arrays.toString(row[0]), textArray(help, expected[++i]), row[0]); } }
@Test public void testDefaultParameterRenderer_showsParamLabelIfPresentOrFieldNameOtherwise() { class Example { @Option(names = "--without" ) String longField; @Option(names = "--with", paramLabel = "LABEL") String otherField; } Help help = new Help(new Example()); Help.IParamLabelRenderer equalSeparatedParameterRenderer = help.createDefaultParamLabelRenderer(); Help help2 = new Help(new Example()); help2.commandSpec().parser().separator(" "); Help.IParamLabelRenderer spaceSeparatedParameterRenderer = help2.createDefaultParamLabelRenderer(); String[] expected = new String[] { "<longField>", "LABEL", }; int i = -1; for (OptionSpec option : help.options()) { i++; Text withSpace = spaceSeparatedParameterRenderer.renderParameterLabel(option, help.ansi(), Collections.<IStyle>emptyList()); assertEquals(withSpace.toString(), " " + expected[i], withSpace.toString()); Text withEquals = equalSeparatedParameterRenderer.renderParameterLabel(option, help.ansi(), Collections.<IStyle>emptyList()); assertEquals(withEquals.toString(), "=" + expected[i], withEquals.toString()); } }
@Test public void testDefaultOptionRenderer_rendersShortestOptionNameThenOtherOptionNamesAndDescription() { @Command(showDefaultValues = true) class Example { @Option(names = {"---long", "-L"}, description = "long description") String longField; @Option(names = {"-b", "-a", "--alpha"}, description = "other") String otherField = "abc"; } Help help = new Help(new Example()); Help.IOptionRenderer renderer = help.createDefaultOptionRenderer(); Help.IParamLabelRenderer parameterRenderer = help.createDefaultParamLabelRenderer(); OptionSpec option = help.options().get(0); Text[][] row1 = renderer.render(option, parameterRenderer, help.colorScheme()); assertEquals(1, row1.length); assertArrayEquals(Arrays.toString(row1[0]), textArray(help, "", "-L", ",", "---long=<longField>", "long description"), row1[0]); //assertArrayEquals(Arrays.toString(row1[1]), textArray(help, "", "", "", "", " Default: null"), row1[1]); // #201 don't show null defaults option = help.options().get(1); Text[][] row2 = renderer.render(option, parameterRenderer, help.colorScheme()); assertEquals(2, row2.length); assertArrayEquals(Arrays.toString(row2[0]), textArray(help, "", "-b", ",", "-a, --alpha=<otherField>", "other"), row2[0]); assertArrayEquals(Arrays.toString(row2[1]), textArray(help, "", "", "", "", " Default: abc"), row2[1]); }
/** Returns a 2-column list with command names and the first line of their header or (if absent) description. * @return a usage help section describing the added commands */ public String commandList() { if (subcommands().isEmpty()) { return ""; } int commandLength = maxLength(subcommands().keySet()); Help.TextTable textTable = Help.TextTable.forColumns(ansi(), new Help.Column(commandLength + 2, 2, Help.Column.Overflow.SPAN), new Help.Column(width() - (commandLength + 2), 2, Help.Column.Overflow.WRAP)); for (Map.Entry<String, Help> entry : subcommands().entrySet()) { Help help = entry.getValue(); UsageMessageSpec usage = help.commandSpec().usageMessage(); String header = !empty(usage.header()) ? usage.header()[0] : (!empty(usage.description()) ? usage.description()[0] : ""); Text[] lines = ansi().text(format(header)).splitLines(); for (int i = 0; i < lines.length; i++) { textTable.addRowValues(i == 0 ? help.commandNamesText(", ") : Ansi.EMPTY_TEXT, lines[i]); } } return textTable.toString(); } private static int maxLength(Collection<String> any) {
@Test public void testDefaultParameterRenderer_appliesToPositionalArgumentsIgnoresSeparator() { class WithLabel { @Parameters(paramLabel = "POSITIONAL_ARGS") String positional; } class WithoutLabel { @Parameters() String positional; } Help withLabel = new Help(new WithLabel()); Help.IParamLabelRenderer equals = withLabel.createDefaultParamLabelRenderer(); withLabel.commandSpec().parser().separator("="); Help.IParamLabelRenderer spaced = withLabel.createDefaultParamLabelRenderer(); Text withSpace = spaced.renderParameterLabel(withLabel.positionalParameters().get(0), withLabel.ansi(), Collections.<IStyle>emptyList()); assertEquals(withSpace.toString(), "POSITIONAL_ARGS", withSpace.toString()); Text withEquals = equals.renderParameterLabel(withLabel.positionalParameters().get(0), withLabel.ansi(), Collections.<IStyle>emptyList()); assertEquals(withEquals.toString(), "POSITIONAL_ARGS", withEquals.toString()); Help withoutLabel = new Help(new WithoutLabel()); withSpace = spaced.renderParameterLabel(withoutLabel.positionalParameters().get(0), withoutLabel.ansi(), Collections.<IStyle>emptyList()); assertEquals(withSpace.toString(), "<positional>", withSpace.toString()); withEquals = equals.renderParameterLabel(withoutLabel.positionalParameters().get(0), withoutLabel.ansi(), Collections.<IStyle>emptyList()); assertEquals(withEquals.toString(), "<positional>", withEquals.toString()); }
@Test public void testDefaultOptionRenderer_rendersSpacePrefixByDefaultForRequiredOptionsWithDefaultValue() { //@Command(showDefaultValues = true) // set programmatically class Example { @Option(names = {"-b", "-a", "--alpha"}, required = true, description = "other") String otherField; } Help help = new Help(new Example()); help.commandSpec().usageMessage().showDefaultValues(true); Help.IOptionRenderer renderer = help.createDefaultOptionRenderer(); Help.IParamLabelRenderer parameterRenderer = help.createDefaultParamLabelRenderer(); OptionSpec option = help.options().get(0); Text[][] row = renderer.render(option, parameterRenderer, help.colorScheme()); assertEquals(1, row.length); assertArrayEquals(Arrays.toString(row[0]), textArray(help, " ", "-b", ",", "-a, --alpha=<otherField>", "other"), row[0]); // assertArrayEquals(Arrays.toString(row[1]), textArray(help, "", "", "", "", " Default: null"), row[1]); // #201 don't show null defaults }
result.put(SECTION_KEY_COMMAND_LIST, new IHelpSectionRenderer() { public String render(Help help) { return help.commandList(); } }); result.put(SECTION_KEY_FOOTER_HEADING, new IHelpSectionRenderer() { public String render(Help help) { return help.footerHeading(); } });
result.put(SECTION_KEY_COMMAND_LIST_HEADING, new IHelpSectionRenderer() { public String render(Help help) { return help.commandListHeading(); } }); //e.g. add adds the frup to the frooble
@Test public void testDefaultParameterRenderer_rendersSpacePrefixForParametersWithZeroArity() { @Command(requiredOptionMarker = '*') class Optional { @Parameters(arity = "0..1", description = "optional") String optional; } Help help = new Help(new Optional()); Help.IParameterRenderer renderer = help.createDefaultParameterRenderer(); Help.IParamLabelRenderer parameterRenderer = Help.createMinimalParamLabelRenderer(); PositionalParamSpec param = help.positionalParameters().get(0); Text[][] row1 = renderer.render(param, parameterRenderer, help.colorScheme()); assertEquals(1, row1.length); assertArrayEquals(Arrays.toString(row1[0]), textArray(help, "", "", "", "<optional>", "optional"), row1[0]); }
private Layout createLayout(int longOptionsColumnWidth) { return new Layout(colorScheme, TextTable.forDefaultColumns(colorScheme.ansi(), longOptionsColumnWidth, width()), createDefaultOptionRenderer(), createDefaultParameterRenderer()); }