Add unit tests
This commit is contained in:
parent
52762a6152
commit
111dd06d6f
|
@ -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();
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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();
|
||||||
|
// }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 = "";
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue