package function.builtin;

import static table.FunctionTable.resetFunctionTable;
import static testutil.TestUtilities.*;

import org.junit.*;

import function.ArgumentValidator.TooFewArgumentsException;

public class FUNCALLTest {

    @Before
    public void setUp() {
        resetFunctionTable();
    }

    @After
    public void tearDown() {
        resetFunctionTable();
    }

    @Test
    public void funcallWithNumbers() {
        String input = "(funcall '+ 1 2 3)";

        assertSExpressionsMatch(parseString("6"), evaluateString(input));
    }

    @Test
    public void callWithNumbers() {
        String input = "(call '+ 1 2 3)";

        assertSExpressionsMatch(parseString("6"), evaluateString(input));
    }

    @Test
    public void funcallWithUserDefinedFunction() {
        String defineUserFunction = "(defun x (n m) (+ n m))";
        String input = "(funcall 'x 2 30)";

        evaluateString(defineUserFunction);
        assertSExpressionsMatch(parseString("32"), evaluateString(input));
    }

    @Test(expected = TooFewArgumentsException.class)
    public void funcallWithTooFewArguments() {
        evaluateString("(funcall)");
    }

}
