Refactored some code and added unit tests
This commit is contained in:
parent
b700b714f3
commit
ea8acd423f
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ public class ErrorManager {
|
|||
printError(lispException);
|
||||
|
||||
if (isCritical(lispException))
|
||||
environment.terminate();
|
||||
environment.terminateExceptionally();
|
||||
}
|
||||
|
||||
private void printError(LispException lispException) {
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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]);
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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)");
|
||||
}
|
||||
|
||||
}
|
|
@ -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());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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"));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
|
|
Loading…
Reference in New Issue