Refactor main interpreter code
Fixed several minor issues Only print the last value when interpreting a file Resolves #4
This commit is contained in:
parent
5cb6212d2a
commit
058e937c3e
|
@ -21,7 +21,7 @@ public class RuntimeEnvironment {
|
|||
private String path;
|
||||
private Runnable terminationFunction;
|
||||
private Runnable errorTerminationFunction;
|
||||
private Function<String, String> outputDecorator;
|
||||
private Function<String, String> promptDecorator;
|
||||
private Function<String, String> valueOutputDecorator;
|
||||
private Function<String, String> warningOutputDecorator;
|
||||
private Function<String, String> errorOutputDecorator;
|
||||
|
@ -40,7 +40,7 @@ public class RuntimeEnvironment {
|
|||
path = null;
|
||||
terminationFunction = null;
|
||||
errorTerminationFunction = null;
|
||||
outputDecorator = null;
|
||||
promptDecorator = null;
|
||||
valueOutputDecorator = null;
|
||||
warningOutputDecorator = null;
|
||||
errorOutputDecorator = null;
|
||||
|
@ -79,8 +79,8 @@ public class RuntimeEnvironment {
|
|||
this.errorTerminationFunction = errorTerminationFunction;
|
||||
}
|
||||
|
||||
public void setOutputDecorator(Function<String, String> outputDecorator) {
|
||||
this.outputDecorator = outputDecorator;
|
||||
public void setPromptDecorator(Function<String, String> promptDecorator) {
|
||||
this.promptDecorator = promptDecorator;
|
||||
}
|
||||
|
||||
public void setValueOutputDecorator(Function<String, String> valueOutputDecorator) {
|
||||
|
@ -131,8 +131,8 @@ public class RuntimeEnvironment {
|
|||
errorTerminationFunction.run();
|
||||
}
|
||||
|
||||
public String decorateOutput(String output) {
|
||||
return outputDecorator.apply(output);
|
||||
public String decoratePrompt(String prompt) {
|
||||
return promptDecorator.apply(prompt);
|
||||
}
|
||||
|
||||
public String decorateValueOutput(String valueOutput) {
|
||||
|
|
|
@ -1,11 +1,29 @@
|
|||
package interpreter;
|
||||
|
||||
import sexpression.SExpression;
|
||||
|
||||
public class FileLispInterpreter extends LispInterpreter {
|
||||
|
||||
private SExpression lastSExpression;
|
||||
|
||||
public FileLispInterpreter() {
|
||||
this.lastSExpression = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void afterInterpreting() {
|
||||
environment.getOutput().println();
|
||||
environment.getOutput().close();
|
||||
protected SExpression evaluateNextSExpression() {
|
||||
return this.lastSExpression = super.evaluateNextSExpression();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void printSExpression(SExpression sExpression) {}
|
||||
|
||||
@Override
|
||||
protected void applyFinishingTouches() {
|
||||
if (lastSExpression != null)
|
||||
super.printSExpression(lastSExpression);
|
||||
|
||||
super.applyFinishingTouches();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,34 +1,28 @@
|
|||
package interpreter;
|
||||
|
||||
import sexpression.SExpression;
|
||||
|
||||
public class InteractiveLispInterpreter extends LispInterpreter {
|
||||
|
||||
private static final String GREETING = "Transcendental Lisp - Version 1.0.0";
|
||||
private static final String PROMPT = "~ ";
|
||||
|
||||
@Override
|
||||
protected void beforeInterpreting() {
|
||||
environment.getOutput().println(GREETING);
|
||||
environment.getOutput().println();
|
||||
environment.getOutput().flush();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void prompt() {
|
||||
environment.getOutput().print(environment.decorateOutput(PROMPT));
|
||||
environment.getOutput().print(environment.decoratePrompt(PROMPT));
|
||||
environment.getOutput().flush();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void printValueOfNextSExpression() {
|
||||
protected void printSExpression(SExpression sExpression) {
|
||||
environment.getOutput().println();
|
||||
super.printValueOfNextSExpression();
|
||||
super.printSExpression(sExpression);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void afterInterpreting() {
|
||||
protected void applyFinishingTouches() {
|
||||
environment.getOutput().println();
|
||||
environment.getOutput().println();
|
||||
environment.getOutput().close();
|
||||
environment.getOutput().println(environment.decoratePrompt(""));
|
||||
environment.getOutput().flush();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -18,39 +18,44 @@ public class LispInterpreter {
|
|||
|
||||
public void interpret() {
|
||||
createParser();
|
||||
beforeInterpreting();
|
||||
|
||||
for (prompt(); !parser.isEof(); prompt())
|
||||
printValueOfNextSExpression();
|
||||
evaluateAndPrintNextSExpression();
|
||||
|
||||
afterInterpreting();
|
||||
applyFinishingTouches();
|
||||
}
|
||||
|
||||
private void createParser() {
|
||||
parser = new LispParser(environment.getInput(), environment.getInputName());
|
||||
}
|
||||
|
||||
protected void beforeInterpreting() {}
|
||||
|
||||
protected void prompt() {}
|
||||
|
||||
protected void printValueOfNextSExpression() {
|
||||
private void evaluateAndPrintNextSExpression() {
|
||||
try {
|
||||
printValueOfNextSExpressionWithException();
|
||||
evaluateAndPrintNextSExpressionWithException();
|
||||
} catch (LispException e) {
|
||||
environment.getErrorManager().handle(e);
|
||||
}
|
||||
}
|
||||
|
||||
private void printValueOfNextSExpressionWithException() {
|
||||
SExpression sExpression = parser.getNextSExpression();
|
||||
String result = environment.decorateValueOutput(String.valueOf(eval(sExpression)));
|
||||
private void evaluateAndPrintNextSExpressionWithException() {
|
||||
printSExpression(evaluateNextSExpression());
|
||||
}
|
||||
|
||||
protected SExpression evaluateNextSExpression() {
|
||||
SExpression sExpression = parser.getNextSExpression();
|
||||
|
||||
return eval(sExpression);
|
||||
}
|
||||
|
||||
protected void printSExpression(SExpression sExpression) {
|
||||
String result = environment.decorateValueOutput(String.valueOf(sExpression));
|
||||
environment.getOutput().println(result);
|
||||
environment.getOutput().flush();
|
||||
}
|
||||
|
||||
protected void afterInterpreting() {
|
||||
protected void applyFinishingTouches() {
|
||||
environment.getOutput().println();
|
||||
environment.getOutput().flush();
|
||||
}
|
||||
|
|
|
@ -19,15 +19,15 @@ public interface LispInterpreterBuilder {
|
|||
|
||||
void useFile(String fileName);
|
||||
|
||||
void setOutputDecorator(Function<String, String> outputDecorator);
|
||||
void setPromptDecorator(Function<String, String> decorator);
|
||||
|
||||
void setValueOutputDecorator(Function<String, String> valueOutputDecorator);
|
||||
void setValueOutputDecorator(Function<String, String> decorator);
|
||||
|
||||
void setWarningOutputDecorator(Function<String, String> warningOutputDecorator);
|
||||
void setWarningOutputDecorator(Function<String, String> decorator);
|
||||
|
||||
void setErrorOutputDecorator(Function<String, String> errorOutputDecorator);
|
||||
void setErrorOutputDecorator(Function<String, String> decorator);
|
||||
|
||||
void setCriticalOutputDecorator(Function<String, String> criticalOutputDecorator);
|
||||
void setCriticalOutputDecorator(Function<String, String> decorator);
|
||||
|
||||
LispInterpreter build();
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ public class LispInterpreterBuilderImpl implements LispInterpreterBuilder {
|
|||
private PrintStream errorOutputStream;
|
||||
private Runnable terminationFunction;
|
||||
private Runnable errorTerminationFunction;
|
||||
private Function<String, String> outputDecorator;
|
||||
private Function<String, String> promptDecorator;
|
||||
private Function<String, String> valueOutputDecorator;
|
||||
private Function<String, String> warningOutputDecorator;
|
||||
private Function<String, String> errorOutputDecorator;
|
||||
|
@ -38,7 +38,7 @@ public class LispInterpreterBuilderImpl implements LispInterpreterBuilder {
|
|||
this.isInteractive = true;
|
||||
this.isFileBased = false;
|
||||
this.isBuilt = false;
|
||||
this.outputDecorator = s -> s;
|
||||
this.promptDecorator = s -> s;
|
||||
this.valueOutputDecorator = s -> s;
|
||||
this.warningOutputDecorator = s -> s;
|
||||
this.errorOutputDecorator = s -> s;
|
||||
|
@ -85,8 +85,8 @@ public class LispInterpreterBuilderImpl implements LispInterpreterBuilder {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void setOutputDecorator(Function<String, String> decorator) {
|
||||
this.outputDecorator = decorator;
|
||||
public void setPromptDecorator(Function<String, String> decorator) {
|
||||
this.promptDecorator = decorator;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -135,7 +135,7 @@ public class LispInterpreterBuilderImpl implements LispInterpreterBuilder {
|
|||
environment.setErrorManager(errorManager);
|
||||
environment.setTerminationFunction(terminationFunction);
|
||||
environment.setErrorTerminationFunction(errorTerminationFunction);
|
||||
environment.setOutputDecorator(outputDecorator);
|
||||
environment.setPromptDecorator(promptDecorator);
|
||||
environment.setValueOutputDecorator(valueOutputDecorator);
|
||||
environment.setWarningOutputDecorator(warningOutputDecorator);
|
||||
environment.setErrorOutputDecorator(errorOutputDecorator);
|
||||
|
|
|
@ -14,6 +14,7 @@ import terminal.SafeStream.UncheckedIOException;
|
|||
|
||||
public class LispMain {
|
||||
|
||||
private static final String GREETING = "Transcendental Lisp - Version 1.0.1";
|
||||
private static final String ANSI_RESET = "\u001B[0m";
|
||||
private static final String ANSI_RED = "\u001B[31m";
|
||||
private static final String ANSI_GREEN = "\u001B[32m";
|
||||
|
@ -33,30 +34,55 @@ public class LispMain {
|
|||
private PipedOutputStream inputWriter;
|
||||
private PipedInputStream outputReader;
|
||||
private PipedOutputStream outputWriter;
|
||||
private PrintStream outputStream;
|
||||
private SafePipedOutputStream safeOutputWriter;
|
||||
private LispTerminal lispTerminal;
|
||||
|
||||
private void runInteractive() {
|
||||
initializeTerminalAndStreams();
|
||||
printGreeting();
|
||||
lispTerminal.start();
|
||||
buildInteractiveInterpreter().interpret();
|
||||
outputStream.close();
|
||||
}
|
||||
|
||||
private void initializeTerminalAndStreams() {
|
||||
try {
|
||||
initalizeTerminalAndStreamsWithException();
|
||||
} catch (IOException e) {
|
||||
throw new UncheckedIOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private void initalizeTerminalAndStreamsWithException() throws IOException {
|
||||
inputReader = new PipedInputStream();
|
||||
inputWriter = new PipedOutputStream(inputReader);
|
||||
outputReader = new PipedInputStream();
|
||||
outputWriter = new PipedOutputStream(outputReader);
|
||||
outputStream = new PrintStream(outputWriter);
|
||||
safeOutputWriter = new SafePipedOutputStream(outputWriter);
|
||||
lispTerminal = new LispTerminal(createIOSafeTerminal(), inputWriter, outputReader);
|
||||
}
|
||||
|
||||
private IOSafeTerminal createIOSafeTerminal() throws IOException {
|
||||
Terminal defaultTerminal = new DefaultTerminalFactory().createTerminal();
|
||||
|
||||
return IOSafeTerminalAdapter.createRuntimeExceptionConvertingAdapter(defaultTerminal);
|
||||
}
|
||||
|
||||
private void runInteractive() {
|
||||
initializeTerminal();
|
||||
lispTerminal.start();
|
||||
buildInteractiveInterpreter().interpret();
|
||||
private void printGreeting() {
|
||||
outputStream.println(GREETING);
|
||||
outputStream.println();
|
||||
}
|
||||
|
||||
private LispInterpreter buildInteractiveInterpreter() {
|
||||
LispInterpreterBuilder builder = LispInterpreterBuilderImpl.getInstance();
|
||||
PrintStream outputStream = new PrintStream(outputWriter);
|
||||
builder.setInput(inputReader, "terminal");
|
||||
builder.setOutput(outputStream);
|
||||
builder.setErrorOutput(outputStream);
|
||||
builder.setTerminationFunction(this::shutdown);
|
||||
builder.setErrorTerminationFunction(this::shutdown);
|
||||
builder.setOutputDecorator(makeInteractiveDecorator(ANSI_GREEN));
|
||||
builder.setPromptDecorator(makeSegmentDecorator(ANSI_GREEN));
|
||||
builder.setValueOutputDecorator(s -> s);
|
||||
builder.setWarningOutputDecorator(s -> s);
|
||||
builder.setErrorOutputDecorator(s -> s);
|
||||
|
@ -66,11 +92,13 @@ public class LispMain {
|
|||
}
|
||||
|
||||
private void shutdown() {
|
||||
outputStream.println();
|
||||
outputStream.println(END_OF_SEGMENT);
|
||||
lispTerminal.stop();
|
||||
safeOutputWriter.close();
|
||||
}
|
||||
|
||||
private static Function<String, String> makeInteractiveDecorator(String color) {
|
||||
private static Function<String, String> makeSegmentDecorator(String color) {
|
||||
return new Function<String, String>() {
|
||||
|
||||
@Override
|
||||
|
@ -80,23 +108,6 @@ public class LispMain {
|
|||
};
|
||||
}
|
||||
|
||||
private void initializeTerminal() {
|
||||
try {
|
||||
initalizeTerminalWithException();
|
||||
} catch (IOException e) {
|
||||
throw new UncheckedIOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private void initalizeTerminalWithException() throws IOException {
|
||||
inputReader = new PipedInputStream();
|
||||
inputWriter = new PipedOutputStream(inputReader);
|
||||
outputReader = new PipedInputStream();
|
||||
outputWriter = new PipedOutputStream(outputReader);
|
||||
safeOutputWriter = new SafePipedOutputStream(outputWriter);
|
||||
lispTerminal = new LispTerminal(createIOSafeTerminal(), inputWriter, outputReader);
|
||||
}
|
||||
|
||||
private void runWithFile(String fileName) {
|
||||
buildFileInterpreter(fileName).interpret();
|
||||
}
|
||||
|
@ -108,7 +119,6 @@ public class LispMain {
|
|||
builder.setErrorOutput(System.err);
|
||||
builder.setTerminationFunction(() -> System.exit(0));
|
||||
builder.setErrorTerminationFunction(() -> System.exit(1));
|
||||
builder.setOutputDecorator(makeColorDecorator(ANSI_GREEN));
|
||||
builder.setValueOutputDecorator(makeColorDecorator(ANSI_GREEN));
|
||||
builder.setWarningOutputDecorator(makeColorDecorator(ANSI_YELLOW));
|
||||
builder.setErrorOutputDecorator(makeColorDecorator(ANSI_RED));
|
||||
|
|
|
@ -100,17 +100,23 @@ public class LispTerminal {
|
|||
private KeyStroke getKeyStroke() {
|
||||
KeyStroke keyStroke = null;
|
||||
|
||||
// issue #299
|
||||
try {
|
||||
keyStroke = terminal.pollInput();
|
||||
} catch (IllegalStateException e) { // issue #299
|
||||
moveCursorToEndOfInput();
|
||||
terminal.putCharacter('\n');
|
||||
stop();
|
||||
} catch (IllegalStateException e) {
|
||||
doControlC();
|
||||
}
|
||||
|
||||
return keyStroke;
|
||||
}
|
||||
|
||||
private void doControlC() {
|
||||
moveCursorToEndOfInput();
|
||||
terminal.putCharacter('\n');
|
||||
updateOrigin();
|
||||
stop();
|
||||
}
|
||||
|
||||
private synchronized void handleKey(KeyStroke keyStroke) {
|
||||
doKey(keyStroke);
|
||||
terminal.flush();
|
||||
|
@ -324,9 +330,7 @@ public class LispTerminal {
|
|||
private void takeNap() {
|
||||
try {
|
||||
Thread.sleep(1);
|
||||
} catch (InterruptedException e) {
|
||||
isStopped = true;
|
||||
}
|
||||
} catch (InterruptedException ignored) {}
|
||||
}
|
||||
|
||||
private void writeOutput() {
|
||||
|
|
|
@ -91,10 +91,10 @@ public class RuntimeEnvironmentTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void assignOutputDecorator() {
|
||||
environment.setOutputDecorator(s -> "[" + s + "]");
|
||||
public void assignPromptDecorator() {
|
||||
environment.setPromptDecorator(s -> "[" + s + "]");
|
||||
|
||||
assertEquals("[test]", environment.decorateOutput("test"));
|
||||
assertEquals("[test]", environment.decoratePrompt("test"));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -135,7 +135,7 @@ public class RuntimeEnvironmentTest {
|
|||
environment.setPath("testpath/");
|
||||
environment.setTerminationFunction(() -> indicatorSet.add(TERMINATED_SUCCESSFULLY));
|
||||
environment.setErrorTerminationFunction(() -> indicatorSet.add(TERMINATED_EXCEPTIONALLY));
|
||||
environment.setOutputDecorator(s -> "[" + s + "]");
|
||||
environment.setPromptDecorator(s -> "[" + s + "]");
|
||||
environment.setValueOutputDecorator(s -> "(" + s + ")");
|
||||
environment.setWarningOutputDecorator(s -> "|" + s + "|");
|
||||
environment.setErrorOutputDecorator(s -> "{" + s + "}");
|
||||
|
@ -160,8 +160,8 @@ public class RuntimeEnvironmentTest {
|
|||
} catch (NullPointerException e) {}
|
||||
|
||||
try {
|
||||
environment.decorateOutput("");
|
||||
fail("decorateOutput");
|
||||
environment.decoratePrompt("");
|
||||
fail("decoratePrompt");
|
||||
} catch (NullPointerException e) {}
|
||||
|
||||
try {
|
||||
|
|
|
@ -47,7 +47,6 @@ public class LOADTest {
|
|||
environment.setErrorOutput(new PrintStream(errorOutputStream));
|
||||
environment.setErrorManager(new ErrorManager());
|
||||
environment.setPath("");
|
||||
environment.setOutputDecorator(s -> s);
|
||||
environment.setWarningOutputDecorator(s -> s);
|
||||
environment.setErrorOutputDecorator(s -> s);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package terminal;
|
||||
|
||||
import static com.googlecode.lanterna.input.KeyType.*;
|
||||
import static org.junit.Assert.*;
|
||||
import static terminal.LispTerminal.END_OF_SEGMENT;
|
||||
|
||||
|
@ -146,7 +147,7 @@ public class LispTerminalTest {
|
|||
|
||||
@Test
|
||||
public void leftArrowDoesNotMovePastOrigin() {
|
||||
pressKey(KeyType.ArrowLeft);
|
||||
pressKey(ArrowLeft);
|
||||
assertCursorPosition(0, 0);
|
||||
}
|
||||
|
||||
|
@ -154,13 +155,13 @@ public class LispTerminalTest {
|
|||
public void leftArrowWorksAfterEnteringCharacters() {
|
||||
enterCharacters("abc");
|
||||
assertCursorPosition(3, 0);
|
||||
pressKey(KeyType.ArrowLeft);
|
||||
pressKey(ArrowLeft);
|
||||
assertCursorPosition(2, 0);
|
||||
pressKey(KeyType.ArrowLeft);
|
||||
pressKey(ArrowLeft);
|
||||
assertCursorPosition(1, 0);
|
||||
pressKey(KeyType.ArrowLeft);
|
||||
pressKey(ArrowLeft);
|
||||
assertCursorPosition(0, 0);
|
||||
pressKey(KeyType.ArrowLeft);
|
||||
pressKey(ArrowLeft);
|
||||
assertCursorPosition(0, 0);
|
||||
}
|
||||
|
||||
|
@ -169,13 +170,13 @@ public class LispTerminalTest {
|
|||
setColumns(5);
|
||||
enterCharacters("123451");
|
||||
assertCursorPosition(1, 1);
|
||||
pressKeyTimes(KeyType.ArrowLeft, 2);
|
||||
pressKeyTimes(ArrowLeft, 2);
|
||||
assertCursorPosition(4, 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void rightArrowDoesNotMovePastEndOfInput() {
|
||||
pressKey(KeyType.ArrowRight);
|
||||
pressKey(ArrowRight);
|
||||
assertCursorPosition(0, 0);
|
||||
}
|
||||
|
||||
|
@ -183,11 +184,11 @@ public class LispTerminalTest {
|
|||
public void rightArrowWorksAfterMovingLeft() {
|
||||
enterCharacters("12");
|
||||
assertCursorPosition(2, 0);
|
||||
pressKey(KeyType.ArrowLeft);
|
||||
pressKey(ArrowLeft);
|
||||
assertCursorPosition(1, 0);
|
||||
pressKey(KeyType.ArrowRight);
|
||||
pressKey(ArrowRight);
|
||||
assertCursorPosition(2, 0);
|
||||
pressKey(KeyType.ArrowRight);
|
||||
pressKey(ArrowRight);
|
||||
assertCursorPosition(2, 0);
|
||||
}
|
||||
|
||||
|
@ -196,9 +197,9 @@ public class LispTerminalTest {
|
|||
setColumns(5);
|
||||
enterCharacters("123451");
|
||||
assertCursorPosition(1, 1);
|
||||
pressKeyTimes(KeyType.ArrowLeft, 3);
|
||||
pressKeyTimes(ArrowLeft, 3);
|
||||
assertCursorPosition(3, 0);
|
||||
pressKeyTimes(KeyType.ArrowRight, 3);
|
||||
pressKeyTimes(ArrowRight, 3);
|
||||
assertCursorPosition(1, 1);
|
||||
}
|
||||
|
||||
|
@ -212,7 +213,7 @@ public class LispTerminalTest {
|
|||
@Test
|
||||
public void characterIsInserted() {
|
||||
enterCharacters("abcd");
|
||||
pressKeyTimes(KeyType.ArrowLeft, 2);
|
||||
pressKeyTimes(ArrowLeft, 2);
|
||||
enterCharacter('x');
|
||||
assertCharacterPositions(new char[][] { { 'a', 'b', 'x', 'c', 'd' } });
|
||||
}
|
||||
|
@ -221,21 +222,21 @@ public class LispTerminalTest {
|
|||
public void characterIsInserted_PushesInputToNextRow() {
|
||||
setColumns(4);
|
||||
enterCharacters("abcd");
|
||||
pressKeyTimes(KeyType.ArrowLeft, 2);
|
||||
pressKeyTimes(ArrowLeft, 2);
|
||||
enterCharacter('x');
|
||||
assertCharacterPositions(new char[][] { { 'a', 'b', 'x', 'c' }, { 'd', ' ', ' ', ' ' } });
|
||||
}
|
||||
|
||||
@Test
|
||||
public void backspaceDoesNothingAtOrigin() {
|
||||
pressKey(KeyType.Backspace);
|
||||
pressKey(Backspace);
|
||||
assertCursorPosition(0, 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void backspaceWorksAfterInput() {
|
||||
enterCharacters("12345");
|
||||
pressKeyTimes(KeyType.Backspace, 2);
|
||||
pressKeyTimes(Backspace, 2);
|
||||
assertCursorPosition(3, 0);
|
||||
assertCharacterPositions(new char[][] { { '1', '2', '3', ' ', ' ', ' ' } });
|
||||
}
|
||||
|
@ -244,7 +245,7 @@ public class LispTerminalTest {
|
|||
public void backspaceWorksAcrossRow() {
|
||||
setColumns(4);
|
||||
enterCharacters("1234567");
|
||||
pressKeyTimes(KeyType.Backspace, 5);
|
||||
pressKeyTimes(Backspace, 5);
|
||||
assertCursorPosition(2, 0);
|
||||
assertCharacterPositions(new char[][] { { '1', '2', ' ', ' ' }, { ' ', ' ', ' ', ' ' } });
|
||||
}
|
||||
|
@ -252,22 +253,22 @@ public class LispTerminalTest {
|
|||
@Test
|
||||
public void backspaceWorksInMiddleOfInput() {
|
||||
enterCharacters("12345");
|
||||
pressKeyTimes(KeyType.ArrowLeft, 2);
|
||||
pressKey(KeyType.Backspace);
|
||||
pressKeyTimes(ArrowLeft, 2);
|
||||
pressKey(Backspace);
|
||||
assertCursorPosition(2, 0);
|
||||
assertCharacterPositions(new char[][] { { '1', '2', '4', '5' } });
|
||||
}
|
||||
|
||||
@Test
|
||||
public void deleteDoesNothingAtOrigin() {
|
||||
pressKey(KeyType.Delete);
|
||||
pressKey(Delete);
|
||||
assertCursorPosition(0, 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void deleteDoesNothingAtEndOfInput() {
|
||||
enterCharacters("del");
|
||||
pressKey(KeyType.Delete);
|
||||
pressKey(Delete);
|
||||
assertCursorPosition(3, 0);
|
||||
assertCharacterPositions(new char[][] { { 'd', 'e', 'l' } });
|
||||
}
|
||||
|
@ -275,8 +276,8 @@ public class LispTerminalTest {
|
|||
@Test
|
||||
public void deleteWorksAtStartOfInput() {
|
||||
enterCharacters("del");
|
||||
pressKeyTimes(KeyType.ArrowLeft, 3);
|
||||
pressKeyTimes(KeyType.Delete, 3);
|
||||
pressKeyTimes(ArrowLeft, 3);
|
||||
pressKeyTimes(Delete, 3);
|
||||
assertCursorPosition(0, 0);
|
||||
assertCharacterPositions(new char[][] { { ' ', ' ', ' ' } });
|
||||
}
|
||||
|
@ -285,56 +286,56 @@ public class LispTerminalTest {
|
|||
public void deleteWorksAcrossRow() {
|
||||
setColumns(4);
|
||||
enterCharacters("delete");
|
||||
pressKeyTimes(KeyType.ArrowLeft, 5);
|
||||
pressKey(KeyType.Delete);
|
||||
pressKeyTimes(ArrowLeft, 5);
|
||||
pressKey(Delete);
|
||||
assertCursorPosition(1, 0);
|
||||
assertCharacterPositions(new char[][] { { 'd', 'l', 'e', 't' }, { 'e', ' ' } });
|
||||
}
|
||||
|
||||
@Test
|
||||
public void enterMovesToNextLine() {
|
||||
pressKey(KeyType.Enter);
|
||||
pressKey(Enter);
|
||||
assertCursorPosition(0, 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void enterWritesLineToPipedStream() {
|
||||
enterCharacters("enter");
|
||||
pressKey(KeyType.Enter);
|
||||
pressKey(Enter);
|
||||
assertInputWritten("enter\n");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void enterPressedInMiddleOfInput_WritesEntireLineToPipedStream() {
|
||||
enterCharacters("enter");
|
||||
pressKeyTimes(KeyType.ArrowLeft, 2);
|
||||
pressKey(KeyType.Enter);
|
||||
pressKeyTimes(ArrowLeft, 2);
|
||||
pressKey(Enter);
|
||||
assertInputWritten("enter\n");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void enterAfterInsertedText_WritesLineToPipedStream() {
|
||||
enterCharacters("enter");
|
||||
pressKeyTimes(KeyType.ArrowLeft, 2);
|
||||
pressKeyTimes(ArrowLeft, 2);
|
||||
enterCharacters("||");
|
||||
pressKey(KeyType.Enter);
|
||||
pressKey(Enter);
|
||||
assertInputWritten("ent||er\n");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void enterAfterBackspace_WritesLineToPipedStream() {
|
||||
enterCharacters("enter");
|
||||
pressKeyTimes(KeyType.Backspace, 2);
|
||||
pressKey(KeyType.Enter);
|
||||
pressKeyTimes(Backspace, 2);
|
||||
pressKey(Enter);
|
||||
assertInputWritten("ent\n");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void enterAfterDelete_WritesLineToPipedStream() {
|
||||
enterCharacters("enter");
|
||||
pressKeyTimes(KeyType.ArrowLeft, 2);
|
||||
pressKeyTimes(KeyType.Delete, 2);
|
||||
pressKey(KeyType.Enter);
|
||||
pressKeyTimes(ArrowLeft, 2);
|
||||
pressKeyTimes(Delete, 2);
|
||||
pressKey(Enter);
|
||||
assertInputWritten("ent\n");
|
||||
}
|
||||
|
||||
|
@ -349,7 +350,7 @@ public class LispTerminalTest {
|
|||
@Test
|
||||
public void controlDWorksInMiddleOfInput() {
|
||||
enterCharacters("control-d");
|
||||
pressKeyTimes(KeyType.ArrowLeft, 2);
|
||||
pressKeyTimes(ArrowLeft, 2);
|
||||
enterControlCharacter('d');
|
||||
assertInputStreamClosed();
|
||||
assertInputWritten("control-d\n");
|
||||
|
@ -357,7 +358,7 @@ public class LispTerminalTest {
|
|||
|
||||
@Test
|
||||
public void escapeDoesNothing() {
|
||||
pressKey(KeyType.Escape);
|
||||
pressKey(Escape);
|
||||
assertCursorPosition(0, 0);
|
||||
assertInputWritten("");
|
||||
}
|
||||
|
@ -371,7 +372,7 @@ public class LispTerminalTest {
|
|||
|
||||
@Test
|
||||
public void controlEnterDoesNothing() {
|
||||
pressControlKey(KeyType.Enter);
|
||||
pressControlKey(Enter);
|
||||
assertCursorPosition(0, 0);
|
||||
assertInputWritten("");
|
||||
}
|
||||
|
@ -403,9 +404,9 @@ public class LispTerminalTest {
|
|||
public void insertingTextPushesInputPastEndOfBuffer() {
|
||||
setColumns(3);
|
||||
setRows(4);
|
||||
pressKey(KeyType.Enter);
|
||||
pressKey(Enter);
|
||||
enterCharacters("00011122");
|
||||
pressKeyTimes(KeyType.ArrowLeft, 4);
|
||||
pressKeyTimes(ArrowLeft, 4);
|
||||
assertCursorPosition(1, 2);
|
||||
enterCharacters("zz");
|
||||
assertCursorPosition(0, 2);
|
||||
|
@ -418,7 +419,7 @@ public class LispTerminalTest {
|
|||
setColumns(3);
|
||||
setRows(3);
|
||||
enterCharacters("00011122");
|
||||
pressKeyTimes(KeyType.ArrowLeft, 4);
|
||||
pressKeyTimes(ArrowLeft, 4);
|
||||
assertCursorPosition(1, 1);
|
||||
enterCharacters("zz");
|
||||
assertCursorPosition(1, 1);
|
||||
|
@ -454,7 +455,7 @@ public class LispTerminalTest {
|
|||
public void printedOutputDoesNotOverwriteInput() {
|
||||
setColumns(3);
|
||||
enterCharacters("01201201");
|
||||
pressKeyTimes(KeyType.ArrowLeft, 5);
|
||||
pressKeyTimes(ArrowLeft, 5);
|
||||
produceOutput("out");
|
||||
assertCursorPosition(0, 4);
|
||||
assertCharacterPositions(new char[][] { { '0', '1', '2' }, { '0', '1', '2' }, { '0', '1', 'o' },
|
||||
|
@ -465,8 +466,8 @@ public class LispTerminalTest {
|
|||
public void printedOutputDoesNotOverwriteInput_AfterEnter() {
|
||||
setColumns(3);
|
||||
enterCharacters("01201201");
|
||||
pressKeyTimes(KeyType.ArrowLeft, 5);
|
||||
pressKey(KeyType.Enter);
|
||||
pressKeyTimes(ArrowLeft, 5);
|
||||
pressKey(Enter);
|
||||
produceOutput("out");
|
||||
assertCursorPosition(0, 4);
|
||||
assertCharacterPositions(new char[][] { { '0', '1', '2' }, { '0', '1', '2' }, { '0', '1', ' ' },
|
||||
|
@ -476,12 +477,35 @@ public class LispTerminalTest {
|
|||
@Test
|
||||
public void resizeIsHandledGracefully() {
|
||||
enterCharacters("resize");
|
||||
pressKey(KeyType.Enter);
|
||||
pressKey(Enter);
|
||||
enterCharacters("test");
|
||||
setColumns(10);
|
||||
assertCursorPosition(4, 0);
|
||||
assertCharacterPositions(new char[][] { { 't', 'e', 's', 't', ' ', ' ', ' ', ' ', ' ', ' ' },
|
||||
{ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' } });
|
||||
setColumns(3);
|
||||
assertCursorPosition(1, 1);
|
||||
assertCharacterPositions(new char[][] { { 't', 'e', 's' }, { 't', ' ', ' ' } });
|
||||
}
|
||||
|
||||
@Test
|
||||
public void backspaceWorksAfterResize() {
|
||||
enterCharacters("resize");
|
||||
pressKey(Enter);
|
||||
enterCharacters("test");
|
||||
setColumns(3);
|
||||
pressKeyTimes(Backspace, 20);
|
||||
assertCursorPosition(0, 0);
|
||||
assertCharacterPositions(new char[][] { { ' ', ' ', ' ' }, { ' ', ' ', ' ' } });
|
||||
}
|
||||
|
||||
@Test
|
||||
public void deleteWorksAfterResize() {
|
||||
enterCharacters("resize");
|
||||
pressKey(Enter);
|
||||
enterCharacters("test");
|
||||
setColumns(3);
|
||||
pressKeyTimes(ArrowLeft, 20);
|
||||
pressKeyTimes(Delete, 20);
|
||||
pressKeyTimes(ArrowRight, 20);
|
||||
assertCursorPosition(0, 0);
|
||||
assertCharacterPositions(new char[][] { { ' ', ' ', ' ' }, { ' ', ' ', ' ' } });
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue