* refactor compilerAst tests, intro prog8test.helpers, @Disable the 3 tests that will pass after subsequent steps of "the plan"

This commit is contained in:
meisl 2021-07-11 17:32:29 +02:00
parent cd295228ef
commit 43c5ab8ecc
5 changed files with 151 additions and 137 deletions

View File

@ -0,0 +1,77 @@
package prog8tests.helpers
import org.junit.jupiter.api.Test
import kotlin.test.*
import kotlin.io.path.*
import prog8.ast.IBuiltinFunctions
import prog8.ast.IMemSizer
import prog8.ast.IStringEncoding
import prog8.ast.base.DataType
import prog8.ast.base.Position
import prog8.ast.expressions.Expression
import prog8.ast.expressions.InferredTypes
import prog8.ast.expressions.NumericLiteralValue
import java.nio.file.Path
val workingDir = Path("").absolute() // Note: Path(".") does NOT work..!
val fixturesDir = workingDir.resolve("test/fixtures")
val resourcesDir = workingDir.resolve("res")
val outputDir = workingDir.resolve("build/tmp/test")
inline fun assumeReadable(path: Path) {
assertTrue(path.isReadable(), "sanity check: should be readable: ${path.absolute()}")
}
inline fun assumeReadableFile(path: Path) {
assertTrue(path.isRegularFile(), "sanity check: should be normal file: ${path.absolute()}")
}
inline fun assumeDirectory(path: Path) {
assertTrue(path.isDirectory(), "sanity check; should be directory: $path")
}
inline fun assumeNotExists(path: Path) {
assertFalse(path.exists(), "sanity check: should not exist: ${path.absolute()}")
}
inline fun sanityCheckDirectories(workingDirName: String? = null) {
if (workingDirName != null)
assertEquals(workingDirName, workingDir.fileName.toString(), "name of current working dir")
assumeDirectory(workingDir)
assumeDirectory(fixturesDir)
assumeDirectory(resourcesDir)
assumeDirectory(outputDir)
}
val DummyEncoding = object : IStringEncoding {
override fun encodeString(str: String, altEncoding: Boolean): List<Short> {
TODO("Not yet implemented")
}
override fun decodeString(bytes: List<Short>, altEncoding: Boolean): String {
TODO("Not yet implemented")
}
}
val DummyFunctions = object : IBuiltinFunctions {
override val names: Set<String> = emptySet()
override val purefunctionNames: Set<String> = emptySet()
override fun constValue(
name: String,
args: List<Expression>,
position: Position,
memsizer: IMemSizer
): NumericLiteralValue? = null
override fun returnType(name: String, args: MutableList<Expression>) = InferredTypes.InferredType.unknown()
}
val DummyMemsizer = object : IMemSizer {
override fun memorySize(dt: DataType): Int = 0
}

View File

@ -1,16 +1,10 @@
package prog8tests
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.TestInstance
import org.junit.jupiter.api.assertThrows
import org.junit.jupiter.api.*
import kotlin.test.*
import prog8tests.helpers.*
import prog8.ast.*
import prog8.ast.base.DataType
import prog8.ast.base.Position
import prog8.ast.expressions.Expression
import prog8.ast.expressions.InferredTypes
import prog8.ast.expressions.NumericLiteralValue
import prog8.parser.Prog8Parser.parseModule
import prog8.parser.SourceCode
@ -21,17 +15,6 @@ import prog8.parser.ParseError
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class TestAstToSourceCode {
object DummyFunctions: IBuiltinFunctions {
override val names: Set<String> = emptySet()
override val purefunctionNames: Set<String> = emptySet()
override fun constValue(name: String, args: List<Expression>, position: Position, memsizer: IMemSizer): NumericLiteralValue? = null
override fun returnType(name: String, args: MutableList<Expression>) = InferredTypes.InferredType.unknown()
}
object DummyMemsizer: IMemSizer {
override fun memorySize(dt: DataType): Int = 0
}
fun generateP8(module: Module) : String {
val program = Program("test", mutableListOf(module), DummyFunctions, DummyMemsizer)
module.linkParents(program)
@ -50,7 +33,7 @@ class TestAstToSourceCode {
val parsedAgain = parseModule(SourceCode.of(generatedText))
return Pair(generatedText, parsedAgain)
} catch (e: ParseError) {
assert(false, { "should produce valid Prog8 but threw $e" })
assert(false) { "should produce valid Prog8 but threw $e" }
throw e
}
}
@ -113,6 +96,7 @@ class TestAstToSourceCode {
}
@Test
@Disabled
fun testCharLiteral_noAlt() {
val orig = SourceCode.of("""
main {
@ -125,6 +109,7 @@ class TestAstToSourceCode {
}
@Test
@Disabled
fun testCharLiteral_withAlt() {
val orig = SourceCode.of("""
main {

View File

@ -3,18 +3,12 @@ package prog8tests
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.TestInstance
import kotlin.test.*
import prog8tests.helpers.*
import java.nio.file.Path // TODO: use kotlin.io.path.Path instead
import kotlin.io.path.*
import prog8.ast.IBuiltinFunctions
import prog8.ast.IMemSizer
import prog8.ast.IStringEncoding
import prog8.ast.Program
import prog8.ast.base.DataType
import prog8.ast.base.Position
import prog8.ast.expressions.Expression
import prog8.ast.expressions.InferredTypes
import prog8.ast.expressions.NumericLiteralValue
import prog8.parser.ModuleImporter
import prog8.parser.ParseError
@ -22,50 +16,29 @@ import prog8.parser.ParseError
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class TestModuleImporter {
object DummyEncoding: IStringEncoding {
override fun encodeString(str: String, altEncoding: Boolean): List<Short> {
TODO("Not yet implemented")
}
override fun decodeString(bytes: List<Short>, altEncoding: Boolean): String {
TODO("Not yet implemented")
}
}
object DummyFunctions: IBuiltinFunctions {
override val names: Set<String> = emptySet()
override val purefunctionNames: Set<String> = emptySet()
override fun constValue(name: String, args: List<Expression>, position: Position, memsizer: IMemSizer): NumericLiteralValue? = null
override fun returnType(name: String, args: MutableList<Expression>) = InferredTypes.InferredType.unknown()
}
object DummyMemsizer: IMemSizer {
override fun memorySize(dt: DataType): Int = 0
}
@Test
fun testImportModuleWithNonExistingPath() {
val program = Program("foo", mutableListOf(), DummyFunctions, DummyMemsizer)
val importer = ModuleImporter(program, DummyEncoding, "blah", listOf("./test/fixtures"))
val searchIn = "./" + workingDir.relativize(fixturesDir).toString().replace("\\", "/")
val importer = ModuleImporter(program, DummyEncoding, "blah", listOf(searchIn))
val srcPath = Path.of("test", "fixtures", "i_do_not_exist")
val srcPath = fixturesDir.resolve("i_do_not_exist")
assumeNotExists(srcPath)
assertFalse(srcPath.exists(), "sanity check: file should not exist")
assertFailsWith<NoSuchFileException> { importer.importModule(srcPath) }
}
@Test
fun testImportModuleWithDirectoryPath() {
val program = Program("foo", mutableListOf(), DummyFunctions, DummyMemsizer)
val importer = ModuleImporter(program, DummyEncoding, "blah", listOf("./test/fixtures"))
val searchIn = "./" + workingDir.relativize(fixturesDir).toString().replace("\\", "/")
val importer = ModuleImporter(program, DummyEncoding, "blah", listOf(searchIn))
val srcPath = Path.of("test", "fixtures")
assertTrue(srcPath.isDirectory(), "sanity check: should be a directory")
val srcPath = fixturesDir
assumeDirectory(srcPath)
// fn importModule(Path) used to check *.isReadable()*, but NOT .isRegularFile():
assertTrue(srcPath.isReadable(), "sanity check: should still be readable")
assumeReadable(srcPath)
assertFailsWith<AccessDeniedException> { importer.importModule(srcPath) }
}
@ -73,10 +46,11 @@ class TestModuleImporter {
@Test
fun testImportModuleWithSyntaxError() {
val program = Program("foo", mutableListOf(), DummyFunctions, DummyMemsizer)
val importer = ModuleImporter(program, DummyEncoding, "blah", listOf("./test/fixtures"))
val searchIn = "./" + workingDir.relativize(fixturesDir).toString().replace("\\", "/")
val importer = ModuleImporter(program, DummyEncoding, "blah", listOf(searchIn))
val filename = "file_with_syntax_error.p8"
val path = Path.of("test", "fixtures", filename)
val path = fixturesDir.resolve(filename)
val act = { importer.importModule(path) }
assertFailsWith<ParseError> { act() }
@ -93,14 +67,16 @@ class TestModuleImporter {
@Test
fun testImportModuleWithImportingModuleWithSyntaxError() {
val program = Program("foo", mutableListOf(), DummyFunctions, DummyMemsizer)
val importer = ModuleImporter(program, DummyEncoding, "blah", listOf("./test/fixtures"))
val searchIn = "./" + workingDir.relativize(fixturesDir).toString().replace("\\", "/")
val importer = ModuleImporter(program, DummyEncoding, "blah", listOf(searchIn))
val importing = Path.of("test", "fixtures", "import_file_with_syntax_error.p8")
val imported = Path.of("test", "fixtures", "file_with_syntax_error.p8")
val importing = fixturesDir.resolve("import_file_with_syntax_error.p8")
val imported = fixturesDir.resolve("file_with_syntax_error.p8")
assumeReadableFile(importing)
assumeReadableFile(imported)
val act = { importer.importModule(importing) }
assertTrue(importing.isRegularFile(), "sanity check: should be regular file")
assertFailsWith<ParseError> { act() }
try {
act()
@ -116,14 +92,15 @@ class TestModuleImporter {
@Test
fun testImportLibraryModuleWithNonExistingName() {
val program = Program("foo", mutableListOf(), DummyFunctions, DummyMemsizer)
val importer = ModuleImporter(program, DummyEncoding, "blah", listOf("./test/fixtures"))
val searchIn = "./" + workingDir.relativize(fixturesDir).toString().replace("\\", "/")
val importer = ModuleImporter(program, DummyEncoding, "blah", listOf(searchIn))
val filenameNoExt = "i_do_not_exist"
val filenameWithExt = filenameNoExt + ".p8"
val srcPathNoExt = Path.of("test", "fixtures", filenameNoExt)
val srcPathWithExt = Path.of("test", "fixtures", filenameWithExt)
val srcPathNoExt = fixturesDir.resolve(filenameNoExt)
val srcPathWithExt = fixturesDir.resolve(filenameWithExt)
assumeNotExists(srcPathNoExt)
assumeNotExists(srcPathWithExt)
assertFalse(srcPathNoExt.exists(), "sanity check: file should not exist")
assertFalse(srcPathWithExt.exists(), "sanity check: file should not exist")
assertFailsWith<NoSuchFileException> { importer.importLibraryModule(filenameNoExt) }
assertFailsWith<NoSuchFileException> { importer.importLibraryModule(filenameWithExt) }
}
@ -131,18 +108,18 @@ class TestModuleImporter {
@Test
fun testImportLibraryModuleWithSyntaxError() {
val program = Program("foo", mutableListOf(), DummyFunctions, DummyMemsizer)
val importer = ModuleImporter(program, DummyEncoding, "blah", listOf("./test/fixtures"))
val searchIn = "./" + workingDir.relativize(fixturesDir).toString().replace("\\", "/")
val importer = ModuleImporter(program, DummyEncoding, "blah", listOf(searchIn))
val srcPath = fixturesDir.resolve("file_with_syntax_error.p8")
assumeReadableFile(srcPath)
val filename = "file_with_syntax_error"
val act = { importer.importLibraryModule(filename) }
val act = { importer.importLibraryModule(srcPath.nameWithoutExtension) }
assertFailsWith<ParseError> { act() }
try {
act()
} catch (e: ParseError) {
val expectedProvenance = Path.of("test", "fixtures", filename + ".p8")
.absolutePathString()
val expectedProvenance = srcPath.absolutePathString()
assertEquals(expectedProvenance, e.position.file)
assertEquals(2, e.position.line, "line; should be 1-based")
assertEquals(6, e.position.startCol, "startCol; should be 0-based")
@ -153,20 +130,21 @@ class TestModuleImporter {
@Test
fun testImportLibraryModuleWithImportingBadModule() {
val program = Program("foo", mutableListOf(), DummyFunctions, DummyMemsizer)
val libdirs = listOf("./test/fixtures")
val importer = ModuleImporter(program, DummyEncoding, "blah", libdirs)
val searchIn = "./" + workingDir.relativize(fixturesDir).toString().replace("\\", "/")
val importer = ModuleImporter(program, DummyEncoding, "blah", listOf(searchIn))
val importing = "import_file_with_syntax_error"
val imported = "file_with_syntax_error"
val act = { importer.importLibraryModule(importing) }
val importing = fixturesDir.resolve("import_file_with_syntax_error.p8")
val imported = fixturesDir.resolve("file_with_syntax_error.p8")
assumeReadableFile(importing)
assumeReadableFile(imported)
val act = { importer.importLibraryModule(importing.nameWithoutExtension) }
assertFailsWith<ParseError> { act() }
try {
act()
} catch (e: ParseError) {
val expectedProvenance = Path.of(libdirs[0], imported + ".p8")
.normalize()
.absolutePathString()
val expectedProvenance = imported.normalize().absolutePathString()
assertEquals(expectedProvenance, e.position.file)
assertEquals(2, e.position.line, "line; should be 1-based")
assertEquals(6, e.position.startCol, "startCol; should be 0-based")

View File

@ -1,8 +1,8 @@
package prog8tests
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.*
import kotlin.test.*
import java.nio.file.Path // TODO: use kotlin.io.path.Path instead
import prog8tests.helpers.*
import kotlin.io.path.*
import prog8.parser.ParseError
@ -13,14 +13,12 @@ import prog8.ast.base.Position
import prog8.ast.statements.*
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class TestProg8Parser {
val workingDir = Path("").absolute() // Note: Path(".") does NOT work..!
val fixturesDir = workingDir.resolve("test/fixtures")
@Test
fun testDirectoriesSanityCheck() {
assertEquals("compilerAst", workingDir.fileName.toString())
assertTrue(fixturesDir.isDirectory(), "sanity check; should be directory: $fixturesDir")
@BeforeAll
fun setUp() {
sanityCheckDirectories("compilerAst")
}
@Test
@ -164,15 +162,14 @@ class TestProg8Parser {
@Test
fun parseModuleShouldNotLookAtImports() {
val imported = "i_do_not_exist"
val pathNoExt = Path.of(imported).absolute()
val pathWithExt = Path.of("${pathNoExt}.p8")
val text = "%import $imported"
assertFalse(pathNoExt.exists(), "sanity check: file should not exist: $pathNoExt")
assertFalse(pathWithExt.exists(), "sanity check: file should not exist: $pathWithExt")
val importedNoExt = fixturesDir.resolve("i_do_not_exist")
val importedWithExt = fixturesDir.resolve("i_do_not_exist.p8")
assumeNotExists(importedNoExt)
assumeNotExists(importedWithExt)
val text = "%import ${importedNoExt.name}"
val module = parseModule(SourceCode.of(text))
assertEquals(1, module.statements.size)
}
@ -186,7 +183,7 @@ class TestProg8Parser {
@Test
fun testParseModuleWithEmptyFile() {
val path = fixturesDir.resolve("empty.p8")
assertTrue(path.isRegularFile(), "sanity check: should be regular file: $path")
assumeReadableFile(path)
val module = parseModule(SourceCode.fromPath(path))
assertEquals(0, module.statements.size)
@ -298,6 +295,7 @@ class TestProg8Parser {
* TODO: this test is testing way too much at once
*/
@Test
@Disabled
fun testInnerNodePositionsForSourceFromString() {
val srcText = """
%target 16, "abc" ; DirectiveArg directly inherits from Node - neither an Expression nor a Statement..?
@ -335,17 +333,4 @@ class TestProg8Parser {
assertPositionOf(whenStmt.choices[2], mpf, 9, 12) // TODO: endCol wrong!
}
@Test
fun testProg8Ast() {
val module = parseModule(SourceCode.of("""
main {
sub start() {
return
}
}
"""))
assertIs<Block>(module.statements.first())
assertEquals("main", (module.statements.first() as Block).name)
}
}

View File

@ -1,28 +1,20 @@
package prog8tests
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.TestInstance
import org.junit.jupiter.api.assertThrows
import org.junit.jupiter.api.*
import kotlin.test.*
import prog8tests.helpers.*
import kotlin.io.path.*
import prog8.parser.SourceCode
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class TestSourceCode {
val workingDir = Path("").absolute() // Note: Path(".") does NOT work..!
val fixturesDir = workingDir.resolve("test/fixtures")
val resourcesDir = workingDir.resolve("res")
val outputDir = workingDir.resolve("build/tmp/test")
@Test
fun sanityCheckDirectories() {
assertEquals("compilerAst", workingDir.fileName.toString())
assertTrue(workingDir.isDirectory(), "sanity check; should be directory: $workingDir")
assertTrue(fixturesDir.isDirectory(), "sanity check; should be directory: $fixturesDir")
assertTrue(resourcesDir.isDirectory(), "sanity check; should be directory: $resourcesDir")
assertTrue(outputDir.isDirectory(), "sanity check; should be directory: $outputDir")
@BeforeAll
fun setUp() {
sanityCheckDirectories("compilerAst")
}
@Test
@ -41,8 +33,7 @@ class TestSourceCode {
fun testFromPathWithNonExistingPath() {
val filename = "i_do_not_exist.p8"
val path = fixturesDir.resolve(filename)
assertFalse(path.exists(), "sanity check: file should not exist: ${path.absolute()}")
assumeNotExists(path)
assertFailsWith<NoSuchFileException> { SourceCode.fromPath(path) }
}
@ -50,9 +41,7 @@ class TestSourceCode {
fun testFromPathWithMissingExtension_p8() {
val pathWithoutExt = fixturesDir.resolve("simple_main")
val pathWithExt = Path(pathWithoutExt.toString() + ".p8")
assertTrue(pathWithExt.isRegularFile(), "sanity check: should be normal file: ${pathWithExt.absolute()}")
assertTrue(pathWithExt.isReadable(), "sanity check: should be readable: ${pathWithExt.absolute()}")
assumeReadableFile(pathWithExt)
assertFailsWith<NoSuchFileException> { SourceCode.fromPath(pathWithoutExt) }
}
@ -108,7 +97,7 @@ class TestSourceCode {
assertEquals("@embedded@$pathString", src.origin)
val expectedSrcText = resourcesDir.resolve(pathString.substringAfter("/")).toFile().readText()
val expectedSrcText = resourcesDir.resolve(pathString.substring(1)).toFile().readText()
val actualSrcText = src.asString()
assertEquals(expectedSrcText, actualSrcText)
}
@ -133,7 +122,7 @@ class TestSourceCode {
assertEquals("@embedded@$pathString", src.origin)
val expectedSrcText = resourcesDir.resolve(pathString.substringAfter("/")).toFile().readText()
val expectedSrcText = resourcesDir.resolve(pathString.substring(1)).toFile().readText()
val actualSrcText = src.asString()
assertEquals(expectedSrcText, actualSrcText)
}
@ -145,7 +134,7 @@ class TestSourceCode {
assertEquals("@embedded@/prog8lib/math.p8", src.origin)
val expectedSrcText = Path( "res", pathString).toFile().readText()
val expectedSrcText = resourcesDir.resolve(pathString.substring(1)).toFile().readText()
val actualSrcText = src.asString()
assertEquals(expectedSrcText, actualSrcText)
assertTrue(src.isFromResources, ".isFromResources")
@ -155,15 +144,15 @@ class TestSourceCode {
@Test
fun testFromResourcesWithNonExistingFile_withLeadingSlash() {
val pathString = "/prog8lib/i_do_not_exist"
val resPath = resourcesDir.resolve(pathString.substringAfter("/"))
assertFalse(resPath.exists(), "sanity check: should not exist: $resPath")
val resPath = resourcesDir.resolve(pathString.substring(1))
assumeNotExists(resPath)
assertThrows<NoSuchFileException> { SourceCode.fromResources(pathString) }
}
@Test
fun testFromResourcesWithNonExistingFile_withoutLeadingSlash() {
val pathString = "prog8lib/i_do_not_exist"
val resPath = resourcesDir.resolve(pathString)
assertFalse(resPath.exists(), "sanity check: should not exist: $resPath")
assumeNotExists(resPath)
assertThrows<NoSuchFileException> { SourceCode.fromResources(pathString) }
}