diff --git a/compiler/src/prog8/compiler/ModuleImporter.kt b/compiler/src/prog8/compiler/ModuleImporter.kt index c02b6bbe3..a0555ad37 100644 --- a/compiler/src/prog8/compiler/ModuleImporter.kt +++ b/compiler/src/prog8/compiler/ModuleImporter.kt @@ -8,14 +8,13 @@ import prog8.ast.statements.Directive import prog8.ast.statements.DirectiveArg import prog8.parser.Prog8Parser import prog8.parser.SourceCode -import java.io.File import java.nio.file.Path import kotlin.io.path.* class ModuleImporter(private val program: Program, private val compilationTargetName: String, - private val errors: IErrorReporter, + val errors: IErrorReporter, libdirs: List) { private val libpaths: List = libdirs.map { Path(it) } diff --git a/compiler/test/ModuleImporterTests.kt b/compiler/test/ModuleImporterTests.kt index 28af6954c..f39f9096b 100644 --- a/compiler/test/ModuleImporterTests.kt +++ b/compiler/test/ModuleImporterTests.kt @@ -1,16 +1,19 @@ package prog8tests import org.hamcrest.MatcherAssert.assertThat -import org.hamcrest.Matchers.containsString -import org.hamcrest.Matchers.equalTo +import org.hamcrest.Matchers.* +import org.hamcrest.core.Is import org.junit.jupiter.api.* import prog8.ast.Program -import prog8.compiler.ErrorReporter +import prog8.compiler.IErrorReporter import prog8.compiler.ModuleImporter import prog8.parser.ParseError import prog8tests.helpers.* import kotlin.io.path.* import kotlin.test.assertContains +import kotlin.test.assertEquals +import kotlin.test.assertFailsWith +import kotlin.test.assertFalse @TestInstance(TestInstance.Lifecycle.PER_CLASS) @@ -23,10 +26,12 @@ class TestModuleImporter { program = Program("foo", DummyFunctions, DummyMemsizer) } - private fun makeImporter(vararg searchIn: String): ModuleImporter = makeImporter(searchIn.asList()) + private fun makeImporter(errors: IErrorReporter?, vararg searchIn: String): ModuleImporter { + return makeImporter(errors, searchIn.asList()) + } - private fun makeImporter(searchIn: Iterable) = - ModuleImporter(program, "blah", ErrorReporter(), searchIn.toList()) + private fun makeImporter(errors: IErrorReporter? = null, searchIn: Iterable) = + ModuleImporter(program, "blah", errors ?: ErrorReporterForTests(), searchIn.toList()) @Nested inner class Constructor { @@ -52,11 +57,11 @@ class TestModuleImporter { @Test fun testNonexisting() { val dirRel = assumeDirectory(".", workingDir.relativize(fixturesDir)) - val importer = makeImporter(dirRel.invariantSeparatorsPathString) + val importer = makeImporter(null, dirRel.invariantSeparatorsPathString) val srcPathRel = assumeNotExists(dirRel, "i_do_not_exist") val srcPathAbs = srcPathRel.absolute() - assertThrows { importer.importModule(srcPathRel) } + assertFailsWith { importer.importModule(srcPathRel) } .let { assertThat( ".file should be normalized", @@ -69,7 +74,7 @@ class TestModuleImporter { } assertThat(program.modules.size, equalTo(1)) - assertThrows { importer.importModule(srcPathAbs) } + assertFailsWith { importer.importModule(srcPathAbs) } .let { assertThat( ".file should be normalized", @@ -88,9 +93,9 @@ class TestModuleImporter { val srcPathRel = assumeDirectory(workingDir.relativize(fixturesDir)) val srcPathAbs = srcPathRel.absolute() val searchIn = Path(".", "$srcPathRel").invariantSeparatorsPathString - val importer = makeImporter(searchIn) + val importer = makeImporter(null, searchIn) - assertThrows { importer.importModule(srcPathRel) } + assertFailsWith { importer.importModule(srcPathRel) } .let { assertThat( ".file should be normalized", @@ -103,7 +108,7 @@ class TestModuleImporter { } assertThat(program.modules.size, equalTo(1)) - assertThrows { importer.importModule(srcPathAbs) } + assertFailsWith { importer.importModule(srcPathAbs) } .let { assertThat( ".file should be normalized", @@ -126,7 +131,7 @@ class TestModuleImporter { val searchIn = listOf( Path(".").div(workingDir.relativize(fixturesDir)), // we do want a dot "." in front ).map { it.invariantSeparatorsPathString } - val importer = makeImporter(searchIn) + val importer = makeImporter(null, searchIn) val fileName = "simple_main.p8" val path = assumeReadableFile(searchIn[0], fileName) @@ -141,7 +146,7 @@ class TestModuleImporter { val searchIn = listOf( Path(".").div(workingDir.relativize(fixturesDir)), // we do want a dot "." in front ).map { it.invariantSeparatorsPathString } - val importer = makeImporter(searchIn) + val importer = makeImporter(null, searchIn) val fileName = "simple_main.p8" val path = assumeReadableFile(searchIn[0], fileName) assertThat("sanity check: path should NOT be absolute", path.isAbsolute, equalTo(false)) @@ -157,7 +162,7 @@ class TestModuleImporter { val searchIn = Path(".") .div(workingDir.relativize(fixturesDir)) .invariantSeparatorsPathString - val importer = makeImporter(searchIn) + val importer = makeImporter(null, searchIn) val fileName = "simple_main.p8" val path = Path(".", fileName) assumeReadableFile(searchIn, path) @@ -181,13 +186,13 @@ class TestModuleImporter { @Test fun testWithSyntaxError() { val searchIn = assumeDirectory("./", workingDir.relativize(fixturesDir)) - val importer = makeImporter(searchIn.invariantSeparatorsPathString) + val importer = makeImporter(null, searchIn.invariantSeparatorsPathString) val srcPath = assumeReadableFile(fixturesDir, "file_with_syntax_error.p8") val act = { importer.importModule(srcPath) } repeat(2) { n -> - assertThrows(count[n] + " call") { act() }.let { + assertFailsWith(count[n] + " call") { act() }.let { assertThat(it.position.file, equalTo(srcPath.absolutePathString())) assertThat("line; should be 1-based", it.position.line, equalTo(2)) assertThat("startCol; should be 0-based", it.position.startCol, equalTo(6)) @@ -210,14 +215,14 @@ class TestModuleImporter { private fun doTestImportingFileWithSyntaxError(repetitions: Int) { val searchIn = assumeDirectory("./", workingDir.relativize(fixturesDir)) - val importer = makeImporter(searchIn.invariantSeparatorsPathString) + val importer = makeImporter(null, searchIn.invariantSeparatorsPathString) val importing = assumeReadableFile(fixturesDir, "import_file_with_syntax_error.p8") val imported = assumeReadableFile(fixturesDir, "file_with_syntax_error.p8") val act = { importer.importModule(importing) } repeat(repetitions) { n -> - assertThrows(count[n] + " call") { act() }.let { + assertFailsWith(count[n] + " call") { act() }.let { assertThat(it.position.file, equalTo(imported.absolutePathString())) assertThat("line; should be 1-based", it.position.line, equalTo(2)) assertThat("startCol; should be 0-based", it.position.startCol, equalTo(6)) @@ -238,21 +243,24 @@ class TestModuleImporter { @Test fun testWithNonExistingName() { val searchIn = assumeDirectory("./", workingDir.relativize(fixturesDir)) - val importer = makeImporter(searchIn.invariantSeparatorsPathString) + val errors = ErrorReporterForTests() + val importer = makeImporter(errors, searchIn.invariantSeparatorsPathString) val filenameNoExt = assumeNotExists(fixturesDir, "i_do_not_exist").name val filenameWithExt = assumeNotExists(fixturesDir, "i_do_not_exist.p8").name repeat(2) { n -> - assertThrows(count[n] + " call / NO .p8 extension") - { importer.importLibraryModule(filenameNoExt) }.let { - assertThat(it.message!!, containsString(filenameWithExt)) - } + val result = importer.importLibraryModule(filenameNoExt) + assertThat(count[n] + " call / NO .p8 extension", result, Is(nullValue())) + assertFalse(errors.noErrors(), count[n] + " call / NO .p8 extension") + assertEquals(errors.errors.single(), "imported file not found: i_do_not_exist.p8") + errors.report() assertThat(program.modules.size, equalTo(1)) - assertThrows(count[n] + " call / with .p8 extension") - { importer.importLibraryModule(filenameWithExt) }.let { - assertThat(it.message!!, containsString(filenameWithExt)) - } + val result2 = importer.importLibraryModule(filenameWithExt) + assertThat(count[n] + " call / with .p8 extension", result2, Is(nullValue())) + assertFalse(importer.errors.noErrors(), count[n] + " call / with .p8 extension") + assertEquals(errors.errors.single(), "imported file not found: i_do_not_exist.p8.p8") // TODO don't duplicate the p8 extension in the import logic... + errors.report() assertThat(program.modules.size, equalTo(1)) } } @@ -265,11 +273,11 @@ class TestModuleImporter { @Test fun testWithSyntaxError() { val searchIn = assumeDirectory("./", workingDir.relativize(fixturesDir)) - val importer = makeImporter(searchIn.invariantSeparatorsPathString) + val importer = makeImporter(null, searchIn.invariantSeparatorsPathString) val srcPath = assumeReadableFile(fixturesDir, "file_with_syntax_error.p8") repeat(2) { n -> - assertThrows(count[n] + " call") + assertFailsWith(count[n] + " call") { importer.importLibraryModule(srcPath.nameWithoutExtension) }.let { assertThat(it.position.file, equalTo(srcPath.absolutePathString())) assertThat("line; should be 1-based", it.position.line, equalTo(2)) @@ -283,14 +291,14 @@ class TestModuleImporter { private fun doTestImportingFileWithSyntaxError(repetitions: Int) { val searchIn = assumeDirectory("./", workingDir.relativize(fixturesDir)) - val importer = makeImporter(searchIn.invariantSeparatorsPathString) + val importer = makeImporter(null, searchIn.invariantSeparatorsPathString) val importing = assumeReadableFile(fixturesDir, "import_file_with_syntax_error.p8") val imported = assumeReadableFile(fixturesDir, "file_with_syntax_error.p8") val act = { importer.importLibraryModule(importing.nameWithoutExtension) } repeat(repetitions) { n -> - assertThrows(count[n] + " call") { act() }.let { + assertFailsWith(count[n] + " call") { act() }.let { assertThat(it.position.file, equalTo(imported.normalize().absolutePathString())) assertThat("line; should be 1-based", it.position.line, equalTo(2)) assertThat("startCol; should be 0-based", it.position.startCol, equalTo(6)) diff --git a/compiler/test/helpers/ErrorReporterForTests.kt b/compiler/test/helpers/ErrorReporterForTests.kt new file mode 100644 index 000000000..bfb589af9 --- /dev/null +++ b/compiler/test/helpers/ErrorReporterForTests.kt @@ -0,0 +1,25 @@ +package prog8tests.helpers + +import prog8.ast.base.Position +import prog8.compiler.IErrorReporter + +class ErrorReporterForTests: IErrorReporter { + + val errors = mutableListOf() + val warnings = mutableListOf() + + override fun err(msg: String, position: Position) { + errors.add(msg) + } + + override fun warn(msg: String, position: Position) { + warnings.add(msg) + } + + override fun noErrors(): Boolean = errors.isEmpty() + + override fun report() { + errors.clear() + warnings.clear() + } +} diff --git a/compilerAst/test/TestSourceCode.kt b/compilerAst/test/TestSourceCode.kt index a35420a83..52b2e944f 100644 --- a/compilerAst/test/TestSourceCode.kt +++ b/compilerAst/test/TestSourceCode.kt @@ -3,7 +3,6 @@ package prog8tests import org.junit.jupiter.api.Disabled import org.junit.jupiter.api.Test import org.junit.jupiter.api.TestInstance -import org.junit.jupiter.api.assertThrows import prog8.parser.SourceCode import prog8tests.helpers.* import kotlin.io.path.Path @@ -129,14 +128,14 @@ class TestSourceCode { val pathString = "/prog8lib/i_do_not_exist" assumeNotExists(resourcesDir, pathString.substring(1)) - assertThrows { SourceCode.fromResources(pathString) } + assertFailsWith { SourceCode.fromResources(pathString) } } @Test fun testFromResourcesWithNonExistingFile_withoutLeadingSlash() { val pathString = "prog8lib/i_do_not_exist" assumeNotExists(resourcesDir, pathString) - assertThrows { SourceCode.fromResources(pathString) } + assertFailsWith { SourceCode.fromResources(pathString) } } @Test @@ -144,7 +143,7 @@ class TestSourceCode { fun testFromResourcesWithDirectory() { val pathString = "/prog8lib" assumeDirectory(resourcesDir, pathString.substring(1)) - assertThrows { SourceCode.fromResources(pathString) } + assertFailsWith { SourceCode.fromResources(pathString) } } } diff --git a/compilerAst/test/ast/ProgramTests.kt b/compilerAst/test/ast/ProgramTests.kt index ef1ecf7f4..e01e44324 100644 --- a/compilerAst/test/ast/ProgramTests.kt +++ b/compilerAst/test/ast/ProgramTests.kt @@ -1,4 +1,4 @@ -package prog8tests +package prog8tests.ast import org.hamcrest.MatcherAssert.assertThat @@ -7,7 +7,6 @@ import org.hamcrest.Matchers.equalTo import org.junit.jupiter.api.Nested import org.junit.jupiter.api.Test import org.junit.jupiter.api.TestInstance -import org.junit.jupiter.api.assertThrows import prog8.ast.Module import prog8.ast.Program import prog8.ast.base.Position @@ -15,6 +14,7 @@ import prog8.ast.internedStringsModuleName import prog8tests.helpers.DummyFunctions import prog8tests.helpers.DummyMemsizer import kotlin.test.assertContains +import kotlin.test.assertFailsWith import kotlin.test.assertSame @@ -49,11 +49,11 @@ class ProgramTests { assertSame(program, m1.program) assertSame(program.namespace, m1.parent) - assertThrows { program.addModule(m1) } + assertFailsWith { program.addModule(m1) } .let { assertThat(it.message, containsString(m1.name)) } val m2 = Module(m1.name, mutableListOf(), m1.position, m1.source) - assertThrows { program.addModule(m2) } + assertFailsWith { program.addModule(m2) } .let { assertThat(it.message, containsString(m2.name)) } } } @@ -75,7 +75,7 @@ class ProgramTests { val program = Program("foo", DummyFunctions, DummyMemsizer) val m = Module("bar", mutableListOf(), Position.DUMMY, null) - assertThrows { program.moveModuleToFront(m) } + assertFailsWith { program.moveModuleToFront(m) } } @Test fun withFirstOfPreviouslyAddedModules() { diff --git a/compilerAst/test/helpers_pathsTests.kt b/compilerAst/test/helpers_pathsTests.kt index 46270f9f7..efc5ddc5b 100644 --- a/compilerAst/test/helpers_pathsTests.kt +++ b/compilerAst/test/helpers_pathsTests.kt @@ -5,10 +5,10 @@ import org.hamcrest.Matchers.`is` import org.junit.jupiter.api.Nested import org.junit.jupiter.api.Test import org.junit.jupiter.api.TestInstance -import org.junit.jupiter.api.assertThrows import prog8tests.helpers.* import kotlin.io.path.Path import kotlin.io.path.div +import kotlin.test.assertFailsWith // Do not move into folder helpers/! @@ -33,14 +33,14 @@ class PathsHelpersTests { @Test fun `on existing file`() { - assertThrows { + assertFailsWith { assumeNotExists(fixturesDir.div("simple_main.p8")) } } @Test fun `on existing directory`() { - assertThrows { + assertFailsWith { assumeNotExists(fixturesDir) } } @@ -59,14 +59,14 @@ class PathsHelpersTests { @Test fun `on existing file`() { val path = fixturesDir.div("simple_main.p8") - assertThrows { + assertFailsWith { assumeNotExists("$path") } } @Test fun `on existing directory`() { - assertThrows { + assertFailsWith { assumeNotExists("$fixturesDir") } } @@ -84,14 +84,14 @@ class PathsHelpersTests { @Test fun `on existing file`() { - assertThrows { + assertFailsWith { assumeNotExists(fixturesDir, "simple_main.p8") } } @Test fun `on existing directory`() { - assertThrows { + assertFailsWith { assumeNotExists(fixturesDir, "..") } } @@ -106,7 +106,7 @@ class PathsHelpersTests { @Test fun `on non-existing path`() { val path = fixturesDir.div("i_do_not_exist") - assertThrows { + assertFailsWith { assumeDirectory(path) } } @@ -114,7 +114,7 @@ class PathsHelpersTests { @Test fun `on existing file`() { val path = fixturesDir.div("simple_main.p8") - assertThrows { + assertFailsWith { assumeDirectory(path) } } @@ -131,7 +131,7 @@ class PathsHelpersTests { @Test fun `on non-existing path`() { val path = fixturesDir.div("i_do_not_exist") - assertThrows { + assertFailsWith { assumeDirectory("$path") } } @@ -139,7 +139,7 @@ class PathsHelpersTests { @Test fun `on existing file`() { val path = fixturesDir.div("simple_main.p8") - assertThrows { + assertFailsWith { assumeDirectory("$path") } } @@ -156,14 +156,14 @@ class PathsHelpersTests { inner class WithPathAndStringArgs { @Test fun `on non-existing path`() { - assertThrows { + assertFailsWith { assumeDirectory(fixturesDir, "i_do_not_exist") } } @Test fun `on existing file`() { - assertThrows { + assertFailsWith { assumeDirectory(fixturesDir, "simple_main.p8") } } @@ -182,14 +182,14 @@ class PathsHelpersTests { inner class WithStringAndStringArgs { @Test fun `on non-existing path`() { - assertThrows { + assertFailsWith { assumeDirectory("$fixturesDir", "i_do_not_exist") } } @Test fun `on existing file`() { - assertThrows { + assertFailsWith { assumeDirectory("$fixturesDir", "simple_main.p8") } } @@ -208,14 +208,14 @@ class PathsHelpersTests { inner class WithStringAndPathArgs { @Test fun `on non-existing path`() { - assertThrows { + assertFailsWith { assumeDirectory("$fixturesDir", Path("i_do_not_exist")) } } @Test fun `on existing file`() { - assertThrows { + assertFailsWith { assumeDirectory("$fixturesDir", Path("simple_main.p8")) } } @@ -240,7 +240,7 @@ class PathsHelpersTests { @Test fun `on non-existing path`() { val path = fixturesDir.div("i_do_not_exist") - assertThrows { + assertFailsWith { assumeReadableFile(path) } } @@ -254,7 +254,7 @@ class PathsHelpersTests { @Test fun `on directory`() { - assertThrows { + assertFailsWith { assumeReadableFile(fixturesDir) } } @@ -266,7 +266,7 @@ class PathsHelpersTests { @Test fun `on non-existing path`() { val path = fixturesDir.div("i_do_not_exist") - assertThrows { + assertFailsWith { assumeReadableFile("$path") } } @@ -280,7 +280,7 @@ class PathsHelpersTests { @Test fun `on directory`() { - assertThrows { + assertFailsWith { assumeReadableFile("$fixturesDir") } } @@ -290,7 +290,7 @@ class PathsHelpersTests { inner class WithPathAndStringArgs { @Test fun `on non-existing path`() { - assertThrows { + assertFailsWith { assumeReadableFile(fixturesDir, "i_do_not_exist") } } @@ -304,7 +304,7 @@ class PathsHelpersTests { @Test fun `on directory`() { - assertThrows { + assertFailsWith { assumeReadableFile(fixturesDir, "..") } } @@ -314,7 +314,7 @@ class PathsHelpersTests { inner class WithPathAndPathArgs { @Test fun `on non-existing path`() { - assertThrows { + assertFailsWith { assumeReadableFile(fixturesDir, Path("i_do_not_exist")) } } @@ -328,7 +328,7 @@ class PathsHelpersTests { @Test fun `on directory`() { - assertThrows { + assertFailsWith { assumeReadableFile(fixturesDir, Path("..")) } } @@ -338,7 +338,7 @@ class PathsHelpersTests { inner class WithStringAndStringArgs { @Test fun `on non-existing path`() { - assertThrows { + assertFailsWith { assumeReadableFile("$fixturesDir", "i_do_not_exist") } } @@ -353,7 +353,7 @@ class PathsHelpersTests { @Test fun `on directory`() { - assertThrows { + assertFailsWith { assumeReadableFile("$fixturesDir", "..") } }