package function.builtin.special;

import static testutil.TestUtilities.assertSExpressionsMatch;
import static testutil.TestUtilities.evaluateString;
import static testutil.TypeAssertions.assertNil;
import static testutil.TypeAssertions.assertT;

import org.junit.Test;

import function.builtin.EVAL.UndefinedSymbolException;
import sexpression.LispNumber;
import testutil.SymbolAndFunctionCleaner;

public class ORTest extends SymbolAndFunctionCleaner {

    @Test
    public void orByItself() {
        String input = "(or)";

        assertNil(evaluateString(input));
    }

    @Test
    public void orWithNil() {
        String input = "(or nil)";

        assertNil(evaluateString(input));
    }

    @Test
    public void orWithT() {
        String input = "(or t)";

        assertT(evaluateString(input));
    }

    @Test
    public void orWithNumber() {
        String input = "(or 7)";

        assertSExpressionsMatch(new LispNumber("7"), evaluateString(input));
    }

    @Test
    public void orWithSeveralValues() {
        String input = "(or nil nil nil t nil)";

        assertT(evaluateString(input));
    }

    @Test
    public void orWithSeveralNumbers() {
        String input = "(or 1 2 3)";

        assertSExpressionsMatch(new LispNumber("1"), evaluateString(input));
    }

    @Test(expected = UndefinedSymbolException.class)
    public void orShortCircuits() {
        String input = "(or t (setq x 22))";

        assertT(evaluateString(input));
        evaluateString("x");
    }

}
