1 package com.lexicalscope.jewel.cli.validation;
2
3 import static com.lexicalscope.fluent.FluentDollar.$;
4 import static com.lexicalscope.jewel.cli.ValidationFailureMatcher.validationError;
5 import static com.lexicalscope.jewel.cli.parser.DefaultArgumentParserFactory.createDefaultArgumentParser;
6 import static java.util.Arrays.asList;
7 import static org.hamcrest.Matchers.contains;
8 import static org.junit.Assert.*;
9
10 import com.lexicalscope.jewel.cli.ArgumentCollectionBuilder;
11 import com.lexicalscope.jewel.cli.ArgumentValidationException;
12 import com.lexicalscope.jewel.cli.Option;
13 import com.lexicalscope.jewel.cli.Unparsed;
14 import com.lexicalscope.jewel.cli.ValidationErrorBuilder;
15 import com.lexicalscope.jewel.cli.ValidationFailureType;
16 import com.lexicalscope.jewel.cli.examples.RmExample;
17 import com.lexicalscope.jewel.cli.specification.OptionsSpecification;
18 import com.lexicalscope.jewel.cli.specification.ParsedOptionSpecification;
19
20 import java.util.Collections;
21 import java.util.List;
22
23 import org.jmock.Expectations;
24 import org.jmock.auto.Mock;
25 import org.jmock.integration.junit4.JUnitRuleMockery;
26 import org.junit.Before;
27 import org.junit.Ignore;
28 import org.junit.Rule;
29 import org.junit.Test;
30
31 public class TestArgumentValidatorImpl<O> {
32 @Rule public final JUnitRuleMockery context = new JUnitRuleMockery();
33
34 @Mock public OptionsSpecification<O> specification;
35 @Mock public ValidationErrorBuilder validationErrorBuilder;
36
37 @Mock public ParsedOptionSpecification option;
38
39 private ArgumentValidatorImpl<O> argumentValidator;
40
41 @Before
42 public void setup() {
43 argumentValidator = new ArgumentValidatorImpl<O>(specification, validationErrorBuilder);
44 }
45
46 public interface NoValue {
47 @Option boolean getName0();
48
49 @Option boolean getName1();
50 }
51
52 public interface SingleValue {
53 @Option String getName();
54 }
55
56 public interface MultipleValue {
57 @Option List<String> getName();
58
59 @Unparsed List<String> getUnparsed();
60 }
61
62 public interface ExtraValue {
63 @Option List<String> getName0();
64
65 @Option String getName1();
66
67 @Unparsed List<String> getUnparsed();
68 }
69
70 public interface OptionalOption {
71 @Option String getName0();
72
73 @Option String getName1();
74 boolean isName1();
75 }
76
77 public interface OptionAndUnparsed {
78 @Option String getName0();
79
80 @Unparsed List<String> getRemainingArguments();
81 }
82
83 @Test @Ignore public void testMissingOption() {
84 context.checking(new Expectations() {{
85 oneOf(validationErrorBuilder).validate();
86 oneOf(specification).getMandatoryOptions(); will(returnValue($.asList(option)));
87 oneOf(validationErrorBuilder).missingOption(option);
88 oneOf(validationErrorBuilder).validate();
89 }});
90 argumentValidator.finishedProcessing();
91 }
92
93 @Test @Ignore public void noUnparsedSpecificationAndNoUnparsedOptionsIsValid() {
94 context.checking(new Expectations() {{
95 oneOf(specification).hasUnparsedSpecification(); will(returnValue(false));
96 }});
97 argumentValidator.processUnparsed(Collections.<String>emptyList());
98 }
99
100 @Test @Ignore public void testMultipleValue() throws ArgumentValidationException {
101 context.checking(new Expectations() {{
102 oneOf(specification).isSpecified("name"); will(returnValue(true));
103 oneOf(specification).getSpecification("name"); will(returnValue(option));
104 oneOf(option).isHelpOption(); will(returnValue(false));
105 oneOf(option).allowedThisManyValues(2); will(returnValue(true));
106
107 oneOf(option).allowedValue("a"); will(returnValue(true));
108 oneOf(option).allowedValue("b"); will(returnValue(true));
109
110 oneOf(validationErrorBuilder).validate();
111 oneOf(specification).getMandatoryOptions(); will(returnValue($.asList(option)));
112 oneOf(validationErrorBuilder).validate();
113 }});
114
115 argumentValidator.processOption("name", asList("a", "b"));
116 argumentValidator.finishedProcessing();
117 }
118
119 @Test @Ignore public void testMultipleValueEndOfArguments() throws ArgumentValidationException {
120 final OptionCollectionImpl validated =
121 validate(new String[] { "--name", "a", "b", "--", "c", "d" }, MultipleValue.class);
122 assertEquals(2, validated.getUnparsed().size());
123 assertEquals(2, validated.getValues("name").size());
124 }
125
126 @Test @Ignore public void testMultipleValueNotEndOfArguments() throws ArgumentValidationException {
127 final OptionCollectionImpl validated =
128 validate(
129 new String[] { "--name0", "a", "b", "--name1", "c", "d", "e", "--", "f", "g" },
130 ExtraValue.class);
131 assertEquals(4, validated.getUnparsed().size());
132 assertEquals(2, validated.getValues("name0").size());
133 assertEquals(1, validated.getValues("name1").size());
134 }
135
136 @Test @Ignore public void testAdjacentShortOptions() throws ArgumentValidationException {
137 final OptionCollectionImpl validated = validate(new String[] { "-vrf", "./" }, RmExample.class);
138 assertEquals(1, validated.getUnparsed().size());
139 }
140
141 @Test @Ignore public void testSingleValue() throws ArgumentValidationException {
142 validate(new String[] { "--name", "a" }, MultipleValue.class);
143 }
144
145 @Test @Ignore public void testExtraOption() {
146 try {
147 validate(new String[] { "--name1", "value", "wrong", "--name0" }, ExtraValue.class);
148 fail();
149 } catch (final ArgumentValidationException e) {
150 assertThat(e.getValidationFailures(), contains(validationError(ValidationFailureType.UnexpectedAdditionalValue)));
151 }
152 }
153
154 @Test @Ignore public void testMissingValue() {
155 try {
156 validate(new String[] { "--name" }, SingleValue.class);
157 fail();
158 } catch (final ArgumentValidationException e) {
159 assertThat(e.getValidationFailures(), contains(validationError(ValidationFailureType.MissingValue)));
160 }
161 }
162
163 @Test @Ignore public void testUnexpectedValue() {
164 try {
165 validate(new String[] { "--name1", "value", "--name0" }, NoValue.class);
166 fail();
167 } catch (final ArgumentValidationException e) {
168 assertThat(e.getValidationFailures(), contains(validationError(ValidationFailureType.UnexpectedValue)));
169 }
170 }
171
172 @Test @Ignore public void testMissingMultipleValue() throws ArgumentValidationException {
173 validate(new String[] { "--name" }, MultipleValue.class);
174
175 }
176
177 @Test @Ignore public void testOptionAndUnparsed() throws ArgumentValidationException {
178 final OptionCollectionImpl validated =
179 validate(new String[] { "--name0", "value0", "remaining0" }, OptionAndUnparsed.class);
180 assertEquals(1, validated.getUnparsed().size());
181 }
182
183 private <O> OptionCollectionImpl validate(final String[] arguments, final Class<O> klass)
184 throws ArgumentValidationException {
185 final ArgumentValidatorImpl<O> impl = null;
186
187
188
189 final ArgumentCollectionBuilder parsedArguments = new ArgumentCollectionBuilder();
190 createDefaultArgumentParser().parseArguments(parsedArguments, arguments);
191
192 return (OptionCollectionImpl) parsedArguments.processArguments(impl);
193 }
194 }