Java tutorial
/* * 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())); } }