mirror of
https://github.com/irmen/prog8.git
synced 2024-09-07 19:54:26 +00:00
Merge pull request #49 from meisl/master
A few automatic tests with examples, *of the whole process*...
This commit is contained in:
commit
2cb1560bbd
138
compiler/test/TestCompilerOnCharLit.kt
Normal file
138
compiler/test/TestCompilerOnCharLit.kt
Normal file
@ -0,0 +1,138 @@
|
|||||||
|
package prog8tests
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test
|
||||||
|
import org.junit.jupiter.api.TestInstance
|
||||||
|
import kotlin.test.*
|
||||||
|
import kotlin.io.path.*
|
||||||
|
|
||||||
|
import prog8.ast.IFunctionCall
|
||||||
|
import prog8.ast.base.DataType
|
||||||
|
import prog8.ast.base.VarDeclType
|
||||||
|
import prog8.ast.expressions.IdentifierReference
|
||||||
|
import prog8.ast.expressions.NumericLiteralValue
|
||||||
|
import prog8.compiler.target.Cx16Target
|
||||||
|
|
||||||
|
import prog8.compiler.compileProgram
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ATTENTION: this is just kludge!
|
||||||
|
* They are not really unit tests, but rather tests of the whole process,
|
||||||
|
* from source file loading all the way through to running 64tass.
|
||||||
|
* What's more: in case of failure (to compile and assemble) - which is when tests should help you -
|
||||||
|
* these tests will actually be ignored (ie. NOT fail),
|
||||||
|
* because in the code there are calls to Process.exit, making it essentially untestable.
|
||||||
|
*/
|
||||||
|
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
||||||
|
class TestCompilerOnCharLit {
|
||||||
|
val workingDir = Path("").absolute() // Note: Path(".") does NOT work..!
|
||||||
|
val fixturesDir = workingDir.resolve("test/fixtures")
|
||||||
|
val outputDir = workingDir.resolve("build/tmp/test")
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testDirectoriesSanityCheck() {
|
||||||
|
assertEquals("compiler", workingDir.fileName.toString())
|
||||||
|
assertTrue(fixturesDir.isDirectory(), "sanity check; should be directory: $fixturesDir")
|
||||||
|
assertTrue(outputDir.isDirectory(), "sanity check; should be directory: $outputDir")
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testCharLitAsRomsubArg() {
|
||||||
|
val filepath = fixturesDir.resolve("charLitAsRomsubArg.p8")
|
||||||
|
val compilationTarget = Cx16Target
|
||||||
|
val result = compileProgram(
|
||||||
|
filepath,
|
||||||
|
optimize = false,
|
||||||
|
writeAssembly = true,
|
||||||
|
slowCodegenWarnings = false,
|
||||||
|
compilationTarget.name,
|
||||||
|
libdirs = listOf(),
|
||||||
|
outputDir
|
||||||
|
)
|
||||||
|
assertTrue(result.success, "compilation successful")
|
||||||
|
|
||||||
|
val program = result.programAst
|
||||||
|
val startSub = program.entrypoint()
|
||||||
|
val funCall = startSub.statements.filterIsInstance<IFunctionCall>()[0]
|
||||||
|
|
||||||
|
assertIs<NumericLiteralValue>(funCall.args[0],
|
||||||
|
"char literal should have been replaced by ubyte literal")
|
||||||
|
val arg = funCall.args[0] as NumericLiteralValue
|
||||||
|
assertEquals(DataType.UBYTE, arg.type)
|
||||||
|
assertEquals(compilationTarget.encodeString("\n", false)[0], arg.number)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testCharVarAsRomsubArg() {
|
||||||
|
val filepath = fixturesDir.resolve("charVarAsRomsubArg.p8")
|
||||||
|
val compilationTarget = Cx16Target
|
||||||
|
val result = compileProgram(
|
||||||
|
filepath,
|
||||||
|
optimize = false,
|
||||||
|
writeAssembly = true,
|
||||||
|
slowCodegenWarnings = false,
|
||||||
|
compilationTarget.name,
|
||||||
|
libdirs = listOf(),
|
||||||
|
outputDir
|
||||||
|
)
|
||||||
|
assertTrue(result.success, "compilation successful")
|
||||||
|
val program = result.programAst
|
||||||
|
val startSub = program.entrypoint()
|
||||||
|
val funCall = startSub.statements.filterIsInstance<IFunctionCall>()[0]
|
||||||
|
|
||||||
|
assertIs<IdentifierReference>(funCall.args[0])
|
||||||
|
val arg = funCall.args[0] as IdentifierReference
|
||||||
|
val decl = arg.targetVarDecl(program)!!
|
||||||
|
assertEquals(VarDeclType.VAR, decl.type)
|
||||||
|
assertEquals(DataType.UBYTE, decl.datatype)
|
||||||
|
|
||||||
|
// TODO: assertIs<CharLiteral>(decl.value,
|
||||||
|
// "char literals should be kept until code gen")
|
||||||
|
// val initializerValue = decl.value as CharLiteral
|
||||||
|
// assertEquals('\n', (initializerValue as CharLiteral).value)
|
||||||
|
|
||||||
|
assertIs<NumericLiteralValue>(decl.value,
|
||||||
|
"char literal should have been replaced by ubyte literal")
|
||||||
|
val initializerValue = decl.value as NumericLiteralValue
|
||||||
|
assertEquals(DataType.UBYTE, initializerValue.type)
|
||||||
|
assertEquals(compilationTarget.encodeString("\n", false)[0], initializerValue.number)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testCharConstAsRomsubArg() {
|
||||||
|
val filepath = fixturesDir.resolve("charConstAsRomsubArg.p8")
|
||||||
|
val compilationTarget = Cx16Target
|
||||||
|
val result = compileProgram(
|
||||||
|
filepath,
|
||||||
|
optimize = false,
|
||||||
|
writeAssembly = true,
|
||||||
|
slowCodegenWarnings = false,
|
||||||
|
compilationTarget.name,
|
||||||
|
libdirs = listOf(),
|
||||||
|
outputDir
|
||||||
|
)
|
||||||
|
assertTrue(result.success, "compilation successful")
|
||||||
|
val program = result.programAst
|
||||||
|
val startSub = program.entrypoint()
|
||||||
|
val funCall = startSub.statements.filterIsInstance<IFunctionCall>()[0]
|
||||||
|
|
||||||
|
// Now, both is ok for the arg: a) still the IdRef or b) replaced by numeric literal
|
||||||
|
when (val arg = funCall.args[0]) {
|
||||||
|
is IdentifierReference -> {
|
||||||
|
val decl = arg.targetVarDecl(program)!!
|
||||||
|
assertEquals(VarDeclType.CONST, decl.type)
|
||||||
|
assertEquals(DataType.UBYTE, decl.datatype)
|
||||||
|
assertEquals(
|
||||||
|
compilationTarget.encodeString("\n", false)[0],
|
||||||
|
(decl.value as NumericLiteralValue).number)
|
||||||
|
}
|
||||||
|
is NumericLiteralValue -> {
|
||||||
|
assertEquals(
|
||||||
|
compilationTarget.encodeString("\n", false)[0],
|
||||||
|
arg.number)
|
||||||
|
}
|
||||||
|
else -> assertIs<IdentifierReference>(funCall.args[0]) // make test fail
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
78
compiler/test/TestCompilerOnExamples.kt
Normal file
78
compiler/test/TestCompilerOnExamples.kt
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
package prog8tests
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test
|
||||||
|
import org.junit.jupiter.api.TestInstance
|
||||||
|
import kotlin.test.*
|
||||||
|
import kotlin.io.path.*
|
||||||
|
|
||||||
|
import prog8.compiler.target.Cx16Target
|
||||||
|
import prog8.compiler.compileProgram
|
||||||
|
import prog8.compiler.target.ICompilationTarget
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ATTENTION: this is just kludge!
|
||||||
|
* They are not really unit tests, but rather tests of the whole process,
|
||||||
|
* from source file loading all the way through to running 64tass.
|
||||||
|
* What's more: in case of failure (to compile and assemble) - which is when tests should help you -
|
||||||
|
* these tests will actually be ignored (ie. NOT fail),
|
||||||
|
* because in the code there are calls to Process.exit, making it essentially untestable.
|
||||||
|
*/
|
||||||
|
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
||||||
|
class TestCompilerOnExamples {
|
||||||
|
val workingDir = Path("").absolute() // Note: Path(".") does NOT work..!
|
||||||
|
val examplesDir = workingDir.resolve("../examples")
|
||||||
|
val outputDir = workingDir.resolve("build/tmp/test")
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testDirectoriesSanityCheck() {
|
||||||
|
assertEquals("compiler", workingDir.fileName.toString())
|
||||||
|
assertTrue(examplesDir.isDirectory(), "sanity check; should be directory: $examplesDir")
|
||||||
|
assertTrue(outputDir.isDirectory(), "sanity check; should be directory: $outputDir")
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: make assembly stage testable - in case of failure (eg of 64tass) it Process.exit s
|
||||||
|
|
||||||
|
fun testExample(nameWithoutExt: String, platform: ICompilationTarget, optimize: Boolean) {
|
||||||
|
val filepath = examplesDir.resolve("$nameWithoutExt.p8")
|
||||||
|
val result = compileProgram(
|
||||||
|
filepath,
|
||||||
|
optimize,
|
||||||
|
writeAssembly = true,
|
||||||
|
slowCodegenWarnings = false,
|
||||||
|
compilationTarget = platform.name,
|
||||||
|
libdirs = listOf(),
|
||||||
|
outputDir
|
||||||
|
)
|
||||||
|
assertTrue(result.success, "${platform.name}, optimize=$optimize: \"$filepath\"")
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun test_cxLogo_noopt() {
|
||||||
|
testExample("cxlogo", Cx16Target, false)
|
||||||
|
}
|
||||||
|
@Test
|
||||||
|
fun test_cxLogo_opt() {
|
||||||
|
testExample("cxlogo", Cx16Target, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun test_swirl_noopt() {
|
||||||
|
testExample("swirl", Cx16Target, false)
|
||||||
|
}
|
||||||
|
@Test
|
||||||
|
fun test_swirl_opt() {
|
||||||
|
testExample("swirl", Cx16Target, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun test_animals_noopt() {
|
||||||
|
testExample("animals", Cx16Target, false)
|
||||||
|
}
|
||||||
|
@Test
|
||||||
|
fun test_animals_opt() {
|
||||||
|
testExample("animals", Cx16Target, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
7
compiler/test/fixtures/charConstAsRomsubArg.p8
vendored
Normal file
7
compiler/test/fixtures/charConstAsRomsubArg.p8
vendored
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
main {
|
||||||
|
romsub $FFD2 = chrout(ubyte ch @ A)
|
||||||
|
sub start() {
|
||||||
|
const ubyte ch = '\n'
|
||||||
|
chrout(ch)
|
||||||
|
}
|
||||||
|
}
|
6
compiler/test/fixtures/charLitAsRomsubArg.p8
vendored
Normal file
6
compiler/test/fixtures/charLitAsRomsubArg.p8
vendored
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
main {
|
||||||
|
romsub $FFD2 = chrout(ubyte ch @ A)
|
||||||
|
sub start() {
|
||||||
|
chrout('\n')
|
||||||
|
}
|
||||||
|
}
|
7
compiler/test/fixtures/charVarAsRomsubArg.p8
vendored
Normal file
7
compiler/test/fixtures/charVarAsRomsubArg.p8
vendored
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
main {
|
||||||
|
romsub $FFD2 = chrout(ubyte ch @ A)
|
||||||
|
sub start() {
|
||||||
|
ubyte ch = '\n'
|
||||||
|
chrout(ch)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user