transcendental-lisp/test/function/builtin/BackquoteEvaluatorTest.java

160 lines
6.1 KiB
Java

package function.builtin;
import static sexpression.Nil.NIL;
import static sexpression.Symbol.T;
import static testutil.TestUtilities.*;
import org.junit.Test;
import function.ArgumentValidator.DottedArgumentListException;
import function.builtin.BackquoteEvaluator.*;
import sexpression.*;
public class BackquoteEvaluatorTest {
private BackquoteEvaluator createBackquoteEvaluator(SExpression expression) {
return new BackquoteEvaluator(new BackquoteExpression(expression));
}
@Test
public void evaluateNil() {
BackquoteEvaluator evaluator = createBackquoteEvaluator(NIL);
assertSExpressionsMatch(NIL, evaluator.evaluate());
}
@Test
public void evaluateNumber() {
SExpression input = new LispNumber("99");
BackquoteEvaluator evaluator = createBackquoteEvaluator(input);
assertSExpressionsMatch(input, evaluator.evaluate());
}
@Test
public void evaluateList() {
SExpression input = makeList(new LispNumber("1"), new LispNumber("99"));
BackquoteEvaluator evaluator = createBackquoteEvaluator(input);
assertSExpressionsMatch(input, evaluator.evaluate());
}
@Test
public void evaluateComma() {
SExpression input = new CommaExpression(makeList(new Symbol("+"), new LispNumber("1"), new LispNumber("9")));
BackquoteEvaluator evaluator = createBackquoteEvaluator(input);
assertSExpressionsMatch(new LispNumber("10"), evaluator.evaluate());
}
@Test
public void evaluateListWithComma() {
SExpression input = makeList(new CommaExpression(makeList(new Symbol("+"), new LispNumber("1"),
new LispNumber("9"))));
BackquoteEvaluator evaluator = createBackquoteEvaluator(input);
assertSExpressionsMatch(makeList(new LispNumber("10")), evaluator.evaluate());
}
@Test(expected = NestedCommaException.class)
public void evaluateListWithNestedComma() {
SExpression input = makeList(new CommaExpression(new CommaExpression(new Symbol("+"))));
BackquoteEvaluator evaluator = createBackquoteEvaluator(input);
evaluator.evaluate();
}
@Test(expected = AtSignNotInCommaException.class)
public void evaluateListWithNoCommaPrecedingAtSign() {
SExpression input = makeList(new AtSignExpression(makeList(new Symbol("+"))));
BackquoteEvaluator evaluator = createBackquoteEvaluator(input);
evaluator.evaluate();
}
@Test(expected = AtSignNotInCommaException.class)
public void evaluateAtSign() {
SExpression input = new AtSignExpression(makeList(new Symbol("+")));
BackquoteEvaluator evaluator = createBackquoteEvaluator(input);
evaluator.evaluate();
}
@Test(expected = NestedAtSignException.class)
public void evaluateListWithNestedAtSigns() {
SExpression input = makeList(new CommaExpression(new AtSignExpression(new AtSignExpression(makeList(new Symbol("+"))))));
BackquoteEvaluator evaluator = createBackquoteEvaluator(input);
evaluator.evaluate();
}
@Test(expected = NestedCommaException.class)
public void evaluateListWithCommaAfterAtSign() {
SExpression input = makeList(new CommaExpression(new AtSignExpression(new CommaExpression(makeList(new Symbol("+"))))));
BackquoteEvaluator evaluator = createBackquoteEvaluator(input);
evaluator.evaluate();
}
@Test
public void evaluateListWithAtSign() {
SExpression input = makeList(new CommaExpression(new AtSignExpression(makeList(new Symbol("LIST"),
new LispNumber("1"),
new LispNumber("9")))));
SExpression expected = makeList(new LispNumber("1"), new LispNumber("9"));
BackquoteEvaluator evaluator = createBackquoteEvaluator(input);
assertSExpressionsMatch(expected, evaluator.evaluate());
}
@Test(expected = AtSignNotListException.class)
public void atSignDoesNotEvaluateToList() {
SExpression input = makeList(new CommaExpression(new AtSignExpression(new LispNumber("1"))));
BackquoteEvaluator evaluator = createBackquoteEvaluator(input);
evaluator.evaluate();
}
@Test
public void evaluateListWithCommasAndAtSign() {
Cons list1 = makeList(new Symbol("LIST"), new LispNumber("1"), new LispNumber("9"));
Cons list2 = makeList(new Symbol("+"), new LispNumber("20"), new LispNumber("5"));
Cons list3 = makeList(new Symbol("LIST"), new LispNumber("7"), new LispNumber("6"));
SExpression input = makeList(new LispNumber("78"), new CommaExpression(new AtSignExpression(list1)),
new CommaExpression(list2), new CommaExpression(list3), new LispString("\"sky\""));
SExpression expected = makeList(new LispNumber("78"), new LispNumber("1"), new LispNumber("9"),
new LispNumber("25"), makeList(new LispNumber("7"), new LispNumber("6")),
new LispString("\"sky\""));
BackquoteEvaluator evaluator = createBackquoteEvaluator(input);
assertSExpressionsMatch(expected, evaluator.evaluate());
}
@Test(expected = DottedArgumentListException.class)
public void evaluateDottedList() {
BackquoteEvaluator evaluator = createBackquoteEvaluator(new Cons(T, T));
evaluator.evaluate();
}
@Test(expected = DottedArgumentListException.class)
public void atSignWithDottedList() {
SExpression input = makeList(new CommaExpression(new AtSignExpression(makeList(new Symbol("CONS"), T, T))));
BackquoteEvaluator evaluator = createBackquoteEvaluator(input);
evaluator.evaluate();
}
@Test
public void backquoteExceptionsHaveCorrectAttributes() {
assertIsErrorWithMessage(new NestedCommaException());
assertIsErrorWithMessage(new NestedAtSignException());
assertIsErrorWithMessage(new AtSignNotInCommaException());
assertIsErrorWithMessage(new AtSignNotListException());
}
}