package table; import static org.junit.Assert.*; import static sexpression.Nil.NIL; import static sexpression.Symbol.T; import static table.FunctionTable.*; import java.util.*; import org.junit.*; import error.ErrorManager; import function.*; import sexpression.*; import table.FunctionTable.LispFunctionInstantiationException; public class FunctionTableTester { @FunctionNames({ "GOOD" }) public static class GoodFunction extends LispFunction { @Override public SExpression call(Cons argList) { return NIL; } } @FunctionNames({ "BAD" }) public static class BadFunction extends LispFunction { public BadFunction() { throw new IllegalArgumentException("bad function"); } @Override public SExpression call(Cons argList) { return NIL; } } public static class UglyFunction extends LispFunction { @Override public SExpression call(Cons argList) { return NIL; } } private LispFunction createLispFunction() { return new LispFunction() { @Override public SExpression call(Cons argList) { 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")); } }