package function.builtin; import static org.junit.Assert.assertNull; import static testutil.TestUtilities.*; import org.junit.*; import function.ArgumentValidator.*; import function.builtin.EVAL.UndefinedSymbolException; import sexpression.LispNumber; import table.*; public class SETTester { private ExecutionContext executionContext; public SETTester() { this.executionContext = ExecutionContext.getInstance(); } @Before public void setUp() { executionContext.clearContext(); } @After public void tearDown() { executionContext.clearContext(); } @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)"); } }