diff --git a/src/main/LispMain.java b/src/main/LispMain.java index 8063b33..b79a7c4 100644 --- a/src/main/LispMain.java +++ b/src/main/LispMain.java @@ -14,7 +14,7 @@ import terminal.*; public class LispMain { - private static final String GREETING = "Transcendental Lisp - Version 1.0.1"; + public static final String GREETING = "Transcendental Lisp - Version 1.0.1"; public static final String ANSI_RESET = "\u001B[0m"; public static final String ANSI_RED = "\u001B[31m"; @@ -33,19 +33,17 @@ public class LispMain { private LispInterpreterBuilder builder; private PipedInputStream inputReader; - private PipedOutputStream outputWriter; private PrintStream output; private LispTerminal lispTerminal; + private TerminalConfiguration configuration; public LispMain() { this.builder = LispInterpreterBuilderImpl.getInstance(); + this.configuration = new TerminalConfiguration(); - TerminalConfiguration terminalConfiguration = new TerminalConfiguration(); - terminalConfiguration.setInputWriter(new PipedOutputStream()); - terminalConfiguration.setOutputReader(new PipedInputStream()); - terminalConfiguration.setTerminal(createIOSafeTerminal()); - - initializeTerminal(terminalConfiguration); + configuration.setInputPair(new PipedOutputStream(), new PipedInputStream()); + configuration.setOutputPair(new PipedOutputStream(), new PipedInputStream()); + configuration.setTerminal(createIOSafeTerminal()); } private IOSafeTerminal createIOSafeTerminal() { @@ -62,28 +60,17 @@ public class LispMain { public LispMain(LispInterpreterBuilder builder, TerminalConfiguration configuration) { this.builder = builder; - initializeTerminal(configuration); + this.configuration = configuration; } - private void initializeTerminal(TerminalConfiguration configuration) { - try { - initalizeTerminalWithException(configuration); - } catch (IOException e) { - throw new UncheckedIOException(e); - } - } - - private void initalizeTerminalWithException(TerminalConfiguration configuration) throws IOException { - PipedOutputStream inputWriter = configuration.getInputWriter(); - PipedInputStream outputReader = configuration.getOutputReader(); - - inputReader = new PipedInputStream(inputWriter); - outputWriter = new PipedOutputStream(outputReader); - output = new PrintStream(outputWriter); - lispTerminal = new LispTerminal(configuration.getTerminal(), inputWriter, outputReader); + private void initializeTerminal() { + inputReader = configuration.getInputReader(); + output = new PrintStream(configuration.getOutputWriter()); + lispTerminal = new LispTerminal(configuration); } public void runInteractive() { + initializeTerminal(); printGreeting(); lispTerminal.start(); buildInteractiveInterpreter().interpret(); diff --git a/src/terminal/LispTerminal.java b/src/terminal/LispTerminal.java index 1661b50..f0c5af7 100644 --- a/src/terminal/LispTerminal.java +++ b/src/terminal/LispTerminal.java @@ -5,7 +5,7 @@ import static terminal.ControlSequenceHandler.isEscape; import static util.Characters.EOF; import static util.Characters.UNICODE_NULL; -import java.io.*; +import java.io.ByteArrayInputStream; import java.util.concurrent.*; import com.googlecode.lanterna.*; @@ -30,10 +30,10 @@ public class LispTerminal { private int originColumn; private int originRow; - public LispTerminal(IOSafeTerminal terminal, PipedOutputStream inputWriter, PipedInputStream outputReader) { - this.terminal = terminal; - this.inputWriter = new SafeOutputStream(inputWriter); - this.outputReader = new SafeInputStream(outputReader); + public LispTerminal(TerminalConfiguration configuration) { + this.terminal = configuration.getTerminal(); + this.inputWriter = new SafeOutputStream(configuration.getInputWriter()); + this.outputReader = new SafeInputStream(configuration.getOutputReader()); this.controlSequenceHandler = new ControlSequenceHandler(); this.executorService = Executors.newFixedThreadPool(2); this.terminalSize = terminal.getTerminalSize(); diff --git a/src/terminal/TerminalConfiguration.java b/src/terminal/TerminalConfiguration.java index 944d074..a6c2907 100644 --- a/src/terminal/TerminalConfiguration.java +++ b/src/terminal/TerminalConfiguration.java @@ -4,6 +4,8 @@ import java.io.*; import com.googlecode.lanterna.terminal.IOSafeTerminal; +import stream.UncheckedIOException; + public class TerminalConfiguration { private PipedOutputStream inputWriter; @@ -12,20 +14,32 @@ public class TerminalConfiguration { private PipedInputStream outputReader; private IOSafeTerminal terminal; - public void setInputWriter(PipedOutputStream inputWriter) { + public void setInputPair(PipedOutputStream inputWriter, PipedInputStream inputReader) { this.inputWriter = inputWriter; - } - - public void setInputReader(PipedInputStream inputReader) { this.inputReader = inputReader; + connectInputPairj(); } - public void setOutputWriter(PipedOutputStream outputWriter) { + private void connectInputPairj() { + try { + inputWriter.connect(inputReader); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + public void setOutputPair(PipedOutputStream outputWriter, PipedInputStream outputReader) { this.outputWriter = outputWriter; + this.outputReader = outputReader; + connectOutputPair(); } - public void setOutputReader(PipedInputStream outputReader) { - this.outputReader = outputReader; + private void connectOutputPair() { + try { + outputWriter.connect(outputReader); + } catch (IOException e) { + throw new UncheckedIOException(e); + } } public void setTerminal(IOSafeTerminal terminal) { diff --git a/test/main/MainTest.java b/test/main/MainTest.java index 1c38241..59addac 100644 --- a/test/main/MainTest.java +++ b/test/main/MainTest.java @@ -5,11 +5,13 @@ import static main.LispMain.*; import static org.junit.Assert.assertEquals; import java.io.*; +import java.util.concurrent.CountDownLatch; import org.junit.*; import org.junit.contrib.java.lang.system.*; -import com.googlecode.lanterna.terminal.virtual.*; +import com.googlecode.lanterna.input.KeyType; +import com.googlecode.lanterna.terminal.virtual.DefaultVirtualTerminal; import environment.RuntimeEnvironment; import interpreter.LispInterpreterBuilderImpl; @@ -18,9 +20,7 @@ import terminal.*; public class MainTest { LispMain main; - PipedOutputStream inputWriter; PipedInputStream outputReader; - VirtualTerminal terminal; RuntimeEnvironment environment; public MainTest() { @@ -37,21 +37,17 @@ public class MainTest { public SystemOutRule systemOutRule = new SystemOutRule().enableLog().mute(); @Before - public void setUp() throws Exception { - environment.reset(); + public void setUp() { TerminalConfiguration configuration = new TerminalConfiguration(); - inputWriter = new PipedOutputStream(); - outputReader = new PipedInputStream(); - terminal = new DefaultVirtualTerminal(); - configuration.setInputWriter(inputWriter); - configuration.setOutputReader(outputReader); - configuration.setTerminal(terminal); + configuration.setInputPair(new PipedOutputStream(), new PipedInputStream()); + configuration.setOutputPair(new PipedOutputStream(), new PipedInputStream()); + configuration.setTerminal(new DefaultVirtualTerminal()); main = new LispMain(new LispInterpreterBuilderImpl() {}, configuration); + environment.reset(); } @After - public void tearDown() throws Exception { - terminal.close(); + public void tearDown() { environment.reset(); } @@ -81,12 +77,32 @@ public class MainTest { @Test public void runInteractive() { + CountDownLatch latch = new CountDownLatch(1); VirtualTerminalInteractor t = new VirtualTerminalInteractor(); + + new Thread(() -> { + main = new LispMain(new LispInterpreterBuilderImpl() {}, t.getConfiguration()); + main.runInteractive(); + latch.countDown(); + }).start(); + + t.waitForPrompt(); + t.enterCharacters("'hi"); + t.pressKey(KeyType.Enter); + t.waitForPrompt(); + t.assertCursorPosition(2, 5); + t.assertScreenText(GREETING, " ", "~ 'hi ", " ", "HI ", "~ "); + t.enterControlCharacter('d'); + t.assertInputStreamClosed(); + try { - t.start(); - } finally { - t.stop(); - } + latch.await(); + } catch (InterruptedException ignored) {} } + // @Test + // public void defaultConstructorCoverage() { + // new LispMain(); + // } + } diff --git a/test/terminal/VirtualTerminalInteractor.java b/test/terminal/VirtualTerminalInteractor.java index d20071f..e72ee18 100644 --- a/test/terminal/VirtualTerminalInteractor.java +++ b/test/terminal/VirtualTerminalInteractor.java @@ -13,27 +13,37 @@ import stream.UncheckedIOException; public class VirtualTerminalInteractor { + private PipedOutputStream inputWriter; + private PipedInputStream inputReader; + private PipedOutputStream outputWriter; + private PipedInputStream outputReader; private VirtualTerminal virtualTerminal; private FlushListener flushListener; - private PipedInputStream inputReader; - private PipedOutputStream inputWriter; - private PipedInputStream outputReader; - private PipedOutputStream outputWriter; private LispTerminal lispTerminal; + private TerminalConfiguration configuration; public VirtualTerminalInteractor() { - try { - this.inputReader = new PipedInputStream(); - this.inputWriter = new PipedOutputStream(inputReader); - this.outputReader = new PipedInputStream(); - this.outputWriter = new PipedOutputStream(outputReader); - this.virtualTerminal = new DefaultVirtualTerminal(); - this.flushListener = new FlushListener(); - this.virtualTerminal.addVirtualTerminalListener(flushListener); - this.lispTerminal = new LispTerminal(virtualTerminal, inputWriter, outputReader); - } catch (IOException e) { - throw new UncheckedIOException(e); - } + this.inputWriter = new PipedOutputStream(); + this.inputReader = new PipedInputStream(); + this.outputWriter = new PipedOutputStream(); + this.outputReader = new PipedInputStream(); + this.virtualTerminal = new DefaultVirtualTerminal(); + this.flushListener = new FlushListener(); + this.virtualTerminal.addVirtualTerminalListener(flushListener); + this.lispTerminal = new LispTerminal(createTerminalConfiguration()); + } + + private TerminalConfiguration createTerminalConfiguration() { + configuration = new TerminalConfiguration(); + configuration.setInputPair(inputWriter, inputReader); + configuration.setOutputPair(outputWriter, outputReader); + configuration.setTerminal(virtualTerminal); + + return configuration; + } + + public TerminalConfiguration getConfiguration() { + return configuration; } public void start() { @@ -105,6 +115,10 @@ public class VirtualTerminalInteractor { } catch (InterruptedException ignored) {} } + public void waitForPrompt() { + waitForFlushes(1); + } + public void setColumns(int columns) { int rows = virtualTerminal.getTerminalSize().getRows(); virtualTerminal.setTerminalSize(new TerminalSize(columns, rows)); @@ -133,6 +147,12 @@ public class VirtualTerminalInteractor { assertCharacterAtPosition(positions[row][column], column, row); } + public void assertScreenText(String... rows) { + for (int row = 0; row < rows.length; row++) + for (int column = 0; column < rows[row].length(); column++) + assertCharacterAtPosition(rows[row].charAt(column), column, row); + } + public void assertInputWritten(String expected) { String actual = "";