transcendental-lisp/test/function/builtin/special/LAMBDATest.java

152 lines
4.8 KiB
Java
Raw Normal View History

2017-01-27 14:31:41 -05:00
package function.builtin.special;
2017-11-12 09:42:25 -05:00
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static sexpression.LispNumber.ONE;
import static sexpression.Nil.NIL;
import static sexpression.Symbol.T;
2017-11-12 09:42:25 -05:00
import static testutil.TestUtilities.assertSExpressionsMatch;
import static testutil.TestUtilities.evaluateString;
import static testutil.TestUtilities.parseString;
2017-01-27 14:31:41 -05:00
import org.junit.Test;
2017-11-12 09:42:25 -05:00
import function.ArgumentValidator.BadArgumentTypeException;
import function.ArgumentValidator.DottedArgumentListException;
import function.ArgumentValidator.TooFewArgumentsException;
import function.ArgumentValidator.TooManyArgumentsException;
2018-03-15 18:48:33 -04:00
import function.builtin.EVAL.UndefinedFunctionException;
2017-11-12 09:42:25 -05:00
import sexpression.Cons;
import sexpression.LispNumber;
import sexpression.Symbol;
import testutil.SymbolAndFunctionCleaner;
2017-01-27 14:31:41 -05:00
public class LAMBDATest extends SymbolAndFunctionCleaner {
2017-01-27 14:31:41 -05:00
@Test
public void lambda() {
2017-01-27 14:31:41 -05:00
String input = "(lambda (x) x)";
assertSExpressionsMatch(parseString("(LAMBDA (X) X)"), evaluateString(input));
}
@Test
public void lambdaSymbol() {
String input = "(λ (x) x)";
assertSExpressionsMatch(parseString("(LAMBDA (X) X)"), evaluateString(input));
}
@Test
public void lambdaWithNoBody() {
String input = "(lambda ())";
assertSExpressionsMatch(parseString("(LAMBDA ())"), evaluateString(input));
}
2017-01-27 14:31:41 -05:00
@Test
public void lambdaExpressionIsLambdaExpression() {
Cons lambdaExpression = new Cons(new Symbol("LAMBDA"), new Cons(NIL, new Cons(NIL, NIL)));
2017-01-27 14:31:41 -05:00
assertTrue(LAMBDA.isLambdaExpression(lambdaExpression));
}
@Test
public void somethingElseIsNotLambdaExpression() {
assertFalse(LAMBDA.isLambdaExpression(T));
2017-01-27 14:31:41 -05:00
}
@Test
public void createLambdaExpression() {
Cons lambdaExpression = new Cons(new Symbol("LAMBDA"), new Cons(NIL, new Cons(NIL, NIL)));
2017-01-27 14:31:41 -05:00
assertSExpressionsMatch(parseString("(:LAMBDA () ())"),
LAMBDA.createFunction(lambdaExpression).getLambdaExpression());
}
@Test(expected = DottedArgumentListException.class)
public void lambdaWithDottedArgumentList() {
2017-01-27 14:31:41 -05:00
String input = "(apply 'lambda (cons '(x) 1))";
evaluateString(input);
}
@Test(expected = DottedArgumentListException.class)
public void lambdaWithDottedLambdaList() {
String input = "(funcall 'lambda (cons 'a 'b) ())";
evaluateString(input);
}
2017-01-27 14:31:41 -05:00
@Test(expected = DottedArgumentListException.class)
public void createFunctionWithDottedArgumentList() {
Cons lambdaExpression = new Cons(new Symbol("LAMBDA"), new Cons(NIL, ONE));
2017-01-27 14:31:41 -05:00
LAMBDA.createFunction(lambdaExpression);
}
@Test(expected = BadArgumentTypeException.class)
public void createFunctionWithNonList() {
Cons lambdaExpression = new Cons(new Symbol("LAMBDA"), ONE);
2017-01-27 14:31:41 -05:00
LAMBDA.createFunction(lambdaExpression);
}
@Test(expected = BadArgumentTypeException.class)
public void lambdaWithNonSymbolParameter() {
evaluateString("(lambda (1) ())");
}
2017-01-27 14:31:41 -05:00
@Test(expected = TooFewArgumentsException.class)
public void lambdaWithTooFewArguments() {
evaluateString("(lambda)");
2017-01-27 14:31:41 -05:00
}
@Test
public void anonymousLambdaCall() {
String input = "((lambda (x) x) 203)";
assertSExpressionsMatch(new LispNumber("203"), evaluateString(input));
}
@Test
public void anonymousLambdaCallWithMultipleArguments() {
String input = "((lambda (x y) (+ x y)) 203 2)";
assertSExpressionsMatch(new LispNumber("205"), evaluateString(input));
}
@Test
public void anonymousLambdaCallWithSymbol() {
String input = "((λ (x) (+ x 1)) 3)";
assertSExpressionsMatch(new LispNumber("4"), evaluateString(input));
}
@Test(expected = TooFewArgumentsException.class)
public void anonymousLambdaCallWithTooFewArguments() {
evaluateString("((lambda (x) x))");
}
@Test(expected = TooManyArgumentsException.class)
public void anonymousLambdaCallWithTooManyArguments() {
evaluateString("((lambda (x y) x) 1 2 3)");
}
2018-03-15 18:48:33 -04:00
@Test(expected = UndefinedFunctionException.class)
public void badAnonymousFunctionCall() {
evaluateString("((bad-lambda (x y) x) 1 2 3)");
}
@Test
public void lexicalClosure() {
2017-03-07 16:41:26 -05:00
evaluateString("(setq increment-count (let ((counter 0)) (lambda () (setq counter (+ 1 counter)))))");
assertSExpressionsMatch(parseString("1"), evaluateString("(funcall increment-count)"));
assertSExpressionsMatch(parseString("2"), evaluateString("(funcall increment-count)"));
assertSExpressionsMatch(parseString("3"), evaluateString("(funcall increment-count)"));
assertSExpressionsMatch(parseString("4"), evaluateString("(funcall increment-count)"));
}
2017-01-27 14:31:41 -05:00
}