diff --git a/acceptance/fixture/LispInterpreterFixture.java b/acceptance/fixture/LispInterpreterFixture.java index ceb5b85..d2e61ce 100644 --- a/acceptance/fixture/LispInterpreterFixture.java +++ b/acceptance/fixture/LispInterpreterFixture.java @@ -2,24 +2,20 @@ package fixture; import java.io.*; -import environment.RuntimeEnvironment; import interpreter.*; public class LispInterpreterFixture { private ByteArrayOutputStream outputStream; - private RuntimeEnvironment environment; private LispInterpreter interpreter; public LispInterpreterFixture() throws IOException { this.outputStream = new ByteArrayOutputStream(); - this.environment = RuntimeEnvironment.getInstance(); this.interpreter = buildInterpreter(); } private LispInterpreter buildInterpreter() { LispInterpreterBuilder builder = LispInterpreterBuilderImpl.getInstance(); - builder.setInputName("fitnesse"); builder.setOutput(new PrintStream(outputStream)); builder.setErrorOutput(new PrintStream(outputStream)); builder.setNotInteractive(); @@ -30,7 +26,7 @@ public class LispInterpreterFixture { } public String evaluate(String input) throws IOException { - environment.setInput(new ByteArrayInputStream(input.getBytes())); + interpreter.setInput(new ByteArrayInputStream(input.getBytes()), "fitnesse"); interpreter.interpret(); String output = outputStream.toString(); outputStream.reset(); diff --git a/src/interpreter/LispInterpreter.java b/src/interpreter/LispInterpreter.java index 90c884a..9d42e57 100644 --- a/src/interpreter/LispInterpreter.java +++ b/src/interpreter/LispInterpreter.java @@ -2,7 +2,7 @@ package interpreter; import static function.builtin.EVAL.eval; -import java.io.PrintStream; +import java.io.*; import environment.RuntimeEnvironment; import error.*; @@ -21,6 +21,11 @@ public class LispInterpreter { this.errorManager = this.environment.getErrorManager(); this.output = environment.getOutput(); } + + public void setInput(InputStream input, String inputName) { + environment.setInput(input); + environment.setInputName(inputName); + } public void interpret() { createParser(); diff --git a/src/interpreter/LispInterpreterBuilder.java b/src/interpreter/LispInterpreterBuilder.java index 0ddb6bf..801324e 100644 --- a/src/interpreter/LispInterpreterBuilder.java +++ b/src/interpreter/LispInterpreterBuilder.java @@ -5,9 +5,7 @@ import java.util.function.Function; public interface LispInterpreterBuilder { - void setInputName(String inputName); - - void setInput(InputStream inputStream); + void setInput(InputStream inputStream, String inputName); void setOutput(PrintStream outputStream); @@ -31,6 +29,8 @@ public interface LispInterpreterBuilder { void setCriticalOutputDecorator(Function criticalOutputDecorator); + default void reset() {} + LispInterpreter build(); } diff --git a/src/interpreter/LispInterpreterBuilderImpl.java b/src/interpreter/LispInterpreterBuilderImpl.java index eb87d60..76b7486 100644 --- a/src/interpreter/LispInterpreterBuilderImpl.java +++ b/src/interpreter/LispInterpreterBuilderImpl.java @@ -27,14 +27,14 @@ public class LispInterpreterBuilderImpl implements LispInterpreterBuilder { private Function criticalOutputDecorator; private RuntimeEnvironment environment; private boolean isInteractive; - private boolean isUseFile; - private boolean isBuilt; + private boolean isFileBased; + protected boolean isBuilt; - private LispInterpreterBuilderImpl() { + protected LispInterpreterBuilderImpl() { this.environment = RuntimeEnvironment.getInstance(); this.inputName = ""; this.isInteractive = true; - this.isUseFile = false; + this.isFileBased = false; this.isBuilt = false; this.outputDecorator = s -> s; this.valueOutputDecorator = s -> s; @@ -44,13 +44,9 @@ public class LispInterpreterBuilderImpl implements LispInterpreterBuilder { } @Override - public void setInputName(String inputName) { - this.inputName = inputName; - } - - @Override - public void setInput(InputStream inputStream) { + public void setInput(InputStream inputStream, String inputName) { this.inputStream = inputStream; + this.inputName = inputName; } @Override @@ -81,8 +77,8 @@ public class LispInterpreterBuilderImpl implements LispInterpreterBuilder { @Override public void useFile(String fileName) { - this.isUseFile = true; - this.setInputName(fileName); + this.isFileBased = true; + this.inputName = fileName; this.setNotInteractive(); } @@ -156,14 +152,14 @@ public class LispInterpreterBuilderImpl implements LispInterpreterBuilder { } private InputStream getInputStream() throws FileNotFoundException { - return isUseFile ? new FileInputStream(inputName) : inputStream; + return isFileBased ? new FileInputStream(inputName) : inputStream; } private LispInterpreter createInterpreter() { return isInteractive ? new InteractiveLispInterpreter() : new LispInterpreter(); } - - public class InterpreterAlreadyBuiltException extends CriticalLispException { + + public static class InterpreterAlreadyBuiltException extends CriticalLispException { private static final long serialVersionUID = 1L; diff --git a/src/main/LispMain.java b/src/main/LispMain.java index 21d03f0..e3ebaf8 100644 --- a/src/main/LispMain.java +++ b/src/main/LispMain.java @@ -37,10 +37,8 @@ public class LispMain { private static void configureInput(String[] args, LispInterpreterBuilder builder) { if (args.length > 0) builder.useFile(args[0]); - else { - builder.setInputName("stdin"); - builder.setInput(System.in); - } + else + builder.setInput(System.in, "stdin"); } private static Function makeColorDecorator(String color) { diff --git a/test/interpreter/LispInterpreterBuilderTester.java b/test/interpreter/LispInterpreterBuilderTester.java new file mode 100644 index 0000000..c0cfb34 --- /dev/null +++ b/test/interpreter/LispInterpreterBuilderTester.java @@ -0,0 +1,78 @@ +package interpreter; + +import static org.junit.Assert.*; + +import java.io.*; + +import org.junit.*; + +import interpreter.LispInterpreterBuilderImpl.InterpreterAlreadyBuiltException; + +public class LispInterpreterBuilderTester { + + private LispInterpreterBuilder builder = new LispInterpreterBuilderImpl() { + + public void reset() { + this.isBuilt = false; + } + }; + + private void setCommonFeatures() { + builder.setOutput(new PrintStream(new ByteArrayOutputStream())); + builder.setErrorOutput(new PrintStream(new ByteArrayOutputStream())); + builder.setTerminationFunction(() -> {}); + builder.setErrorTerminationFunction(() -> {}); + } + + @Before + public void setUp() throws Exception { + builder.reset(); + } + + @After + public void tearDown() throws Exception { + builder.reset(); + } + + @Test + public void buildInteractiveInterpreter() { + setCommonFeatures(); + builder.setInput(System.in, "stdin"); + LispInterpreter interpreter = builder.build(); + + assertTrue(interpreter instanceof InteractiveLispInterpreter); + } + + @Test + public void buildNonInteractiveInterpreter() { + setCommonFeatures(); + builder.setInput(System.in, "stdin"); + builder.setNotInteractive(); + LispInterpreter interpreter = builder.build(); + + assertFalse(interpreter instanceof InteractiveLispInterpreter); + } + + @Test + public void buildFileBasedInterpreter() { + setCommonFeatures(); + builder.useFile("test/interpreter/test-files/file.lisp"); + LispInterpreter interpreter = builder.build(); + + assertFalse(interpreter instanceof InteractiveLispInterpreter); + } + + @Test(expected = InterpreterAlreadyBuiltException.class) + public void cannotBuildMoreThanOneInterpreter() { + builder.build(); + builder.build(); + } + + public void interpreterAlreadyBuiltException_HasMessage() { + InterpreterAlreadyBuiltException e = new InterpreterAlreadyBuiltException(); + + assertNotNull(e.getMessage()); + assertTrue(e.getMessage().length() > 0); + } + +} diff --git a/test/interpreter/test-files/file.lisp b/test/interpreter/test-files/file.lisp new file mode 100644 index 0000000..e69de29 diff --git a/test/main/MainTester.java b/test/main/MainTester.java new file mode 100644 index 0000000..05c7b33 --- /dev/null +++ b/test/main/MainTester.java @@ -0,0 +1,21 @@ +package main; + +import static org.junit.Assert.*; + +import org.junit.*; + + +public class MainTester { + + @Before + public void setUp() throws Exception {} + + @After + public void tearDown() throws Exception {} + + @Test + public void test() { + fail("Not yet implemented"); + } + +}