155 lines
5.1 KiB
Kotlin
155 lines
5.1 KiB
Kotlin
package interpreter
|
|
|
|
import environment.RuntimeEnvironment
|
|
import interpreter.InteractiveLispInterpreter.PROMPT
|
|
import org.junit.After
|
|
import org.junit.Assert.assertEquals
|
|
import org.junit.Assert.assertFalse
|
|
import org.junit.Assert.assertTrue
|
|
import org.junit.Before
|
|
import org.junit.Test
|
|
import testutil.TestUtilities.createInputStreamFromString
|
|
import java.io.ByteArrayOutputStream
|
|
import java.io.PrintStream
|
|
import java.text.MessageFormat.format
|
|
import java.util.HashSet
|
|
|
|
class LispInterpreterTest {
|
|
|
|
companion object {
|
|
private const val TERMINATED = "terminated"
|
|
private val FILE = LispInterpreterTest::class.java.getResource("file.lisp").file
|
|
}
|
|
|
|
private var indicatorSet = HashSet<String>()
|
|
private var outputStream = ByteArrayOutputStream()
|
|
private var errorOutputStream = ByteArrayOutputStream()
|
|
|
|
private fun setCommonFeatures() {
|
|
LispInterpreterBuilder.setOutput(PrintStream(outputStream))
|
|
LispInterpreterBuilder.setErrorOutput(PrintStream(errorOutputStream))
|
|
LispInterpreterBuilder.setTerminationFunction { }
|
|
LispInterpreterBuilder.setErrorTerminationFunction { indicatorSet.add(TERMINATED) }
|
|
}
|
|
|
|
private fun assertTerminated() {
|
|
assertTrue(indicatorSet.contains(TERMINATED))
|
|
}
|
|
|
|
private fun assertErrorMessageWritten() {
|
|
assertTrue(errorOutputStream.toByteArray().isNotEmpty())
|
|
}
|
|
|
|
@Before
|
|
fun setUp() {
|
|
indicatorSet.clear()
|
|
outputStream.reset()
|
|
errorOutputStream.reset()
|
|
RuntimeEnvironment.reset()
|
|
LispInterpreterBuilder.reset()
|
|
}
|
|
|
|
@After
|
|
fun tearDown() {
|
|
RuntimeEnvironment.reset()
|
|
LispInterpreterBuilder.reset()
|
|
}
|
|
|
|
@Test
|
|
fun buildInteractiveInterpreter() {
|
|
setCommonFeatures()
|
|
LispInterpreterBuilder.setInput(System.`in`, "stdin")
|
|
val interpreter = LispInterpreterBuilder.build()
|
|
|
|
assertTrue(interpreter is InteractiveLispInterpreter)
|
|
}
|
|
|
|
@Test
|
|
fun buildNonInteractiveInterpreter() {
|
|
setCommonFeatures()
|
|
LispInterpreterBuilder.setInput(System.`in`, "stdin")
|
|
LispInterpreterBuilder.setNotInteractive()
|
|
val interpreter = LispInterpreterBuilder.build()
|
|
|
|
assertFalse(interpreter is InteractiveLispInterpreter)
|
|
assertFalse(interpreter is FileLispInterpreter)
|
|
}
|
|
|
|
@Test
|
|
fun buildFileBasedInterpreter() {
|
|
setCommonFeatures()
|
|
LispInterpreterBuilder.useFile(FILE)
|
|
val interpreter = LispInterpreterBuilder.build()
|
|
|
|
assertTrue(interpreter is FileLispInterpreter)
|
|
}
|
|
|
|
@Test
|
|
fun attemptToBuildInterpreterOnBadFile() {
|
|
setCommonFeatures()
|
|
LispInterpreterBuilder.useFile("does-not-exist.lisp")
|
|
LispInterpreterBuilder.build()
|
|
|
|
assertErrorMessageWritten()
|
|
assertTerminated()
|
|
}
|
|
|
|
@Test
|
|
fun makeSureDecoratorsAreInitializedWithDefaults() {
|
|
LispInterpreterBuilder.build()
|
|
|
|
assertEquals("", RuntimeEnvironment.decoratePrompt(""))
|
|
assertEquals("", RuntimeEnvironment.decorateValueOutput(""))
|
|
assertEquals("", RuntimeEnvironment.decorateWarningOutput(""))
|
|
assertEquals("", RuntimeEnvironment.decorateErrorOutput(""))
|
|
assertEquals("", RuntimeEnvironment.decorateCriticalOutput(""))
|
|
}
|
|
|
|
@Test
|
|
fun makeSureDecoratorsAreSetCorrectly() {
|
|
LispInterpreterBuilder.setPromptDecorator { s -> "#$s#" }
|
|
LispInterpreterBuilder.setValueOutputDecorator { s -> "@$s@" }
|
|
LispInterpreterBuilder.setWarningOutputDecorator { s -> "%$s%" }
|
|
LispInterpreterBuilder.setErrorOutputDecorator { s -> "*$s*" }
|
|
LispInterpreterBuilder.setCriticalOutputDecorator { s -> "$$s$" }
|
|
LispInterpreterBuilder.build()
|
|
|
|
assertEquals("#x#", RuntimeEnvironment.decoratePrompt("x"))
|
|
assertEquals("@x@", RuntimeEnvironment.decorateValueOutput("x"))
|
|
assertEquals("%x%", RuntimeEnvironment.decorateWarningOutput("x"))
|
|
assertEquals("*x*", RuntimeEnvironment.decorateErrorOutput("x"))
|
|
assertEquals("\$x$", RuntimeEnvironment.decorateCriticalOutput("x"))
|
|
}
|
|
|
|
@Test
|
|
fun fileBasedInterpreterWorks_PrintsLastValueOnly() {
|
|
setCommonFeatures()
|
|
LispInterpreterBuilder.useFile(FILE)
|
|
LispInterpreterBuilder.build().interpret()
|
|
|
|
assertEquals("PICKLE\n\n", outputStream.toString())
|
|
assertEquals("", errorOutputStream.toString())
|
|
}
|
|
|
|
@Test
|
|
fun interactiveInterpreterWorks() {
|
|
setCommonFeatures()
|
|
LispInterpreterBuilder.setInput(createInputStreamFromString("'pickle"), "input")
|
|
LispInterpreterBuilder.build().interpret()
|
|
|
|
assertEquals(format("{0}\n{1}\n{0}\n", PROMPT, "PICKLE"), outputStream.toString())
|
|
assertEquals("", errorOutputStream.toString())
|
|
}
|
|
|
|
@Test
|
|
fun interpreterHandlesError() {
|
|
setCommonFeatures()
|
|
LispInterpreterBuilder.setNotInteractive()
|
|
LispInterpreterBuilder.setInput(createInputStreamFromString("pickle"), "input")
|
|
LispInterpreterBuilder.build().interpret()
|
|
|
|
assertEquals("\n", outputStream.toString())
|
|
assertEquals("[error] symbol PICKLE has no value\n", errorOutputStream.toString())
|
|
}
|
|
}
|