1 package com.lexicalscope.jewel.cli.validation;
2
3 import static com.lexicalscope.fluentreflection.FluentReflection.type;
4 import static com.lexicalscope.jewel.cli.ValidationFailureMatcher.validationError;
5 import static com.lexicalscope.jewel.cli.parser.DefaultArgumentParserFactory.createDefaultArgumentParser;
6 import static org.hamcrest.Matchers.contains;
7 import static org.junit.Assert.*;
8
9 import java.util.List;
10
11 import org.junit.Test;
12
13 import com.lexicalscope.jewel.cli.ArgumentCollectionBuilder;
14 import com.lexicalscope.jewel.cli.ArgumentValidationException;
15 import com.lexicalscope.jewel.cli.InterfaceOptionsSpecificationParser;
16 import com.lexicalscope.jewel.cli.Option;
17 import com.lexicalscope.jewel.cli.Unparsed;
18 import com.lexicalscope.jewel.cli.ValidationErrorBuilderImpl;
19 import com.lexicalscope.jewel.cli.ValidationFailureType;
20 import com.lexicalscope.jewel.cli.examples.RmExample;
21
22 public class TestArgumentValidatorImpl2 {
23 public interface NoValue {
24 @Option boolean getName0();
25
26 @Option boolean getName1();
27 }
28
29 public interface SingleValue {
30 @Option String getName();
31 }
32
33 public interface MultipleValue {
34 @Option List<String> getName();
35
36 @Unparsed List<String> getUnparsed();
37 }
38
39 public interface ExtraValue {
40 @Option List<String> getName0();
41
42 @Option String getName1();
43
44 @Unparsed List<String> getUnparsed();
45 }
46
47 public interface OptionalOption {
48 @Option String getName0();
49
50 @Option String getName1();
51 boolean isName1();
52 }
53
54 public interface OptionAndUnparsed {
55 @Option String getName0();
56
57 @Unparsed List<String> getRemainingArguments();
58 }
59
60 @Test public void testMissingOption() {
61 try {
62 validate(new String[] { "--name1", "value" }, OptionalOption.class);
63 fail();
64 } catch (final ArgumentValidationException e) {
65 assertThat(e.getValidationFailures(), contains(validationError(ValidationFailureType.MissingOption)));
66 }
67 }
68
69 @Test public void testMultipleValue() throws ArgumentValidationException {
70 validate(new String[] { "--name", "a", "b" }, MultipleValue.class);
71 }
72
73 @Test public void testMultipleValueEndOfArguments() throws ArgumentValidationException {
74 final OptionCollectionImpl validated =
75 validate(new String[] { "--name", "a", "b", "--", "c", "d" }, MultipleValue.class);
76 assertEquals(2, validated.getUnparsed().size());
77 assertEquals(2, validated.getValues("name").size());
78 }
79
80 @Test public void testMultipleValueNotEndOfArguments() throws ArgumentValidationException {
81 final OptionCollectionImpl validated =
82 validate(
83 new String[] { "--name0", "a", "b", "--name1", "c", "d", "e", "--", "f", "g" },
84 ExtraValue.class);
85 assertEquals(4, validated.getUnparsed().size());
86 assertEquals(2, validated.getValues("name0").size());
87 assertEquals(1, validated.getValues("name1").size());
88 }
89
90 @Test public void testAdjacentShortOptions() throws ArgumentValidationException {
91 final OptionCollectionImpl validated = validate(new String[] { "-vrf", "./" }, RmExample.class);
92 assertEquals(1, validated.getUnparsed().size());
93 }
94
95 @Test public void testSingleValue() throws ArgumentValidationException {
96 validate(new String[] { "--name", "a" }, MultipleValue.class);
97 }
98
99 @Test public void testExtraOption() {
100 try {
101 validate(new String[] { "--name1", "value", "wrong", "--name0" }, ExtraValue.class);
102 fail();
103 } catch (final ArgumentValidationException e) {
104 assertThat(e.getValidationFailures(), contains(validationError(ValidationFailureType.UnexpectedAdditionalValue)));
105 }
106 }
107
108 @Test public void testMissingValue() {
109 try {
110 validate(new String[] { "--name" }, SingleValue.class);
111 fail();
112 } catch (final ArgumentValidationException e) {
113 assertThat(e.getValidationFailures(), contains(validationError(ValidationFailureType.MissingValue)));
114 }
115 }
116
117 @Test public void testUnexpectedValue() {
118 try {
119 validate(new String[] { "--name1", "value", "--name0" }, NoValue.class);
120 fail();
121 } catch (final ArgumentValidationException e) {
122 assertThat(e.getValidationFailures(), contains(validationError(ValidationFailureType.UnexpectedValue)));
123 }
124 }
125
126 @Test public void testMissingMultipleValue() throws ArgumentValidationException {
127 validate(new String[] { "--name" }, MultipleValue.class);
128
129 }
130
131 @Test public void testOptionAndUnparsed() throws ArgumentValidationException {
132 final OptionCollectionImpl validated =
133 validate(new String[] { "--name0", "value0", "remaining0" }, OptionAndUnparsed.class);
134 assertEquals(1, validated.getUnparsed().size());
135 }
136
137 private <O> OptionCollectionImpl validate(final String[] arguments, final Class<O> klass)
138 throws ArgumentValidationException {
139 final ArgumentValidatorImpl<O> impl =
140 new ArgumentValidatorImpl<O>(
141 InterfaceOptionsSpecificationParser.<O>createOptionsSpecificationImpl(type(klass)), new ValidationErrorBuilderImpl());
142
143 final ArgumentCollectionBuilder parsedArguments = new ArgumentCollectionBuilder();
144 createDefaultArgumentParser().parseArguments(parsedArguments, arguments);
145
146 return (OptionCollectionImpl) parsedArguments.processArguments(impl);
147 }
148 }