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
	
	Block a user