package com.lexicalscope.jewel.cli.examples;
import static com.lexicalscope.jewel.cli.CliFactory.parseArguments;
import static com.lexicalscope.jewel.cli.ValidationFailureMatcher.validationError;
import static com.lexicalscope.jewel.cli.ValidationFailureType.*;
import static java.lang.String.format;
import static junit.framework.Assert.fail;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;
import java.util.List;
import org.junit.Test;
import com.lexicalscope.jewel.cli.ArgumentValidationException;
import com.lexicalscope.jewel.cli.HelpRequestedException;
import com.lexicalscope.jewel.cli.Option;
import com.lexicalscope.jewel.cli.Unparsed;
/*
* Copyright 2011 Tim Wood
*
* Licensed 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.
*/
public class TestValidationFailure {
public interface HelpArugments {
@Option(helpRequest = true) boolean getHelp();
}
@Test public void testHelpRequested() throws ArgumentValidationException
{
try
{
parseArguments(HelpArugments.class, "--help");
fail("exception should have been thrown");
}
catch(final HelpRequestedException e)
{
final String expectedMessage = format("The options available are:%n\t[--help]");
assertThat(e.getMessage(), equalTo(expectedMessage));
assertThat(e.getValidationFailures(), contains(validationError(HelpRequested, expectedMessage)));
}
}
public interface InvalidValueForType {
@Option Integer getMyOption();
}
@Test public void invalidNumberThrowsException() throws ArgumentValidationException
{
try
{
parseArguments(InvalidValueForType.class, "--myOption", "wrongValue");
fail("exception should have been thrown");
}
catch(final ArgumentValidationException e)
{
final String expectedMessage = format("Invalid value (Unsupported number format: For input string: \"wrongValue\"): --myOption value");
assertThat(e.getMessage(), equalTo(expectedMessage));
assertThat(e.getValidationFailures(), contains(validationError(InvalidValueForType, expectedMessage)));
}
}
public interface MisplacedOption {
@Option Integer getMyOption();
@Unparsed List<String> getMyUnparsed();
}
@Test public void optionAfterUnparsedThrowsException() throws ArgumentValidationException
{
try
{
parseArguments(MisplacedOption.class, "myOutOfPlaceValue", "--myOption", "2");
fail("exception should have been thrown");
}
catch(final ArgumentValidationException e)
{
final String expectedMessage = format("Option not expected in this position (myOption)");
assertThat(e.getMessage(), equalTo(expectedMessage));
assertThat(e.getValidationFailures(), contains(validationError(MisplacedOption, expectedMessage)));
}
}
public interface MissingOption {
@Option Integer getMyOption();
}
@Test public void missingMandatoryOptionThrowsException() throws ArgumentValidationException
{
try
{
parseArguments(MissingOption.class);
fail("exception should have been thrown");
}
catch(final ArgumentValidationException e)
{
final String expectedMessage = format("Option is mandatory: --myOption value");
assertThat(e.getMessage(), equalTo(expectedMessage));
assertThat(e.getValidationFailures(), contains(validationError(MissingOption, expectedMessage)));
}
}
public interface MissingValue {
@Option Integer getMyOption();
}
@Test public void missingValueForOptionThrowsException() throws ArgumentValidationException
{
try
{
parseArguments(MissingValue.class, "--myOption");
fail("exception should have been thrown");
}
catch(final ArgumentValidationException e)
{
final String expectedMessage = format("Option must have a value: --myOption value");
assertThat(e.getMessage(), equalTo(expectedMessage));
assertThat(e.getValidationFailures(), contains(validationError(MissingValue, expectedMessage)));
}
}
public interface MissingValuesInListWithMinimumOfOne {
@Option(minimum = 1) List<String> getMyOption();
}
@Test public void missingValueInListWithMinimumOfOneThrowsException() throws ArgumentValidationException
{
try
{
parseArguments(MissingValuesInListWithMinimumOfOne.class, "--myOption");
fail("exception should have been thrown");
}
catch(final ArgumentValidationException e)
{
final String expectedMessage = format("Option takes at least 1 value; please specify more than []: --myOption value...");
assertThat(e.getMessage(), equalTo(expectedMessage));
assertThat(e.getValidationFailures(), contains(validationError(TooFewValues, expectedMessage)));
}
}
public interface MissingValuesInListWithMinimumOfTwo {
@Option(minimum = 2) List<String> getMyOption();
}
@Test public void missingValueInListWithMinimumOfTwoThrowsException() throws ArgumentValidationException
{
try
{
parseArguments(MissingValuesInListWithMinimumOfTwo.class, "--myOption", "myValue");
fail("exception should have been thrown");
}
catch(final ArgumentValidationException e)
{
final String expectedMessage = format("Option takes at least 2 values; please specify more than [myValue]: --myOption value...");
assertThat(e.getMessage(), equalTo(expectedMessage));
assertThat(e.getValidationFailures(), contains(validationError(TooFewValues, expectedMessage)));
}
}
public interface PatternMismatch {
@Option(pattern="\\d+") String getMyOption();
}
@Test public void valueThatDoesNotMatchThrowsException() throws ArgumentValidationException
{
try
{
parseArguments(PatternMismatch.class, "--myOption", "myBadValue");
fail("exception should have been thrown");
}
catch(final ArgumentValidationException e)
{
final String expectedMessage = format("Cannot match (myBadValue) to pattern: --myOption /\\d+/");
assertThat(e.getMessage(), equalTo(expectedMessage));
assertThat(e.getValidationFailures(), contains(validationError(PatternMismatch, expectedMessage)));
}
}
/*
UnableToConstructType
*/
public interface UnexpectedAdditionalValue {
@Option String getMyOption();
@Option String getMyOtherOption();
}
@Test public void unusedAdditionalValueThrowsException() throws ArgumentValidationException
{
try
{
parseArguments(UnexpectedAdditionalValue.class, "--myOption", "myValue", "myExcessValue", "--myOtherOption", "anotherValue");
fail("exception should have been thrown");
}
catch(final ArgumentValidationException e)
{
final String expectedMessage = format("Option only takes one value; cannot use [myExcessValue]: --myOption value");
assertThat(e.getMessage(), equalTo(expectedMessage));
assertThat(e.getValidationFailures(), contains(validationError(UnexpectedAdditionalValue, expectedMessage)));
}
}
public interface UnexpectedAdditionalValueInListWithMaximumOfOne {
@Option(maximum = 1) List<String> getMyOption();
@Option String getMyOtherOption();
}
@Test public void unexpectedAdditionalValueInListWithMaximumOfOneThrowsException() throws ArgumentValidationException
{
try
{
parseArguments(UnexpectedAdditionalValueInListWithMaximumOfOne.class, "--myOption", "myValue", "myExcessValue", "--myOtherOption", "anotherValue");
fail("exception should have been thrown");
}
catch(final ArgumentValidationException e)
{
final String expectedMessage = format("Option takes at most 1 value; please remove [myExcessValue]: --myOption value...");
assertThat(e.getMessage(), equalTo(expectedMessage));
assertThat(e.getValidationFailures(), contains(validationError(TooManyValues, expectedMessage)));
}
}
public interface UnexpectedAdditionalValueInListWithMaximumOfTwo {
@Option(maximum = 2) List<String> getMyOption();
@Option String getMyOtherOption();
}
@Test public void unexpectedAdditionalValueInListWithMaximumOfTwoThrowsException() throws ArgumentValidationException
{
try
{
parseArguments(UnexpectedAdditionalValueInListWithMaximumOfTwo.class, "--myOption", "myValue", "myOtherValue", "myExcessValue", "--myOtherOption", "anotherValue");
fail("exception should have been thrown");
}
catch(final ArgumentValidationException e)
{
final String expectedMessage = format("Option takes at most 2 values; please remove [myExcessValue]: --myOption value...");
assertThat(e.getMessage(), equalTo(expectedMessage));
assertThat(e.getValidationFailures(), contains(validationError(TooManyValues, expectedMessage)));
}
}
public interface UnexpectedAdditionalValueInListWithExactArity {
@Option(exactly = 1) List<String> getMyOption();
@Option String getMyOtherOption();
}
@Test public void unexpectedAdditionalValueInListWithExactArityThrowsException() throws ArgumentValidationException
{
try
{
parseArguments(UnexpectedAdditionalValueInListWithExactArity.class, "--myOption", "myValue", "myExcessValue", "--myOtherOption", "anotherValue");
fail("exception should have been thrown");
}
catch(final ArgumentValidationException e)
{
final String expectedMessage = format("Option takes exactly 1 value; please remove [myExcessValue]: --myOption value...");
assertThat(e.getMessage(), equalTo(expectedMessage));
assertThat(e.getValidationFailures(), contains(validationError(TooManyValues, expectedMessage)));
}
}
public interface UnexpectedAdditionalValueInListWithExactMultiValuedArity {
@Option(exactly = 2) List<String> getMyOption();
@Option String getMyOtherOption();
}
@Test public void unexpectedAdditionalValueInListWithExactMultiValuedArityThrowsException() throws ArgumentValidationException
{
try
{
parseArguments(UnexpectedAdditionalValueInListWithExactMultiValuedArity.class, "--myOption", "myValue", "myOtherValue", "myExcessValue", "--myOtherOption", "anotherValue");
fail("exception should have been thrown");
}
catch(final ArgumentValidationException e)
{
final String expectedMessage = format("Option takes exactly 2 values; please remove [myExcessValue]: --myOption value...");
assertThat(e.getMessage(), equalTo(expectedMessage));
assertThat(e.getValidationFailures(), contains(validationError(TooManyValues, expectedMessage)));
}
}
public interface UnexpectedAdditionalUnparsedValue {
@Option Integer getMyOption();
@Unparsed String getMyUnparsed();
}
@Test public void unusedUnparsedValueThrowsException() throws ArgumentValidationException
{
try
{
parseArguments(UnexpectedAdditionalUnparsedValue.class, "--myOption", "myValue", "anotherValue", "myExcessValue");
fail("exception should have been thrown");
}
catch(final ArgumentValidationException e)
{
final String expectedMessage = format("Option only takes one value; cannot use [myExcessValue]: ARGUMENTS");
assertThat(e.getMessage(), equalTo(expectedMessage));
assertThat(e.getValidationFailures(), contains(validationError(UnexpectedAdditionalValue, expectedMessage)));
}
}
public interface UnexpectedOption {
@Option String getMyOption();
}
@Test public void unexpectedOptionThrowsException() throws ArgumentValidationException
{
try
{
parseArguments(UnexpectedOption.class, "--myOption", "myValue", "--myOtherOption", "anotherValue");
fail("exception should have been thrown");
}
catch(final ArgumentValidationException e)
{
final String expectedMessage = format("Unexpected Option: myOtherOption");
assertThat(e.getMessage(), equalTo(expectedMessage));
assertThat(e.getValidationFailures(), contains(validationError(UnexpectedOption, expectedMessage)));
}
}
public interface UnexpectedTrailingValue {
@Option String getMyOption();
}
@Test public void unexpectedTrailingValueThrowsException() throws ArgumentValidationException
{
try
{
parseArguments(UnexpectedTrailingValue.class, "--myOption", "myValue", "anotherValue");
fail("exception should have been thrown");
}
catch(final ArgumentValidationException e)
{
final String expectedMessage = format("Option only takes one value; cannot use [anotherValue]: --myOption value");
assertThat(e.getMessage(), equalTo(expectedMessage));
assertThat(e.getValidationFailures(), contains(validationError(UnexpectedAdditionalValue, expectedMessage)));
}
}
@Test public void multipleUnexpectedTrailingValuesThrowsException() throws ArgumentValidationException
{
try
{
parseArguments(UnexpectedTrailingValue.class, "--myOption", "myValue", "anotherValue", "yetAnotherValue");
fail("exception should have been thrown");
}
catch(final ArgumentValidationException e)
{
final String expectedMessage = format("Option only takes one value; cannot use [anotherValue, yetAnotherValue]: --myOption value");
assertThat(e.getMessage(), equalTo(expectedMessage));
assertThat(e.getValidationFailures(), contains(validationError(UnexpectedAdditionalValue, expectedMessage)));
}
}
public interface UnexpectedValue {
@Option boolean getMyOption();
@Option String getMyOtherOption();
}
@Test public void unexpectedValueThrowsException() throws ArgumentValidationException
{
try
{
parseArguments(UnexpectedValue.class, "--myOption", "myValue", "--myOtherOption", "myOtherValue");
fail("exception should have been thrown");
}
catch(final ArgumentValidationException e)
{
final String expectedMessage = format("Option does not take a value; cannot use (myValue): [--myOption]");
assertThat(e.getMessage(), equalTo(expectedMessage));
assertThat(e.getValidationFailures(), contains(validationError(UnexpectedValue, expectedMessage)));
}
}
@Test public void multipleUnexpectedValuesThrowsException() throws ArgumentValidationException
{
try
{
parseArguments(UnexpectedValue.class, "--myOption", "myRougeValue", "myOtherRougeValue", "--myOtherOption", "myOtherValue");
fail("exception should have been thrown");
}
catch(final ArgumentValidationException e)
{
final String expectedMessage = format("Option does not take any values; cannot use [myRougeValue, myOtherRougeValue]: [--myOption]");
assertThat(e.getMessage(), equalTo(expectedMessage));
assertThat(e.getValidationFailures(), contains(validationError(UnexpectedValue, expectedMessage)));
}
}
}