package function.builtin import environment.RuntimeEnvironment import error.ErrorManager import function.ArgumentValidator.BadArgumentTypeException import function.ArgumentValidator.TooFewArgumentsException import function.ArgumentValidator.TooManyArgumentsException import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Assertions.assertThrows import org.junit.jupiter.api.Test import testutil.LispTestInstance import testutil.SymbolAndFunctionCleaner import testutil.TestUtilities.evaluateString import testutil.TypeAssertions.assertNil import testutil.TypeAssertions.assertT import java.io.ByteArrayOutputStream import java.io.PrintStream @LispTestInstance class LoadTest : SymbolAndFunctionCleaner() { private var outputStream = ByteArrayOutputStream() private var errorOutputStream = ByteArrayOutputStream() private fun assertWarningMessagePrinted() { assertThat(outputStream.toByteArray()).isNotEmpty() assertThat(errorOutputStream.toByteArray()).isEmpty() } private fun assertErrorMessagePrinted() { assertThat(errorOutputStream.toByteArray()).isNotEmpty() assertThat(outputStream.toByteArray()).isEmpty() } private fun assertNothingPrinted() { assertThat(errorOutputStream.toByteArray()).isEmpty() assertThat(outputStream.toByteArray()).isEmpty() } override fun additionalSetUp() { outputStream.reset() errorOutputStream.reset() RuntimeEnvironment.reset() RuntimeEnvironment.output = PrintStream(outputStream) RuntimeEnvironment.errorOutput = PrintStream(errorOutputStream) RuntimeEnvironment.errorManager = ErrorManager() RuntimeEnvironment.path = "" RuntimeEnvironment.warningOutputDecorator = { it } RuntimeEnvironment.errorOutputDecorator = { it } } override fun additionalTearDown() { RuntimeEnvironment.reset() } @Test fun loadEmptyFileName_ReturnsNilAndPrintsWarning() { val input = "(load \"\")" assertNil(evaluateString(input)) assertWarningMessagePrinted() } @Test fun loadGoodFile_ReturnsTAndPrintsNothing() { val file = LoadTest::class.java.getResource("load-good.lisp").file val input = "(load \"$file\")" assertT(evaluateString(input)) assertNothingPrinted() } @Test fun loadBadFile_ReturnsNilAndPrintsError() { val file = LoadTest::class.java.getResource("load-bad.lisp").file val input = "(load \"$file\")" assertNil(evaluateString(input)) assertErrorMessagePrinted() } @Test fun loadNonExistentFile_ReturnsNilAndPrintsWarning() { val input = "(load \"doesNotExist.lisp\")" assertNil(evaluateString(input)) assertWarningMessagePrinted() } @Test fun nestedLoadsInTheSameDirectory() { val file = LoadTest::class.java.getResource("nested/nested.lisp").file val input = "(load \"$file\")" assertT(evaluateString(input)) assertNothingPrinted() } @Test fun nestedLoadsInDifferentDirectories() { val file = LoadTest::class.java.getResource("nested/one/load-one.lisp").file val input = "(load \"$file\")" assertT(evaluateString(input)) assertNothingPrinted() } @Test fun loadWithBadArgumentType() { assertThrows(BadArgumentTypeException::class.java) { evaluateString("(load '1)") } } @Test fun loadWithTooManyArguments() { assertThrows(TooManyArgumentsException::class.java) { evaluateString("(load \"1\" \"2\")") } } @Test fun loadWithTooFewArguments() { assertThrows(TooFewArgumentsException::class.java) { evaluateString("(load)") } } @Test fun loadUsesRuntimePath() { RuntimeEnvironment.path = LoadTest::class.java.getResource("nested/one/").path val input = "(load \"load-one.lisp\")" assertT(evaluateString(input)) assertNothingPrinted() } }