package function.builtin; import static org.junit.Assert.assertNull; import static testutil.TestUtilities.assertSExpressionsMatch; import static testutil.TestUtilities.evaluateString; import org.junit.Test; import function.ArgumentValidator.BadArgumentTypeException; import function.ArgumentValidator.TooFewArgumentsException; import function.ArgumentValidator.TooManyArgumentsException; import function.builtin.EVAL.UndefinedSymbolException; import sexpression.LispNumber; import table.SymbolTable; import testutil.SymbolAndFunctionCleaner; public class SETTest extends SymbolAndFunctionCleaner { @Test public void set() { evaluateString("(set 'a 23)"); assertSExpressionsMatch(new LispNumber("23"), evaluateString("a")); } @Test public void lookupDefinedSymbol() { evaluateString("(set 'a 23)"); assertSExpressionsMatch(new LispNumber("23"), executionContext.lookupSymbolValue("A")); } @Test public void lookupUndefinedSymbol() { assertNull(executionContext.lookupSymbolValue("A")); } @Test public void setGlobalVariable() { evaluateString("(set 'a 23)"); SymbolTable global = executionContext.getScope(); executionContext.setScope(new SymbolTable(global)); evaluateString("(set 'a 94)"); executionContext.setScope(global); assertSExpressionsMatch(new LispNumber("94"), evaluateString("a")); } @Test(expected = UndefinedSymbolException.class) public void setLocalVariableDefined_DoesNotSetGlobal() { SymbolTable global = executionContext.getScope(); SymbolTable local = new SymbolTable(global); local.put("A", new LispNumber("99")); executionContext.setScope(local); evaluateString("(set 'a 94)"); executionContext.setScope(global); evaluateString("a"); } @Test public void setLocalVariableUndefined_SetsGlobal() { SymbolTable global = executionContext.getScope(); SymbolTable local = new SymbolTable(global); executionContext.setScope(local); evaluateString("(set 'a 94)"); executionContext.setScope(global); assertSExpressionsMatch(new LispNumber("94"), evaluateString("a")); } @Test(expected = BadArgumentTypeException.class) public void setWithNonSymbol() { evaluateString("(set '1 2)"); } @Test(expected = TooFewArgumentsException.class) public void setWithTooFewArguments() { evaluateString("(set 'x)"); } @Test(expected = TooManyArgumentsException.class) public void setWithTooManyArguments() { evaluateString("(set 'a 'b 'c)"); } }