Refactored some code and added unit tests

This commit is contained in:
Mike Cifelli 2017-01-18 16:25:09 -05:00
parent b700b714f3
commit ea8acd423f
12 changed files with 103 additions and 27 deletions

View File

@ -13,7 +13,8 @@ public class Environment {
private InputStream input;
private PrintStream output;
private PrintStream errorOutput;
private Runnable terminate;
private Runnable terminationFunction;
private Runnable errorTerminationFunction;
private Environment() {}
@ -29,8 +30,12 @@ public class Environment {
this.errorOutput = errorOutput;
}
public void setTerminate(Runnable terminate) {
this.terminate = terminate;
public void setTerminationFunction(Runnable terminationFunction) {
this.terminationFunction = terminationFunction;
}
public void setErrorTerminationFunction(Runnable errorTerminationFunction) {
this.errorTerminationFunction = errorTerminationFunction;
}
public InputStream getInput() {
@ -49,8 +54,12 @@ public class Environment {
return errorOutput;
}
public void terminate() {
terminate.run();
public void terminateSuccessfully() {
terminationFunction.run();
}
public void terminateExceptionally() {
errorTerminationFunction.run();
}
}

View File

@ -26,7 +26,7 @@ public class ErrorManager {
printError(lispException);
if (isCritical(lispException))
environment.terminate();
environment.terminateExceptionally();
}
private void printError(LispException lispException) {

View File

@ -1,22 +1,25 @@
package function.builtin;
import environment.Environment;
import function.*;
import sexpression.*;
public class EXIT extends LispFunction {
private ArgumentValidator argumentValidator;
private Environment environment;
public EXIT() {
this.argumentValidator = new ArgumentValidator("EXIT");
this.argumentValidator.setMaximumNumberOfArguments(0);
this.environment = Environment.getInstance();
}
public SExpression call(Cons argumentList) {
argumentValidator.validate(argumentList);
System.exit(0);
environment.terminateSuccessfully();
return null;
return Nil.getInstance();
}
}

View File

@ -15,8 +15,9 @@ public class PRINT extends LispFunction {
this.environment = Environment.getInstance();
}
public SExpression call(Cons argList) {
SExpression argument = argList.getCar();
public SExpression call(Cons argumentList) {
argumentValidator.validate(argumentList);
SExpression argument = argumentList.getCar();
environment.getOutput().println(argument);
return argument;

View File

@ -10,7 +10,9 @@ public interface LispInterpreterBuilder {
void setErrorOutput(PrintStream errorOutputStream);
void setTerminate(Runnable terminationFunction);
void setTerminationFunction(Runnable terminationFunction);
void setErrorTerminationFunction(Runnable errorTerminationFunction);
void useFile(String fileName);

View File

@ -33,10 +33,16 @@ public class LispInterpreterBuilderImpl implements LispInterpreterBuilder {
}
@Override
public void setTerminate(Runnable terminationFunction) {
this.environment.setTerminate(terminationFunction);
public void setTerminationFunction(Runnable terminationFunction) {
this.environment.setTerminationFunction(terminationFunction);
}
@Override
public void setErrorTerminationFunction(Runnable errorTerminationFunction) {
this.environment.setErrorTerminationFunction(errorTerminationFunction);
}
@Override
public void useFile(String fileName) {
this.fileName = fileName;

View File

@ -16,7 +16,8 @@ public class LispMain {
builder.setInput(System.in);
builder.setOutput(System.out);
builder.setErrorOutput(System.err);
builder.setTerminate(() -> System.exit(1));
builder.setTerminationFunction(() -> System.exit(0));
builder.setErrorTerminationFunction(() -> System.exit(1));
if (args.length > 0)
builder.useFile(args[0]);

View File

@ -18,7 +18,7 @@ public class ErrorManagerTester {
private ByteArrayOutputStream outputStream;
private ErrorManager createErrorManagerWithIndicators() {
Environment.getInstance().setTerminate(() -> indicatorSet.add(TERMINATED));
Environment.getInstance().setErrorTerminationFunction(() -> indicatorSet.add(TERMINATED));
Environment.getInstance().setErrorOutput(new PrintStream(outputStream));
return new ErrorManager();

View File

@ -0,0 +1,54 @@
package function.builtin;
import static org.junit.Assert.assertEquals;
import static testutil.TestUtilities.evaluateString;
import java.io.*;
import java.text.MessageFormat;
import org.junit.*;
import environment.Environment;
import function.ArgumentValidator.*;
public class PRINTTester {
private ByteArrayOutputStream outputStream;
private void assertPrinted(String expected) {
assertEquals(expected, outputStream.toString());
}
@Before
public void setUp() {
this.outputStream = new ByteArrayOutputStream();
Environment.getInstance().setOutput(new PrintStream(outputStream));
}
@Test
public void printStringWorks() {
String output = "\"Hello, world!\"";
evaluateString(MessageFormat.format("(print {0})", output));
assertPrinted(MessageFormat.format("{0}\n", output));
}
@Test
public void printSymbolWorks() {
String output = "A";
evaluateString(MessageFormat.format("(print ''{0})", output));
assertPrinted(MessageFormat.format("{0}\n", output));
}
@Test(expected = TooManyArgumentsException.class)
public void testPrintWithTooManyArguments() {
evaluateString("(print '1 '2)");
}
@Test(expected = TooFewArgumentsException.class)
public void testPrintWithTooFewArguments() {
evaluateString("(print)");
}
}

View File

@ -106,12 +106,12 @@ public class SExpressionTester {
@Test
public void testCarOfNilIsNil() {
assertEquals(Nil.getInstance().getCar(), Nil.getInstance());
assertEquals(Nil.getInstance(), Nil.getInstance().getCar());
}
@Test
public void testCdrOfNilIsNil() {
assertEquals(Nil.getInstance().getCdr(), Nil.getInstance());
assertEquals(Nil.getInstance(), Nil.getInstance().getCdr());
}
@Test
@ -119,7 +119,7 @@ public class SExpressionTester {
Cons nil = Nil.getInstance();
nil.setCar(new LispNumber("2"));
assertEquals(nil.getCar(), Nil.getInstance());
assertEquals(Nil.getInstance(), nil.getCar());
}
@Test
@ -127,7 +127,7 @@ public class SExpressionTester {
Cons nil = Nil.getInstance();
nil.setCdr(new LispNumber("2"));
assertEquals(nil.getCdr(), Nil.getInstance());
assertEquals(Nil.getInstance(), nil.getCdr());
}
@Test
@ -135,7 +135,7 @@ public class SExpressionTester {
BigInteger value = new BigInteger("12");
LispNumber number = new LispNumber(value.toString());
assertEquals(number.getValue(), value);
assertEquals(value, number.getValue());
}
@Test(expected = InvalidNumberException.class)
@ -166,8 +166,8 @@ public class SExpressionTester {
@Test
public void testLispNumberConstants() {
assertEquals(LispNumber.ZERO.getValue(), new BigInteger("0"));
assertEquals(LispNumber.ONE.getValue(), new BigInteger("1"));
assertEquals(BigInteger.ZERO, LispNumber.ZERO.getValue());
assertEquals(BigInteger.ONE, LispNumber.ONE.getValue());
}
}

View File

@ -29,21 +29,21 @@ public class SymbolTableTester {
@Test
public void retrieveSymbolValue() {
symbolTable.put("symbol", Symbol.T);
assertEquals(symbolTable.get("symbol"), Symbol.T);
assertEquals(Symbol.T, symbolTable.get("symbol"));
}
@Test
public void redefineSymbolValue() {
symbolTable.put("symbol", Symbol.T);
symbolTable.put("symbol", Nil.getInstance());
assertEquals(symbolTable.get("symbol"), Nil.getInstance());
assertEquals(Nil.getInstance(), symbolTable.get("symbol"));
}
@Test
public void checkParentTableIsCorrect() {
SymbolTable childTable = new SymbolTable(symbolTable);
assertEquals(childTable.getParent(), symbolTable);
assertEquals(symbolTable, childTable.getParent());
}
@Test
@ -52,7 +52,7 @@ public class SymbolTableTester {
SymbolTable childTable = new SymbolTable(symbolTable);
SymbolTable parentTable = childTable.getParent();
assertEquals(parentTable.get("symbol"), Symbol.T);
assertEquals(Symbol.T, parentTable.get("symbol"));
}
}

View File

@ -18,7 +18,7 @@ public final class SExpressionTypeAssertions {
}
public static void assertNil(SExpression sExpression) {
assertEquals(sExpression, Nil.getInstance());
assertEquals(Nil.getInstance(), sExpression);
assertTrue(sExpression.atomp());
assertFalse(sExpression.consp());