package com.lexicalscope.jewel.cli.validation; import static com.lexicalscope.fluent.FluentDollar.$; import static com.lexicalscope.jewel.cli.ValidationFailureMatcher.validationError; import static com.lexicalscope.jewel.cli.parser.DefaultArgumentParserFactory.createDefaultArgumentParser; import static java.util.Arrays.asList; import static org.hamcrest.Matchers.contains; import static org.junit.Assert.*; import com.lexicalscope.jewel.cli.ArgumentCollectionBuilder; import com.lexicalscope.jewel.cli.ArgumentValidationException; import com.lexicalscope.jewel.cli.Option; import com.lexicalscope.jewel.cli.Unparsed; import com.lexicalscope.jewel.cli.ValidationErrorBuilder; import com.lexicalscope.jewel.cli.ValidationFailureType; import com.lexicalscope.jewel.cli.examples.RmExample; import com.lexicalscope.jewel.cli.specification.OptionsSpecification; import com.lexicalscope.jewel.cli.specification.ParsedOptionSpecification; import java.util.Collections; import java.util.List; import org.jmock.Expectations; import org.jmock.auto.Mock; import org.jmock.integration.junit4.JUnitRuleMockery; import org.junit.Before; import org.junit.Ignore; import org.junit.Rule; import org.junit.Test; public class TestArgumentValidatorImpl<O> { @Rule public final JUnitRuleMockery context = new JUnitRuleMockery(); @Mock public OptionsSpecification<O> specification; @Mock public ValidationErrorBuilder validationErrorBuilder; @Mock public ParsedOptionSpecification option; private ArgumentValidatorImpl<O> argumentValidator; @Before public void setup() { argumentValidator = new ArgumentValidatorImpl<O>(specification, validationErrorBuilder); } public interface NoValue { @Option boolean getName0(); @Option boolean getName1(); } public interface SingleValue { @Option String getName(); } public interface MultipleValue { @Option List<String> getName(); @Unparsed List<String> getUnparsed(); } public interface ExtraValue { @Option List<String> getName0(); @Option String getName1(); @Unparsed List<String> getUnparsed(); } public interface OptionalOption { @Option String getName0(); @Option String getName1(); boolean isName1(); } public interface OptionAndUnparsed { @Option String getName0(); @Unparsed List<String> getRemainingArguments(); } @Test @Ignore public void testMissingOption() { context.checking(new Expectations() {{ oneOf(validationErrorBuilder).validate(); oneOf(specification).getMandatoryOptions(); will(returnValue($.asList(option))); oneOf(validationErrorBuilder).missingOption(option); oneOf(validationErrorBuilder).validate(); }}); argumentValidator.finishedProcessing(); } @Test @Ignore public void noUnparsedSpecificationAndNoUnparsedOptionsIsValid() { context.checking(new Expectations() {{ oneOf(specification).hasUnparsedSpecification(); will(returnValue(false)); }}); argumentValidator.processUnparsed(Collections.<String>emptyList()); } @Test @Ignore public void testMultipleValue() throws ArgumentValidationException { context.checking(new Expectations() {{ oneOf(specification).isSpecified("name"); will(returnValue(true)); oneOf(specification).getSpecification("name"); will(returnValue(option)); oneOf(option).isHelpOption(); will(returnValue(false)); oneOf(option).allowedThisManyValues(2); will(returnValue(true)); oneOf(option).allowedValue("a"); will(returnValue(true)); oneOf(option).allowedValue("b"); will(returnValue(true)); oneOf(validationErrorBuilder).validate(); oneOf(specification).getMandatoryOptions(); will(returnValue($.asList(option))); oneOf(validationErrorBuilder).validate(); }}); argumentValidator.processOption("name", asList("a", "b")); argumentValidator.finishedProcessing(); } @Test @Ignore public void testMultipleValueEndOfArguments() throws ArgumentValidationException { final OptionCollectionImpl validated = validate(new String[] { "--name", "a", "b", "--", "c", "d" }, MultipleValue.class); assertEquals(2, validated.getUnparsed().size()); assertEquals(2, validated.getValues("name").size()); } @Test @Ignore public void testMultipleValueNotEndOfArguments() throws ArgumentValidationException { final OptionCollectionImpl validated = validate( new String[] { "--name0", "a", "b", "--name1", "c", "d", "e", "--", "f", "g" }, ExtraValue.class); assertEquals(4, validated.getUnparsed().size()); assertEquals(2, validated.getValues("name0").size()); assertEquals(1, validated.getValues("name1").size()); } @Test @Ignore public void testAdjacentShortOptions() throws ArgumentValidationException { final OptionCollectionImpl validated = validate(new String[] { "-vrf", "./" }, RmExample.class); assertEquals(1, validated.getUnparsed().size()); } @Test @Ignore public void testSingleValue() throws ArgumentValidationException { validate(new String[] { "--name", "a" }, MultipleValue.class); } @Test @Ignore public void testExtraOption() { try { validate(new String[] { "--name1", "value", "wrong", "--name0" }, ExtraValue.class); fail(); } catch (final ArgumentValidationException e) { assertThat(e.getValidationFailures(), contains(validationError(ValidationFailureType.UnexpectedAdditionalValue))); } } @Test @Ignore public void testMissingValue() { try { validate(new String[] { "--name" }, SingleValue.class); fail(); } catch (final ArgumentValidationException e) { assertThat(e.getValidationFailures(), contains(validationError(ValidationFailureType.MissingValue))); } } @Test @Ignore public void testUnexpectedValue() { try { validate(new String[] { "--name1", "value", "--name0" }, NoValue.class); fail(); } catch (final ArgumentValidationException e) { assertThat(e.getValidationFailures(), contains(validationError(ValidationFailureType.UnexpectedValue))); } } @Test @Ignore public void testMissingMultipleValue() throws ArgumentValidationException { validate(new String[] { "--name" }, MultipleValue.class); // TODO[tim]:support minimum/maximum value list lengths } @Test @Ignore public void testOptionAndUnparsed() throws ArgumentValidationException { final OptionCollectionImpl validated = validate(new String[] { "--name0", "value0", "remaining0" }, OptionAndUnparsed.class); assertEquals(1, validated.getUnparsed().size()); } private <O> OptionCollectionImpl validate(final String[] arguments, final Class<O> klass) throws ArgumentValidationException { final ArgumentValidatorImpl<O> impl = null; // new ArgumentValidatorImpl<O>( // InterfaceOptionsSpecificationParser.<O>createOptionsSpecificationImpl(type(klass))); final ArgumentCollectionBuilder parsedArguments = new ArgumentCollectionBuilder(); createDefaultArgumentParser().parseArguments(parsedArguments, arguments); return (OptionCollectionImpl) parsedArguments.processArguments(impl); } }