package main; import static java.text.MessageFormat.format; 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.input.KeyType; import com.googlecode.lanterna.terminal.virtual.DefaultVirtualTerminal; import environment.RuntimeEnvironment; import interpreter.LispInterpreterBuilderImpl; import terminal.*; public class MainTest { private RuntimeEnvironment environment; private CountDownLatch latch; public MainTest() { this.environment = RuntimeEnvironment.getInstance(); } private void runInterpreterWithFile(String fileName) { TerminalConfiguration configuration = new TerminalConfiguration(); configuration.setInputPair(new PipedOutputStream(), new PipedInputStream()); configuration.setOutputPair(new PipedOutputStream(), new PipedInputStream()); configuration.setTerminal(new DefaultVirtualTerminal()); LispMain main = new LispMain(new LispInterpreterBuilderImpl() {}, configuration); main.runWithFile(fileName); } private VirtualTerminalInteractor runInterpreterAndGetInteractor() { VirtualTerminalInteractor terminal = new VirtualTerminalInteractor(); latch = new CountDownLatch(1); new Thread(() -> { LispMain main = new LispMain(new LispInterpreterBuilderImpl() {}, terminal.getConfiguration()); main.runInteractive(); latch.countDown(); }).start(); return terminal; } private void waitForInterpreterToShutdown() { try { latch.await(); } catch (InterruptedException ignored) {} } private String getSystemOutLog() { return systemOutRule.getLogWithNormalizedLineSeparator(); } private String getSystemErrLog() { return systemErrRule.getLogWithNormalizedLineSeparator(); } @Rule public ExpectedSystemExit exit = ExpectedSystemExit.none(); @Rule public SystemErrRule systemErrRule = new SystemErrRule().enableLog().mute(); @Rule public SystemOutRule systemOutRule = new SystemOutRule().enableLog().mute(); @Before public void setUp() { environment.reset(); } @After public void tearDown() { environment.reset(); } @Test public void runWithBadFile() { String expectedMessage = "[critical] test/main/test-files/bad.lisp (No such file or directory)"; exit.expectSystemExitWithStatus(1); exit.checkAssertionAfterwards(() -> { assertEquals(format("{0}{1}{2}\n", ANSI_PURPLE, expectedMessage, ANSI_RESET), getSystemErrLog()); assertEquals("", getSystemOutLog()); }); runInterpreterWithFile("test/main/test-files/bad.lisp"); } @Test public void runWithFile_PrintsDecoratedLastValueOnly() { runInterpreterWithFile("test/main/test-files/file.lisp"); assertEquals("", getSystemErrLog()); assertEquals(format("{0}{1}{2}\n\n", ANSI_GREEN, "RADISH", ANSI_RESET), getSystemOutLog()); } @Test public void runInteractive() { VirtualTerminalInteractor terminal = runInterpreterAndGetInteractor(); terminal.waitForPrompt(); terminal.enterCharacters("'hi"); terminal.pressKey(KeyType.Enter); terminal.waitForPrompt(); terminal.assertCursorPosition(2, 5); terminal.assertScreenText(GREETING, " ", "~ 'hi ", " ", "HI ", "~ "); terminal.enterControlCharacter('d'); terminal.assertInputStreamClosed(); waitForInterpreterToShutdown(); } @Test public void defaultConstructorCoverage() { new LispMain(); } }