candr.yoclip.DefaultParserHelpFactoryTest.java Source code

Java tutorial

Introduction

Here is the source code for candr.yoclip.DefaultParserHelpFactoryTest.java

Source

/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package candr.yoclip;

import candr.yoclip.annotation.*;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.text.StrBuilder;
import org.apache.commons.lang3.tuple.Pair;
import org.junit.Test;

import java.util.*;

import static org.hamcrest.core.Is.is;
import static org.junit.Assert.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

/**
 * {@link DefaultParserHelpFactory} unit tests.
 */
public class DefaultParserHelpFactoryTest {

    @Options(name = "testCase", prefix = "/", separator = "=", usage = "[/s=value] [/Dprop=value] [ARGS]")
    class TestCase {

        @SuppressWarnings("unused")
        @Option(name = { "s", "string" })
        String option;

        @SuppressWarnings("unused")
        @OptionProperties
        Map<String, String> properties = new LinkedHashMap<String, String>();

        @Arguments
        @SuppressWarnings("unused")
        List<String> arguments = new LinkedList<String>();
    }

    @Options(name = "requiredTestCase")
    class RequiredTestCase {

        @SuppressWarnings("unused")
        @Option(name = { "s", "string" }, required = true)
        String option;

        @SuppressWarnings("unused")
        @OptionProperties(required = true)
        Map<String, String> properties = new LinkedHashMap<String, String>();

        @Arguments(required = true)
        @SuppressWarnings("unused")
        List<String> arguments = new LinkedList<String>();
    }

    @Options(name = "propsTest")
    class PropertiesTestCase {

        @SuppressWarnings("unused")
        @OptionProperties(propertyDescriptions = {
                @PropertyDescription(synopsis = "one", details = { "Property", "one.\n", "\n",
                        "Has explicit line breaks." }),
                @PropertyDescription(synopsis = "two", details = "Details for property two."),
                @PropertyDescription() })
        Map<String, String> properties = new LinkedHashMap<String, String>();
    }

    @SuppressWarnings("unused")
    @Options(name = "help", usage = "-option value [-Dkey=value] [ARGS]\n", header = {
            "The header will be output between the usage and options description.",
            "\n\nOptions:\n" }, trailer = "The trailer will be output after option descriptions.\n(Understands line breaks)")
    class HelpTestCase {

        @Option(name = "option", required = true, usage = "-option value", description = {
                "The option description.\n", "(Required)\n" })
        String option;

        @OptionProperties(propertyDescriptions = {
                @PropertyDescription(synopsis = "key1", details = "This is key1\nwith embedded line break.\n"),
                @PropertyDescription(synopsis = "key2", details = { "This is key2",
                        "without an embedded line break but long enough to wrap.\n" }) })
        Map<String, String> properties = new LinkedHashMap<String, String>();

        @Arguments(required = true, description = { "The arguments description also supports an array of text\n" })
        @SuppressWarnings("unused")
        List<String> arguments = new LinkedList<String>();
    }

    @Test
    public void testCreateUsageTestCase() {

        final ParserHelpFactory<TestCase> testCase = new DefaultParserHelpFactory<TestCase>();
        final ParserOptions<TestCase> parserOptions = new ParserOptionsFactory<TestCase>(TestCase.class).create();
        final String testCaseUsage = testCase.createUsage(parserOptions);
        assertThat("TestCase usage", testCaseUsage, is("[OPTION [OPTION ...]] [ARGS]"));

        ParserOption<TestCase> testCaseParserProperties = parserOptions.get("D");
        parserOptions.removeParserParameter(testCaseParserProperties);
        String oneOptionTestCaseUsage = testCase.createUsage(parserOptions);
        assertThat("TestCase 1 option", oneOptionTestCaseUsage, is("[OPTION] [ARGS]"));

        testCaseParserProperties = parserOptions.get(ParserOptions.ARGUMENTS_KEY);
        parserOptions.removeParserParameter(testCaseParserProperties);
        oneOptionTestCaseUsage = testCase.createUsage(parserOptions);
        assertThat("TestCase 1 option no args", oneOptionTestCaseUsage, is("[OPTION]"));
    }

    @Test
    public void testCreateUsageRequiredTestCase() {

        final ParserHelpFactory<RequiredTestCase> requiredTestCase = new DefaultParserHelpFactory<RequiredTestCase>();
        final ParserOptions<RequiredTestCase> requiredParserOptions = new ParserOptionsFactory<RequiredTestCase>(
                RequiredTestCase.class).create();
        final String requiredTestCaseUsage = requiredTestCase.createUsage(requiredParserOptions);
        assertThat("RequiredTestCase usage", requiredTestCaseUsage, is("OPTION [OPTION ...] ARGS"));

        ParserOption<RequiredTestCase> requiredTestCaseParserProperties = requiredParserOptions.get("D");
        requiredParserOptions.removeParserParameter(requiredTestCaseParserProperties);
        String oneOptionRequiredTestCaseUsage = requiredTestCase.createUsage(requiredParserOptions);
        assertThat("RequiredTestCase 1 option", oneOptionRequiredTestCaseUsage, is("OPTION ARGS"));

        requiredTestCaseParserProperties = requiredParserOptions.get(ParserOptions.ARGUMENTS_KEY);
        requiredParserOptions.removeParserParameter(requiredTestCaseParserProperties);
        oneOptionRequiredTestCaseUsage = requiredTestCase.createUsage(requiredParserOptions);
        assertThat("RequiredTestCase 1 option no args", oneOptionRequiredTestCaseUsage, is("OPTION"));
    }

    @Test
    public void createParserParameterDescriptionRequiredTestCase() {

        final DefaultParserHelpFactory<RequiredTestCase> testCase = new DefaultParserHelpFactory<RequiredTestCase>();
        final ParserOptions<RequiredTestCase> parserOptions = new ParserOptionsFactory<RequiredTestCase>(
                RequiredTestCase.class).create();

        assertThat("option description", testCase.createParserParameterDescription(parserOptions.get("s")),
                is("Sets the 'option' field option. This option is required."));

        assertThat("properties description", testCase.createParserParameterDescription(parserOptions.get("D")),
                is("Sets a property and value into the 'properties' Map field. This option is required."));

        assertThat("arguments description", testCase.createParserParameterDescription(parserOptions.getArguments()),
                is("Sets an argument into the 'arguments' List field. This option is required."));
    }

    @Test(expected = IllegalArgumentException.class)
    public void createParserParameterDescriptionWithNull() {
        new DefaultParserHelpFactory<RequiredTestCase>().createParserParameterDescription(null);
    }

    @Test(expected = IllegalArgumentException.class)
    public void testCreateUsageWithNull() {
        new DefaultParserHelpFactory<TestCase>().createUsage(null);
    }

    @Test
    public void testGetHeaderDescription() {

        final ParserHelpFactory<TestCase> testCase = new DefaultParserHelpFactory<TestCase>();
        final ParserOptions<TestCase> parserOptions = new ParserOptionsFactory<TestCase>(TestCase.class).create();
        assertThat("TestCase header", testCase.getHeaderDescription(parserOptions),
                is(DefaultParserHelpFactory.DEFAULT_HEADER));

        final ParserHelpFactory<HelpTestCase> helpTestCase = new DefaultParserHelpFactory<HelpTestCase>();
        final ParserOptions<HelpTestCase> helpParserOptions = new ParserOptionsFactory<HelpTestCase>(
                HelpTestCase.class).create();
        final String helpHeader = StringUtils
                .join("The header will be output between the usage and options description.", "\n\nOptions:\n");
        assertThat("HelpTestCase header", helpTestCase.getHeaderDescription(helpParserOptions), is(helpHeader));
    }

    @Test(expected = IllegalArgumentException.class)
    public void testGetHeaderDescriptionWithNull() {
        new DefaultParserHelpFactory<HelpTestCase>().getHeaderDescription(null);
    }

    @Test
    public void testGetTrailerDescription() {

        final ParserHelpFactory<TestCase> testCase = new DefaultParserHelpFactory<TestCase>();
        final ParserOptions<TestCase> parserOptions = new ParserOptionsFactory<TestCase>(TestCase.class).create();
        assertThat("TestCase trailer", testCase.getTrailerDescription(parserOptions), is(StringUtils.EMPTY));

        final ParserHelpFactory<HelpTestCase> helpTestCase = new DefaultParserHelpFactory<HelpTestCase>();
        final ParserOptions<HelpTestCase> helpParserOptions = new ParserOptionsFactory<HelpTestCase>(
                HelpTestCase.class).create();
        final String helpTrailer = "The trailer will be output after option descriptions.\n(Understands line breaks)";
        assertThat("HelpTestCase trailer", helpTestCase.getTrailerDescription(helpParserOptions), is(helpTrailer));
    }

    @Test(expected = IllegalArgumentException.class)
    public void testGetTrailerDescriptionWithNull() {
        new DefaultParserHelpFactory<HelpTestCase>().getTrailerDescription(null);
    }

    @Test
    public void testGetOptionPropertyDescriptions() {

        final ParserHelpFactory<PropertiesTestCase> testCase = new DefaultParserHelpFactory<PropertiesTestCase>();
        final ParserOptions<PropertiesTestCase> parserOptions = new ParserOptionsFactory<PropertiesTestCase>(
                PropertiesTestCase.class).create();

        ParserOption<PropertiesTestCase> optionParameter = parserOptions.get("D");
        List<Pair<String, String>> descriptions = testCase.getOptionPropertyDescriptions(optionParameter);

        assertThat("size", descriptions.size(), is(3));

        Pair<String, String> propertyHelp = descriptions.get(0);
        assertThat("property help 0 synopsis", propertyHelp.getKey(), is("one"));
        assertThat("property help 0 details", propertyHelp.getValue(),
                is(new StrBuilder().append("Property one.").append(Options.LINE_BREAK).append(Options.LINE_BREAK)
                        .append("Has explicit line breaks.").toString()));

        propertyHelp = descriptions.get(1);
        assertThat("property help 1 synopsis", propertyHelp.getKey(), is("two"));
        assertThat("property help 1 details", propertyHelp.getValue(), is("Details for property two."));

        propertyHelp = descriptions.get(2);
        assertThat("property help 2 synopsis", propertyHelp.getKey(), is("key"));
        assertThat("property help 2 details", propertyHelp.getValue(),
                is("An option property value for properties."));
    }

    @Test(expected = IllegalArgumentException.class)
    public void getOptionPropertyDescriptionsWithNull() {
        new DefaultParserHelpFactory<PropertiesTestCase>().getOptionPropertyDescriptions(null);
    }

    @Test
    public void testGetOptionPropertyDescriptionsWhenEmpty() {

        final ParserHelpFactory<PropertiesTestCase> testCase = new DefaultParserHelpFactory<PropertiesTestCase>();

        @SuppressWarnings("unchecked")
        final ParserOption<PropertiesTestCase> parserOption = mock(ParserOption.class);
        final List<Pair<String, String>> propertyDescriptions = Collections.emptyList();
        when(parserOption.getPropertyDescriptions()).thenReturn(propertyDescriptions);
        assertThat("empty property descriptions", testCase.getOptionPropertyDescriptions(parserOption).isEmpty(),
                is(true));
    }

    @Test
    public void testGetOptionDescription() {

        final ParserHelpFactory<TestCase> testCase = new DefaultParserHelpFactory<TestCase>();
        final ParserOptions<TestCase> parserOptions = new ParserOptionsFactory<TestCase>(TestCase.class).create();

        final String prefix = parserOptions.getPrefix();
        final String separator = parserOptions.getSeparator();

        ParserOption<TestCase> optionParameter = parserOptions.get("s");
        Pair<String, String> description = testCase.getOptionDescription(prefix, separator, optionParameter);
        assertThat("option usage", description.getLeft(), is("/s|/string=STRING"));
        assertThat("option description", description.getRight(), is("Sets the 'option' field option."));

        optionParameter = parserOptions.get("D");
        description = testCase.getOptionDescription(prefix, separator, optionParameter);
        assertThat("properties usage", description.getLeft(), is("/DKEY=VALUE"));
        assertThat("option description", description.getRight(),
                is("Sets a property and value into the 'properties' Map field."));

        optionParameter = parserOptions.get(ParserOptions.ARGUMENTS_KEY);
        description = testCase.getOptionDescription(prefix, separator, optionParameter);
        assertThat("arguments usage", description.getLeft(), is("ARG"));
        assertThat("option description", description.getRight(),
                is("Sets an argument into the 'arguments' List field."));
    }

    @Test(expected = IllegalArgumentException.class)
    public void getOptionDescriptionWithNull() {
        new DefaultParserHelpFactory<TestCase>().getOptionDescription("prefix", "separator", null);
    }

    @Test(expected = IllegalArgumentException.class)
    public void createParserParameterUsageWithNullPrefix() {
        @SuppressWarnings("unchecked")
        final ParserOption<TestCase> parserOption = mock(ParserOption.class);
        new DefaultParserHelpFactory<TestCase>().getOptionDescription(null, "separator", parserOption);
    }

    @Test(expected = IllegalArgumentException.class)
    public void createParserParameterUsageWithEmptyPrefix() {
        @SuppressWarnings("unchecked")
        final ParserOption<TestCase> parserOption = mock(ParserOption.class);
        new DefaultParserHelpFactory<TestCase>().getOptionDescription("", "separator", parserOption);
    }

    @Test(expected = IllegalArgumentException.class)
    public void createParserParameterUsageWithNullSeparator() {
        @SuppressWarnings("unchecked")
        final ParserOption<TestCase> parserOption = mock(ParserOption.class);
        new DefaultParserHelpFactory<TestCase>().getOptionDescription("prefix", null, parserOption);
    }

    @Test(expected = IllegalArgumentException.class)
    public void createParserParameterUsageWithEmptySeparator() {
        @SuppressWarnings("unchecked")
        final ParserOption<TestCase> parserOption = mock(ParserOption.class);
        new DefaultParserHelpFactory<TestCase>().getOptionDescription("prefix", "", parserOption);
    }

    @Test
    public void testHangingIndentWrap() {

        final ParserHelpFactory<TestCase> testCase = new DefaultParserHelpFactory<TestCase>();

        final int width = 30;
        final int indent = 10;

        assertThat("empty", StringUtils.isEmpty(testCase.hangingIndentWrap("", indent, width)), is(true));
        assertThat("null", StringUtils.isEmpty(testCase.hangingIndentWrap(null, indent, width)), is(true));

        StrBuilder builder = new StrBuilder();
        builder.appendln(StringUtils.repeat("abc", 10)).appendPadding(indent, ' ')
                .append(StringUtils.repeat("abc", 5));
        assertThat("!whitespace", testCase.hangingIndentWrap(StringUtils.repeat("abc", 15), indent, width),
                is(builder.toString()));

        final String pangram = "The quick brown fox jumps over the lazy dog";
        builder.clear();
        builder.appendln("The quick brown fox jumps over").appendPadding(indent, ' ').append("the lazy dog");
        assertThat("pangram", testCase.hangingIndentWrap(pangram, indent, width), is(builder.toString()));

        final String newLines = "\nExpected text without indent.\n\nFollowed by more that is indented.\n";
        builder.clear();
        builder.appendNewLine().appendln("Expected text without indent.").appendNewLine().appendPadding(indent, ' ')
                .appendln("Followed by more").appendPadding(indent, ' ').appendln("that is indented.");
        assertThat("new lines", testCase.hangingIndentWrap(newLines, indent, width), is(builder.toString()));
    }

    @Test(expected = OptionsParseException.class)
    public void hangingIndentWrapWithLargeIndent() {
        new DefaultParserHelpFactory<TestCase>().hangingIndentWrap("foobar", 30, 30);
    }

    @Test
    public void testWrap() {

        final ParserHelpFactory<TestCase> testCase = new DefaultParserHelpFactory<TestCase>();
        final int width = 30;

        assertThat("empty", StringUtils.isEmpty(testCase.wrap("", width)), is(true));
        assertThat("null", StringUtils.isEmpty(testCase.wrap(null, width)), is(true));

        StrBuilder builder = new StrBuilder();
        builder.appendln(StringUtils.repeat("abc", 10)).append(StringUtils.repeat("abc", 5));
        assertThat("!whitespace", testCase.wrap(StringUtils.repeat("abc", 15), width), is(builder.toString()));

        final String pangram = "The quick brown fox jumps over the lazy dog";
        builder.clear();
        builder.appendln("The quick brown fox jumps over").append("the lazy dog");
        assertThat("pangram", testCase.wrap(pangram, width), is(builder.toString()));

        final String newLines = "\nExpected first line without indent.\n\nFollowed by more that are not indented.\n";
        builder.clear();
        builder.appendNewLine().appendln("Expected first line without").appendln("indent.").appendNewLine()
                .appendln("Followed by more that are not").appendln("indented.");
        assertThat("new lines", testCase.wrap(newLines, width), is(builder.toString()));

    }
}