Refactor main interpreter code

Fixed several minor issues

Only print the last value when interpreting a file

Resolves #4
This commit is contained in:
Mike Cifelli 2017-03-21 15:03:16 -04:00
parent 5cb6212d2a
commit 058e937c3e
11 changed files with 187 additions and 133 deletions

View File

@ -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) {

View File

@ -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();
}
}

View File

@ -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();
}
}

View File

@ -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();
}

View File

@ -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();

View File

@ -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);

View File

@ -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));

View File

@ -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() {

View File

@ -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 {

View File

@ -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);
}

View File

@ -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[][] { { ' ', ' ', ' ' }, { ' ', ' ', ' ' } });
}
}