Add unit tests

This commit is contained in:
Mike Cifelli 2017-03-23 18:48:37 -04:00
parent 52762a6152
commit 111dd06d6f
5 changed files with 107 additions and 70 deletions

View File

@ -14,7 +14,7 @@ import terminal.*;
public class LispMain { 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_RESET = "\u001B[0m";
public static final String ANSI_RED = "\u001B[31m"; public static final String ANSI_RED = "\u001B[31m";
@ -33,19 +33,17 @@ public class LispMain {
private LispInterpreterBuilder builder; private LispInterpreterBuilder builder;
private PipedInputStream inputReader; private PipedInputStream inputReader;
private PipedOutputStream outputWriter;
private PrintStream output; private PrintStream output;
private LispTerminal lispTerminal; private LispTerminal lispTerminal;
private TerminalConfiguration configuration;
public LispMain() { public LispMain() {
this.builder = LispInterpreterBuilderImpl.getInstance(); this.builder = LispInterpreterBuilderImpl.getInstance();
this.configuration = new TerminalConfiguration();
TerminalConfiguration terminalConfiguration = new TerminalConfiguration(); configuration.setInputPair(new PipedOutputStream(), new PipedInputStream());
terminalConfiguration.setInputWriter(new PipedOutputStream()); configuration.setOutputPair(new PipedOutputStream(), new PipedInputStream());
terminalConfiguration.setOutputReader(new PipedInputStream()); configuration.setTerminal(createIOSafeTerminal());
terminalConfiguration.setTerminal(createIOSafeTerminal());
initializeTerminal(terminalConfiguration);
} }
private IOSafeTerminal createIOSafeTerminal() { private IOSafeTerminal createIOSafeTerminal() {
@ -62,28 +60,17 @@ public class LispMain {
public LispMain(LispInterpreterBuilder builder, TerminalConfiguration configuration) { public LispMain(LispInterpreterBuilder builder, TerminalConfiguration configuration) {
this.builder = builder; this.builder = builder;
initializeTerminal(configuration); this.configuration = configuration;
} }
private void initializeTerminal(TerminalConfiguration configuration) { private void initializeTerminal() {
try { inputReader = configuration.getInputReader();
initalizeTerminalWithException(configuration); output = new PrintStream(configuration.getOutputWriter());
} catch (IOException e) { lispTerminal = new LispTerminal(configuration);
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);
} }
public void runInteractive() { public void runInteractive() {
initializeTerminal();
printGreeting(); printGreeting();
lispTerminal.start(); lispTerminal.start();
buildInteractiveInterpreter().interpret(); buildInteractiveInterpreter().interpret();

View File

@ -5,7 +5,7 @@ import static terminal.ControlSequenceHandler.isEscape;
import static util.Characters.EOF; import static util.Characters.EOF;
import static util.Characters.UNICODE_NULL; import static util.Characters.UNICODE_NULL;
import java.io.*; import java.io.ByteArrayInputStream;
import java.util.concurrent.*; import java.util.concurrent.*;
import com.googlecode.lanterna.*; import com.googlecode.lanterna.*;
@ -30,10 +30,10 @@ public class LispTerminal {
private int originColumn; private int originColumn;
private int originRow; private int originRow;
public LispTerminal(IOSafeTerminal terminal, PipedOutputStream inputWriter, PipedInputStream outputReader) { public LispTerminal(TerminalConfiguration configuration) {
this.terminal = terminal; this.terminal = configuration.getTerminal();
this.inputWriter = new SafeOutputStream(inputWriter); this.inputWriter = new SafeOutputStream(configuration.getInputWriter());
this.outputReader = new SafeInputStream(outputReader); this.outputReader = new SafeInputStream(configuration.getOutputReader());
this.controlSequenceHandler = new ControlSequenceHandler(); this.controlSequenceHandler = new ControlSequenceHandler();
this.executorService = Executors.newFixedThreadPool(2); this.executorService = Executors.newFixedThreadPool(2);
this.terminalSize = terminal.getTerminalSize(); this.terminalSize = terminal.getTerminalSize();

View File

@ -4,6 +4,8 @@ import java.io.*;
import com.googlecode.lanterna.terminal.IOSafeTerminal; import com.googlecode.lanterna.terminal.IOSafeTerminal;
import stream.UncheckedIOException;
public class TerminalConfiguration { public class TerminalConfiguration {
private PipedOutputStream inputWriter; private PipedOutputStream inputWriter;
@ -12,20 +14,32 @@ public class TerminalConfiguration {
private PipedInputStream outputReader; private PipedInputStream outputReader;
private IOSafeTerminal terminal; private IOSafeTerminal terminal;
public void setInputWriter(PipedOutputStream inputWriter) { public void setInputPair(PipedOutputStream inputWriter, PipedInputStream inputReader) {
this.inputWriter = inputWriter; this.inputWriter = inputWriter;
}
public void setInputReader(PipedInputStream inputReader) {
this.inputReader = 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.outputWriter = outputWriter;
this.outputReader = outputReader;
connectOutputPair();
} }
public void setOutputReader(PipedInputStream outputReader) { private void connectOutputPair() {
this.outputReader = outputReader; try {
outputWriter.connect(outputReader);
} catch (IOException e) {
throw new UncheckedIOException(e);
}
} }
public void setTerminal(IOSafeTerminal terminal) { public void setTerminal(IOSafeTerminal terminal) {

View File

@ -5,11 +5,13 @@ import static main.LispMain.*;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import java.io.*; import java.io.*;
import java.util.concurrent.CountDownLatch;
import org.junit.*; import org.junit.*;
import org.junit.contrib.java.lang.system.*; 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 environment.RuntimeEnvironment;
import interpreter.LispInterpreterBuilderImpl; import interpreter.LispInterpreterBuilderImpl;
@ -18,9 +20,7 @@ import terminal.*;
public class MainTest { public class MainTest {
LispMain main; LispMain main;
PipedOutputStream inputWriter;
PipedInputStream outputReader; PipedInputStream outputReader;
VirtualTerminal terminal;
RuntimeEnvironment environment; RuntimeEnvironment environment;
public MainTest() { public MainTest() {
@ -37,21 +37,17 @@ public class MainTest {
public SystemOutRule systemOutRule = new SystemOutRule().enableLog().mute(); public SystemOutRule systemOutRule = new SystemOutRule().enableLog().mute();
@Before @Before
public void setUp() throws Exception { public void setUp() {
environment.reset();
TerminalConfiguration configuration = new TerminalConfiguration(); TerminalConfiguration configuration = new TerminalConfiguration();
inputWriter = new PipedOutputStream(); configuration.setInputPair(new PipedOutputStream(), new PipedInputStream());
outputReader = new PipedInputStream(); configuration.setOutputPair(new PipedOutputStream(), new PipedInputStream());
terminal = new DefaultVirtualTerminal(); configuration.setTerminal(new DefaultVirtualTerminal());
configuration.setInputWriter(inputWriter);
configuration.setOutputReader(outputReader);
configuration.setTerminal(terminal);
main = new LispMain(new LispInterpreterBuilderImpl() {}, configuration); main = new LispMain(new LispInterpreterBuilderImpl() {}, configuration);
environment.reset();
} }
@After @After
public void tearDown() throws Exception { public void tearDown() {
terminal.close();
environment.reset(); environment.reset();
} }
@ -81,12 +77,32 @@ public class MainTest {
@Test @Test
public void runInteractive() { public void runInteractive() {
CountDownLatch latch = new CountDownLatch(1);
VirtualTerminalInteractor t = new VirtualTerminalInteractor(); 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 { try {
t.start(); latch.await();
} finally { } catch (InterruptedException ignored) {}
t.stop();
}
} }
// @Test
// public void defaultConstructorCoverage() {
// new LispMain();
// }
} }

View File

@ -13,27 +13,37 @@ import stream.UncheckedIOException;
public class VirtualTerminalInteractor { public class VirtualTerminalInteractor {
private PipedOutputStream inputWriter;
private PipedInputStream inputReader;
private PipedOutputStream outputWriter;
private PipedInputStream outputReader;
private VirtualTerminal virtualTerminal; private VirtualTerminal virtualTerminal;
private FlushListener flushListener; private FlushListener flushListener;
private PipedInputStream inputReader;
private PipedOutputStream inputWriter;
private PipedInputStream outputReader;
private PipedOutputStream outputWriter;
private LispTerminal lispTerminal; private LispTerminal lispTerminal;
private TerminalConfiguration configuration;
public VirtualTerminalInteractor() { public VirtualTerminalInteractor() {
try { this.inputWriter = new PipedOutputStream();
this.inputReader = new PipedInputStream(); this.inputReader = new PipedInputStream();
this.inputWriter = new PipedOutputStream(inputReader); this.outputWriter = new PipedOutputStream();
this.outputReader = new PipedInputStream(); this.outputReader = new PipedInputStream();
this.outputWriter = new PipedOutputStream(outputReader); this.virtualTerminal = new DefaultVirtualTerminal();
this.virtualTerminal = new DefaultVirtualTerminal(); this.flushListener = new FlushListener();
this.flushListener = new FlushListener(); this.virtualTerminal.addVirtualTerminalListener(flushListener);
this.virtualTerminal.addVirtualTerminalListener(flushListener); this.lispTerminal = new LispTerminal(createTerminalConfiguration());
this.lispTerminal = new LispTerminal(virtualTerminal, inputWriter, outputReader); }
} catch (IOException e) {
throw new UncheckedIOException(e); 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() { public void start() {
@ -105,6 +115,10 @@ public class VirtualTerminalInteractor {
} catch (InterruptedException ignored) {} } catch (InterruptedException ignored) {}
} }
public void waitForPrompt() {
waitForFlushes(1);
}
public void setColumns(int columns) { public void setColumns(int columns) {
int rows = virtualTerminal.getTerminalSize().getRows(); int rows = virtualTerminal.getTerminalSize().getRows();
virtualTerminal.setTerminalSize(new TerminalSize(columns, rows)); virtualTerminal.setTerminalSize(new TerminalSize(columns, rows));
@ -133,6 +147,12 @@ public class VirtualTerminalInteractor {
assertCharacterAtPosition(positions[row][column], column, row); 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) { public void assertInputWritten(String expected) {
String actual = ""; String actual = "";