Resolves #13 - Exclusion based on type in ArgumentValidator
This commit is contained in:
parent
ef4c03a672
commit
d55ebdd22f
|
@ -12,18 +12,20 @@ public class ArgumentValidator {
|
||||||
|
|
||||||
private Class<? extends SExpression> firstArgumentType;
|
private Class<? extends SExpression> firstArgumentType;
|
||||||
private Class<? extends SExpression> trailingArgumentType;
|
private Class<? extends SExpression> trailingArgumentType;
|
||||||
|
private Class<? extends SExpression> excludedFirstArgumentType;
|
||||||
|
private Class<? extends SExpression> excludedTrailingArgumentType;
|
||||||
private String functionName;
|
private String functionName;
|
||||||
private BigInteger maximumNumberOfArguments;
|
private BigInteger maximumNumberOfArguments;
|
||||||
private BigInteger minimumNumberOfArguments;
|
private BigInteger minimumNumberOfArguments;
|
||||||
private boolean isNilAcceptable;
|
|
||||||
|
|
||||||
public ArgumentValidator(String functionName) {
|
public ArgumentValidator(String functionName) {
|
||||||
this.firstArgumentType = SExpression.class;
|
this.firstArgumentType = SExpression.class;
|
||||||
this.trailingArgumentType = SExpression.class;
|
this.trailingArgumentType = SExpression.class;
|
||||||
|
this.excludedFirstArgumentType = null;
|
||||||
|
this.excludedTrailingArgumentType = null;
|
||||||
this.functionName = functionName;
|
this.functionName = functionName;
|
||||||
this.minimumNumberOfArguments = null;
|
this.minimumNumberOfArguments = null;
|
||||||
this.maximumNumberOfArguments = null;
|
this.maximumNumberOfArguments = null;
|
||||||
this.isNilAcceptable = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setFirstArgumentExpectedType(Class<? extends SExpression> argumentType) {
|
public void setFirstArgumentExpectedType(Class<? extends SExpression> argumentType) {
|
||||||
|
@ -39,6 +41,19 @@ public class ArgumentValidator {
|
||||||
this.trailingArgumentType = argumentType;
|
this.trailingArgumentType = argumentType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setFirstArgumentExcludedType(Class<? extends SExpression> argumentType) {
|
||||||
|
this.excludedFirstArgumentType = argumentType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTrailingArgumentExcludedType(Class<? extends SExpression> argumentType) {
|
||||||
|
this.excludedTrailingArgumentType = argumentType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEveryArgumentExcludedType(Class<? extends SExpression> argumentType) {
|
||||||
|
this.excludedFirstArgumentType = argumentType;
|
||||||
|
this.excludedTrailingArgumentType = argumentType;
|
||||||
|
}
|
||||||
|
|
||||||
public void setMaximumNumberOfArguments(int maximumNumberOfArguments) {
|
public void setMaximumNumberOfArguments(int maximumNumberOfArguments) {
|
||||||
this.maximumNumberOfArguments = BigInteger.valueOf(maximumNumberOfArguments);
|
this.maximumNumberOfArguments = BigInteger.valueOf(maximumNumberOfArguments);
|
||||||
}
|
}
|
||||||
|
@ -52,10 +67,6 @@ public class ArgumentValidator {
|
||||||
this.maximumNumberOfArguments = BigInteger.valueOf(exactNumberOfArguments);
|
this.maximumNumberOfArguments = BigInteger.valueOf(exactNumberOfArguments);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void doNotAcceptNil() {
|
|
||||||
this.isNilAcceptable = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void validate(Cons argumentList) {
|
public void validate(Cons argumentList) {
|
||||||
validateListNotDotted(argumentList);
|
validateListNotDotted(argumentList);
|
||||||
validateListLength(argumentList);
|
validateListLength(argumentList);
|
||||||
|
@ -118,11 +129,11 @@ public class ArgumentValidator {
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isExpectedFirstArgumentType(SExpression firstArgument) {
|
private boolean isExpectedFirstArgumentType(SExpression firstArgument) {
|
||||||
return firstArgumentType.isInstance(firstArgument) && !isDisallowedNil(firstArgument);
|
return firstArgumentType.isInstance(firstArgument) && !isExcludedFirstArgumentType(firstArgument);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isDisallowedNil(SExpression argument) {
|
private boolean isExcludedFirstArgumentType(SExpression firstArgument) {
|
||||||
return !isNilAcceptable && argument.isNull();
|
return excludedFirstArgumentType != null && excludedFirstArgumentType.isInstance(firstArgument);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void validateTrailingArguments(Cons argumentList) {
|
private void validateTrailingArguments(Cons argumentList) {
|
||||||
|
@ -132,7 +143,11 @@ public class ArgumentValidator {
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isExpectedTrailingArgumentType(SExpression trailingArgument) {
|
private boolean isExpectedTrailingArgumentType(SExpression trailingArgument) {
|
||||||
return trailingArgumentType.isInstance(trailingArgument) && !isDisallowedNil(trailingArgument);
|
return trailingArgumentType.isInstance(trailingArgument) && !isExcludedTrailingArgumentType(trailingArgument);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isExcludedTrailingArgumentType(SExpression trailingArgument) {
|
||||||
|
return excludedTrailingArgumentType != null && excludedTrailingArgumentType.isInstance(trailingArgument);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class TooFewArgumentsException extends LispException {
|
public static class TooFewArgumentsException extends LispException {
|
||||||
|
|
|
@ -17,7 +17,7 @@ public class CASE extends LispSpecialFunction {
|
||||||
this.argumentValidator = new ArgumentValidator("CASE");
|
this.argumentValidator = new ArgumentValidator("CASE");
|
||||||
this.argumentValidator.setMinimumNumberOfArguments(1);
|
this.argumentValidator.setMinimumNumberOfArguments(1);
|
||||||
this.argumentValidator.setTrailingArgumentExpectedType(Cons.class);
|
this.argumentValidator.setTrailingArgumentExpectedType(Cons.class);
|
||||||
this.argumentValidator.doNotAcceptNil();
|
this.argumentValidator.setTrailingArgumentExcludedType(Nil.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public SExpression call(Cons argumentList) {
|
public SExpression call(Cons argumentList) {
|
||||||
|
|
|
@ -14,7 +14,7 @@ public class COND extends LispSpecialFunction {
|
||||||
public COND() {
|
public COND() {
|
||||||
this.argumentValidator = new ArgumentValidator("COND");
|
this.argumentValidator = new ArgumentValidator("COND");
|
||||||
this.argumentValidator.setEveryArgumentExpectedType(Cons.class);
|
this.argumentValidator.setEveryArgumentExpectedType(Cons.class);
|
||||||
this.argumentValidator.doNotAcceptNil();
|
this.argumentValidator.setEveryArgumentExcludedType(Nil.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public SExpression call(Cons argumentList) {
|
public SExpression call(Cons argumentList) {
|
||||||
|
|
|
@ -74,46 +74,28 @@ public class ArgumentValidatorTester {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void tooManyArgumentsException_HasCorrectSeverity() {
|
public void tooManyArgumentsException_HasCorrectAttributes() {
|
||||||
TooManyArgumentsException e = new TooManyArgumentsException("TEST", NIL);
|
TooManyArgumentsException e = new TooManyArgumentsException("TEST", NIL);
|
||||||
|
|
||||||
assertEquals(ERROR, e.getSeverity());
|
assertEquals(ERROR, e.getSeverity());
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void tooManyArgumentsException_HasMessageText() {
|
|
||||||
TooManyArgumentsException e = new TooManyArgumentsException("TEST", NIL);
|
|
||||||
|
|
||||||
assertNotNull(e.getMessage());
|
assertNotNull(e.getMessage());
|
||||||
assertTrue(e.getMessage().length() > 0);
|
assertTrue(e.getMessage().length() > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void tooFewArgumentsException_HasCorrectSeverity() {
|
public void tooFewArgumentsException_HasCorrectAttributes() {
|
||||||
TooFewArgumentsException e = new TooFewArgumentsException("TEST", NIL);
|
TooFewArgumentsException e = new TooFewArgumentsException("TEST", NIL);
|
||||||
|
|
||||||
assertEquals(ERROR, e.getSeverity());
|
assertEquals(ERROR, e.getSeverity());
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void tooFewArgumentsException_HasMessageText() {
|
|
||||||
TooFewArgumentsException e = new TooFewArgumentsException("TEST", NIL);
|
|
||||||
|
|
||||||
assertNotNull(e.getMessage());
|
assertNotNull(e.getMessage());
|
||||||
assertTrue(e.getMessage().length() > 0);
|
assertTrue(e.getMessage().length() > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void BadArgumentTypeException_HasCorrectSeverity() {
|
public void badArgumentTypeException_HasCorrectAttributes() {
|
||||||
BadArgumentTypeException e = new BadArgumentTypeException("TEST", NIL, SExpression.class);
|
BadArgumentTypeException e = new BadArgumentTypeException("TEST", NIL, SExpression.class);
|
||||||
|
|
||||||
assertEquals(ERROR, e.getSeverity());
|
assertEquals(ERROR, e.getSeverity());
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void BadArgumentTypeException_HasMessageText() {
|
|
||||||
BadArgumentTypeException e = new BadArgumentTypeException("TEST", NIL, SExpression.class);
|
|
||||||
|
|
||||||
assertNotNull(e.getMessage());
|
assertNotNull(e.getMessage());
|
||||||
assertTrue(e.getMessage().length() > 0);
|
assertTrue(e.getMessage().length() > 0);
|
||||||
}
|
}
|
||||||
|
@ -201,22 +183,40 @@ public class ArgumentValidatorTester {
|
||||||
assertTrue(e.getMessage().length() > 0);
|
assertTrue(e.getMessage().length() > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = BadArgumentTypeException.class)
|
@Test
|
||||||
public void doNotAcceptNil_ThrowsExceptionOnNilArgument() {
|
public void excludedFirstArgumentType_DoesNotAffectTrailingArguments() {
|
||||||
validator.doNotAcceptNil();
|
validator.setFirstArgumentExcludedType(Nil.class);
|
||||||
validator.validate(new Cons(T, new Cons(NIL, NIL)));
|
validator.validate(new Cons(T, new Cons(NIL, NIL)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void doNotAcceptNil_AllowsEmptyArgumentList() {
|
public void excludedTrailingArgumentType_DoesNotAffectFirstArgument() {
|
||||||
validator.doNotAcceptNil();
|
validator.setTrailingArgumentExcludedType(Nil.class);
|
||||||
validator.validate(NIL);
|
validator.validate(new Cons(NIL, new Cons(T, NIL)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test(expected = BadArgumentTypeException.class)
|
||||||
public void doNotAcceptNil_AllowsProperList() {
|
public void excludedFirstArgumentType_ThrowsException() {
|
||||||
validator.doNotAcceptNil();
|
validator.setFirstArgumentExcludedType(Nil.class);
|
||||||
validator.validate(new Cons(T, new Cons(T, NIL)));
|
validator.validate(new Cons(NIL, new Cons(T, NIL)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = BadArgumentTypeException.class)
|
||||||
|
public void excludedTrailingArgumentType_ThrowsException() {
|
||||||
|
validator.setTrailingArgumentExcludedType(Nil.class);
|
||||||
|
validator.validate(new Cons(T, new Cons(NIL, NIL)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = BadArgumentTypeException.class)
|
||||||
|
public void excludedArgumentType_ThrowsExceptionOnFirstArgument() {
|
||||||
|
validator.setEveryArgumentExcludedType(Nil.class);
|
||||||
|
validator.validate(new Cons(NIL, new Cons(T, NIL)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = BadArgumentTypeException.class)
|
||||||
|
public void excludedArgumentType_ThrowsExceptionOnTrailingArgument() {
|
||||||
|
validator.setEveryArgumentExcludedType(Nil.class);
|
||||||
|
validator.validate(new Cons(T, new Cons(NIL, NIL)));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue