package table; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static sexpression.Nil.NIL; import static sexpression.Symbol.T; import static table.FunctionTable.defineFunction; import static table.FunctionTable.isAlreadyDefined; import static table.FunctionTable.lookupFunction; import static table.FunctionTable.resetFunctionTable; import java.util.HashSet; import java.util.Set; import org.junit.After; import org.junit.Before; import org.junit.Test; import error.ErrorManager; import function.FunctionNames; import function.LispFunction; import sexpression.Cons; import sexpression.SExpression; import table.FunctionTable.LispFunctionInstantiationException; public class FunctionTableTest { @FunctionNames({ "GOOD" }) public static class GoodFunction extends LispFunction { public GoodFunction(String name) {} @Override public SExpression call(Cons argumentList) { return NIL; } } @FunctionNames({ "BAD" }) public static class BadFunction extends LispFunction { @Override public SExpression call(Cons argumentList) { return NIL; } } public static class UglyFunction extends LispFunction { @Override public SExpression call(Cons argumentList) { return NIL; } } private LispFunction createLispFunction() { return new LispFunction() { @Override public SExpression call(Cons argumentList) { return T; } }; } @Before public void setUp() { resetFunctionTable(); } @After public void tearDown() { resetFunctionTable(); } @Test public void builtInFunctionIsDefined() { assertTrue(isAlreadyDefined("CONS")); } @Test public void undefinedFunctionIsNotDefined() { assertFalse(isAlreadyDefined("undefined")); } @Test public void lookupBuiltInFunction_ReturnsFunction() { assertNotNull(lookupFunction("CONS")); } @Test public void lookupUndefinedFunction_ReturnsNull() { assertNull(lookupFunction("undefined")); } @Test public void defineFunctionWorks() { String functionName = "testFunction"; LispFunction testFunction = createLispFunction(); assertNull(lookupFunction(functionName)); assertFalse(isAlreadyDefined(functionName)); defineFunction(functionName, testFunction); assertTrue(isAlreadyDefined(functionName)); assertEquals(testFunction, lookupFunction(functionName)); } @Test public void resetFunctionTableWorks() { String functionName = "testFunction"; LispFunction testFunction = createLispFunction(); defineFunction(functionName, testFunction); resetFunctionTable(); assertFalse(isAlreadyDefined(functionName)); assertNull(lookupFunction(functionName)); } @Test public void resetWithCustomBuitIns() { Set> goodBuiltIns = new HashSet<>(); goodBuiltIns.add(GoodFunction.class); resetFunctionTable(goodBuiltIns); assertTrue(isAlreadyDefined("GOOD")); assertNotNull(lookupFunction("GOOD")); } @Test(expected = LispFunctionInstantiationException.class) public void unableToInitializeBuiltIn() { Set> badBuiltIns = new HashSet<>(); badBuiltIns.add(BadFunction.class); resetFunctionTable(badBuiltIns); } @Test public void lispFunctionInstantiationException_HasCorrectAttributes() { LispFunctionInstantiationException e = new LispFunctionInstantiationException("Bad"); assertNotNull(e.getMessage()); assertTrue(e.getMessage().length() > 0); assertEquals(ErrorManager.Severity.CRITICAL, e.getSeverity()); } @Test public void namelessBuiltIn_DoesNotCauseNPE() { Set> namelessBuiltins = new HashSet<>(); namelessBuiltins.add(UglyFunction.class); resetFunctionTable(namelessBuiltins); assertFalse(isAlreadyDefined("UGLY")); assertNull(lookupFunction("UGLY")); } }