package function.builtin;

import static function.builtin.GENSYM.GENSYM_PREFIX;
import static testutil.TestUtilities.assertSExpressionsDoNotMatch;
import static testutil.TestUtilities.assertSExpressionsMatch;
import static testutil.TestUtilities.evaluateString;
import static testutil.TypeAssertions.assertSymbol;

import org.junit.Test;

import function.ArgumentValidator.TooManyArgumentsException;
import testutil.SymbolAndFunctionCleaner;
import token.TokenFactory.BadCharacterException;

public class GENSYMTest extends SymbolAndFunctionCleaner {

    @Test
    public void gensymCreatesSymbol() {
        assertSymbol(evaluateString("(gensym)"));
    }

    @Test
    public void gensymCreatesUniqueSymbol() {
        assertSExpressionsDoNotMatch(evaluateString("(gensym)"), evaluateString("(gensym)"));
    }

    @Test
    public void simpleGensymUsage() {
        String input = "(let ((x (gensym))) (set x 23) (eval x))";
        assertSExpressionsMatch(evaluateString("23"), evaluateString(input));
    }

    @Test(expected = BadCharacterException.class)
    public void cannotUseGensymValueManually() {
        String variableName = GENSYM_PREFIX + 1;
        evaluateString("(setq " + variableName + " 100)");
    }

    @Test(expected = TooManyArgumentsException.class)
    public void gensymWithTooManyArguments() {
        evaluateString("(gensym 1)");
    }

}
