package com.lexicalscope.jewel.cli.validation;
import static com.lexicalscope.fluentreflection.FluentReflection.type;
import static com.lexicalscope.jewel.cli.ValidationFailureMatcher.validationError;
import static com.lexicalscope.jewel.cli.parser.DefaultArgumentParserFactory.createDefaultArgumentParser;
import static org.hamcrest.Matchers.contains;
import static org.junit.Assert.*;
import java.util.List;
import org.junit.Test;
import com.lexicalscope.jewel.cli.ArgumentCollectionBuilder;
import com.lexicalscope.jewel.cli.ArgumentValidationException;
import com.lexicalscope.jewel.cli.InterfaceOptionsSpecificationParser;
import com.lexicalscope.jewel.cli.Option;
import com.lexicalscope.jewel.cli.Unparsed;
import com.lexicalscope.jewel.cli.ValidationErrorBuilderImpl;
import com.lexicalscope.jewel.cli.ValidationFailureType;
import com.lexicalscope.jewel.cli.examples.RmExample;
public class TestArgumentValidatorImpl2 {
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 public void testMissingOption() {
try {
validate(new String[] { "--name1", "value" }, OptionalOption.class);
fail();
} catch (final ArgumentValidationException e) {
assertThat(e.getValidationFailures(), contains(validationError(ValidationFailureType.MissingOption)));
}
}
@Test public void testMultipleValue() throws ArgumentValidationException {
validate(new String[] { "--name", "a", "b" }, MultipleValue.class);
}
@Test 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 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 public void testAdjacentShortOptions() throws ArgumentValidationException {
final OptionCollectionImpl validated = validate(new String[] { "-vrf", "./" }, RmExample.class);
assertEquals(1, validated.getUnparsed().size());
}
@Test public void testSingleValue() throws ArgumentValidationException {
validate(new String[] { "--name", "a" }, MultipleValue.class);
}
@Test 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 public void testMissingValue() {
try {
validate(new String[] { "--name" }, SingleValue.class);
fail();
} catch (final ArgumentValidationException e) {
assertThat(e.getValidationFailures(), contains(validationError(ValidationFailureType.MissingValue)));
}
}
@Test 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 public void testMissingMultipleValue() throws ArgumentValidationException {
validate(new String[] { "--name" }, MultipleValue.class);
// TODO[tim]:support minimum/maximum value list lengths
}
@Test 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 =
new ArgumentValidatorImpl<O>(
InterfaceOptionsSpecificationParser.<O>createOptionsSpecificationImpl(type(klass)), new ValidationErrorBuilderImpl());
final ArgumentCollectionBuilder parsedArguments = new ArgumentCollectionBuilder();
createDefaultArgumentParser().parseArguments(parsedArguments, arguments);
return (OptionCollectionImpl) parsedArguments.processArguments(impl);
}
}