diff --git a/src/table/FunctionTable.java b/src/table/FunctionTable.java index 6366e4f..d00388a 100644 --- a/src/table/FunctionTable.java +++ b/src/table/FunctionTable.java @@ -25,15 +25,19 @@ public class FunctionTable { uniqueInstance.functionTable.put(functionName, function); } + public static void reset() { + uniqueInstance.initializeFunctionTable(); + } + private HashMap functionTable; private FunctionTable() { - this.functionTable = new HashMap<>(); - initializeFunctionTable(); } private void initializeFunctionTable() { + functionTable = new HashMap<>(); + functionTable.put("*", new MULTIPLY()); functionTable.put("+", new PLUS()); functionTable.put("-", new MINUS()); diff --git a/test/function/builtin/FUNCALLTester.java b/test/function/builtin/FUNCALLTester.java index f14bee7..7c2d676 100644 --- a/test/function/builtin/FUNCALLTester.java +++ b/test/function/builtin/FUNCALLTester.java @@ -2,12 +2,23 @@ package function.builtin; import static testutil.TestUtilities.*; -import org.junit.Test; +import org.junit.*; import function.ArgumentValidator.TooFewArgumentsException; +import table.FunctionTable; public class FUNCALLTester { + @Before + public void setUp() { + FunctionTable.reset(); + } + + @After + public void tearDown() { + FunctionTable.reset(); + } + @Test public void testFuncallWithNumbers() { String input = "(funcall '+ 1 2 3)"; diff --git a/test/function/builtin/SYMBOL_FUNCTIONTester.java b/test/function/builtin/SYMBOL_FUNCTIONTester.java index 593fbe0..1cf33f4 100644 --- a/test/function/builtin/SYMBOL_FUNCTIONTester.java +++ b/test/function/builtin/SYMBOL_FUNCTIONTester.java @@ -3,14 +3,25 @@ package function.builtin; import static org.junit.Assert.*; import static testutil.TestUtilities.evaluateString; -import org.junit.Test; +import org.junit.*; import function.ArgumentValidator.*; import function.builtin.SYMBOL_FUNCTION.UndefinedSymbolFunctionException; import sexpression.Nil; +import table.FunctionTable; public class SYMBOL_FUNCTIONTester { + @Before + public void setUp() { + FunctionTable.reset(); + } + + @After + public void tearDown() { + FunctionTable.reset(); + } + @Test public void testSymbolFunction_BuiltinFunction() { String input = "(symbol-function '+)"; diff --git a/test/function/builtin/special/DEFUNTester.java b/test/function/builtin/special/DEFUNTester.java index 4e2163a..d23f6a3 100644 --- a/test/function/builtin/special/DEFUNTester.java +++ b/test/function/builtin/special/DEFUNTester.java @@ -9,6 +9,7 @@ import org.junit.*; import environment.Environment; import function.ArgumentValidator.*; +import table.FunctionTable; public class DEFUNTester { @@ -22,6 +23,12 @@ public class DEFUNTester { public void setUp() { this.outputStream = new ByteArrayOutputStream(); Environment.getInstance().setOutput(new PrintStream(outputStream)); + FunctionTable.reset(); + } + + @After + public void tearDown() { + FunctionTable.reset(); } @Test diff --git a/test/table/ExecutionContextTester.java b/test/table/ExecutionContextTester.java new file mode 100644 index 0000000..2da0d9e --- /dev/null +++ b/test/table/ExecutionContextTester.java @@ -0,0 +1,84 @@ +package table; + +import static org.junit.Assert.*; + +import org.junit.*; + +import sexpression.*; + +public class ExecutionContextTester { + + private ExecutionContext executionContext; + + public ExecutionContextTester() { + this.executionContext = ExecutionContext.getInstance(); + } + + @Before + public void setUp() { + executionContext.clearContext(); + } + + @After + public void tearDown() { + executionContext.clearContext(); + } + + @Test + public void assignANewScope() { + SymbolTable scope = new SymbolTable(); + executionContext.setScope(scope); + + assertEquals(scope, executionContext.getScope()); + } + + @Test + public void clearContext() { + SymbolTable scope = new SymbolTable(); + executionContext.setScope(scope); + + assertEquals(scope, executionContext.getScope()); + executionContext.clearContext(); + assertNotEquals(scope, executionContext.getScope()); + assertNull(executionContext.getScope().getParent()); + } + + @Test + public void lookupVariable() { + executionContext.getScope().put("test", Symbol.T); + + assertEquals(Symbol.T, executionContext.lookupSymbolValue("test")); + } + + @Test + public void lookupLocalVariable() { + SymbolTable scope = new SymbolTable(executionContext.getScope()); + + scope.put("local", Symbol.T); + executionContext.setScope(scope); + + assertEquals(Symbol.T, executionContext.lookupSymbolValue("local")); + } + + @Test + public void lookupGlobalVariable() { + SymbolTable scope = new SymbolTable(executionContext.getScope()); + + executionContext.getScope().put("global", Symbol.T); + executionContext.setScope(scope); + + assertEquals(Symbol.T, executionContext.lookupSymbolValue("global")); + } + + @Test + public void lookupShadowedVariable() { + SymbolTable scope = new SymbolTable(executionContext.getScope()); + + scope.put("shadowed", Nil.getInstance()); + executionContext.getScope().put("shadowed", Symbol.T); + executionContext.setScope(scope); + + assertEquals(Nil.getInstance(), executionContext.lookupSymbolValue("shadowed")); + } + +} diff --git a/test/table/FunctionTableTester.java b/test/table/FunctionTableTester.java new file mode 100644 index 0000000..6528834 --- /dev/null +++ b/test/table/FunctionTableTester.java @@ -0,0 +1,77 @@ +package table; + +import static org.junit.Assert.*; + +import org.junit.*; + +import function.LispFunction; +import sexpression.*; + +public class FunctionTableTester { + + private LispFunction createLispFunction() { + return new LispFunction() { + + @Override + public SExpression call(Cons argList) { + return Symbol.T; + } + }; + } + + @Before + public void setUp() { + FunctionTable.reset(); + } + + @After + public void tearDown() { + FunctionTable.reset(); + } + + @Test + public void builtinFunctionIsDefined() { + assertTrue(FunctionTable.isAlreadyDefined("CONS")); + } + + @Test + public void undefinedFunctionIsNotDefined() { + assertFalse(FunctionTable.isAlreadyDefined("undefined")); + } + + @Test + public void lookupBuiltinFunction_ReturnsFunction() { + assertNotNull(FunctionTable.lookupFunction("CONS")); + } + + @Test + public void lookupUndefinedFunction_ReturnsNull() { + assertNull(FunctionTable.lookupFunction("undefined")); + } + + @Test + public void defineFunction() { + String functionName = "testFunction"; + LispFunction testFunction = createLispFunction(); + + assertNull(FunctionTable.lookupFunction(functionName)); + assertFalse(FunctionTable.isAlreadyDefined(functionName)); + + FunctionTable.defineFunction(functionName, testFunction); + + assertTrue(FunctionTable.isAlreadyDefined(functionName)); + assertEquals(testFunction, FunctionTable.lookupFunction(functionName)); + } + + @Test + public void resetFunctionTable() { + String functionName = "testFunction"; + LispFunction testFunction = createLispFunction(); + FunctionTable.defineFunction(functionName, testFunction); + FunctionTable.reset(); + + assertFalse(FunctionTable.isAlreadyDefined(functionName)); + assertNull(FunctionTable.lookupFunction(functionName)); + } + +} diff --git a/test/table/SymbolTableTester.java b/test/table/SymbolTableTester.java index 29a1e4d..85f98b4 100644 --- a/test/table/SymbolTableTester.java +++ b/test/table/SymbolTableTester.java @@ -11,7 +11,7 @@ public class SymbolTableTester { private SymbolTable symbolTable; @Before - public void setUp() throws Exception { + public void setUp() { symbolTable = new SymbolTable(); } @@ -23,12 +23,14 @@ public class SymbolTableTester { @Test public void lookupSymbolInTable() { symbolTable.put("symbol", Symbol.T); + assertTrue(symbolTable.contains("symbol")); } @Test public void retrieveSymbolValue() { symbolTable.put("symbol", Symbol.T); + assertEquals(Symbol.T, symbolTable.get("symbol")); } @@ -36,6 +38,7 @@ public class SymbolTableTester { public void redefineSymbolValue() { symbolTable.put("symbol", Symbol.T); symbolTable.put("symbol", Nil.getInstance()); + assertEquals(Nil.getInstance(), symbolTable.get("symbol")); }