package function.builtin.special; import static testutil.TestUtilities.assertSExpressionsMatch; import static testutil.TestUtilities.evaluateString; import static testutil.TestUtilities.parseString; import org.junit.Test; import function.ArgumentValidator.BadArgumentTypeException; import function.builtin.special.RECUR.RecurOutsideOfFunctionException; import testutil.SymbolAndFunctionCleaner; public class RECURTest extends SymbolAndFunctionCleaner { @Test(expected = RecurOutsideOfFunctionException.class) public void recurOutsideOfFunction_ThrowsException() { evaluateString("(recur)"); } @Test(expected = RecurOutsideOfFunctionException.class) public void recurOutsideOfFunction_AfterFunctionCall_ThrowsException() { evaluateString("(defun f (n) (if (= n 0) 'ZERO n))"); evaluateString("(f 2)"); evaluateString("(recur)"); } @Test public void recurCallsCurrentFunction() { evaluateString("(defun tail-recursive (n) (if (= n 0) 'PASS (recur (- n 1))))"); assertSExpressionsMatch(parseString("PASS"), evaluateString("(tail-recursive 900)")); } @Test(expected = BadArgumentTypeException.class) public void recurInSpecialFunction_DoesNotEvaluateArguments() { evaluateString("(define-special tail-recursive (n) (if (= n 0) 'PASS (recur (- n 1))))"); evaluateString("(tail-recursive 900)"); } }