mirror of
https://github.com/irmen/prog8.git
synced 2025-02-09 07:31:34 +00:00
(7.2) can now test for specific error messages, and specify to omit invoking assembler in tests
This commit is contained in:
parent
f4dfa60790
commit
2815a14bb5
@ -73,11 +73,11 @@ fun compileProgram(filepath: Path,
|
|||||||
slowCodegenWarnings: Boolean,
|
slowCodegenWarnings: Boolean,
|
||||||
compilationTarget: String,
|
compilationTarget: String,
|
||||||
sourceDirs: List<String>,
|
sourceDirs: List<String>,
|
||||||
outputDir: Path): CompilationResult {
|
outputDir: Path,
|
||||||
|
errors: IErrorReporter = ErrorReporter()): CompilationResult {
|
||||||
var programName = ""
|
var programName = ""
|
||||||
lateinit var programAst: Program
|
lateinit var programAst: Program
|
||||||
lateinit var importedFiles: List<Path>
|
lateinit var importedFiles: List<Path>
|
||||||
val errors = ErrorReporter()
|
|
||||||
|
|
||||||
val compTarget =
|
val compTarget =
|
||||||
when(compilationTarget) {
|
when(compilationTarget) {
|
||||||
|
@ -9,6 +9,10 @@ interface IErrorReporter {
|
|||||||
fun warn(msg: String, position: Position)
|
fun warn(msg: String, position: Position)
|
||||||
fun noErrors(): Boolean
|
fun noErrors(): Boolean
|
||||||
fun report()
|
fun report()
|
||||||
|
fun finalizeNumErrors(numErrors: Int, numWarnings: Int) {
|
||||||
|
if(numErrors>0)
|
||||||
|
throw ParsingFailedError("There are $numErrors errors and $numWarnings warnings.")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -49,8 +53,7 @@ internal class ErrorReporter: IErrorReporter {
|
|||||||
System.err.print("\u001b[0m") // reset color
|
System.err.print("\u001b[0m") // reset color
|
||||||
}
|
}
|
||||||
messages.clear()
|
messages.clear()
|
||||||
if(numErrors>0)
|
finalizeNumErrors(numErrors, numWarnings)
|
||||||
throw ParsingFailedError("There are $numErrors errors and $numWarnings warnings.")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun noErrors() = messages.none { it.severity==MessageSeverity.ERROR }
|
override fun noErrors() = messages.none { it.severity==MessageSeverity.ERROR }
|
||||||
|
@ -36,7 +36,7 @@ class TestModuleImporter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun makeImporter(errors: IErrorReporter? = null, searchIn: Iterable<String>) =
|
private fun makeImporter(errors: IErrorReporter? = null, searchIn: Iterable<String>) =
|
||||||
ModuleImporter(program, "blah", errors ?: ErrorReporterForTests(), searchIn.toList())
|
ModuleImporter(program, "blah", errors ?: ErrorReporterForTests(false), searchIn.toList())
|
||||||
|
|
||||||
@Nested
|
@Nested
|
||||||
inner class Constructor {
|
inner class Constructor {
|
||||||
@ -243,7 +243,7 @@ class TestModuleImporter {
|
|||||||
@Test
|
@Test
|
||||||
fun testWithNonExistingName() {
|
fun testWithNonExistingName() {
|
||||||
val searchIn = assumeDirectory("./", workingDir.relativize(fixturesDir))
|
val searchIn = assumeDirectory("./", workingDir.relativize(fixturesDir))
|
||||||
val errors = ErrorReporterForTests()
|
val errors = ErrorReporterForTests(false)
|
||||||
val importer = makeImporter(errors, searchIn.invariantSeparatorsPathString)
|
val importer = makeImporter(errors, searchIn.invariantSeparatorsPathString)
|
||||||
val filenameNoExt = assumeNotExists(fixturesDir, "i_do_not_exist").name
|
val filenameNoExt = assumeNotExists(fixturesDir, "i_do_not_exist").name
|
||||||
val filenameWithExt = assumeNotExists(fixturesDir, "i_do_not_exist.p8").name
|
val filenameWithExt = assumeNotExists(fixturesDir, "i_do_not_exist.p8").name
|
||||||
|
@ -13,10 +13,10 @@ import prog8.compiler.astprocessing.size
|
|||||||
import prog8.compiler.astprocessing.toConstantIntegerRange
|
import prog8.compiler.astprocessing.toConstantIntegerRange
|
||||||
import prog8.compiler.target.C64Target
|
import prog8.compiler.target.C64Target
|
||||||
import prog8.compiler.target.Cx16Target
|
import prog8.compiler.target.Cx16Target
|
||||||
|
import prog8tests.helpers.*
|
||||||
import prog8tests.helpers.assertFailure
|
import prog8tests.helpers.assertFailure
|
||||||
import prog8tests.helpers.assertSuccess
|
import prog8tests.helpers.assertSuccess
|
||||||
import prog8tests.helpers.compileText
|
import prog8tests.helpers.compileText
|
||||||
import prog8tests.helpers.mapCombinations
|
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
|
|
||||||
@ -224,6 +224,7 @@ class TestCompilerOnRanges {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testForLoopWithRange_str_downto_str() {
|
fun testForLoopWithRange_str_downto_str() {
|
||||||
|
val errors = ErrorReporterForTests()
|
||||||
compileText(Cx16Target, true, """
|
compileText(Cx16Target, true, """
|
||||||
main {
|
main {
|
||||||
sub start() {
|
sub start() {
|
||||||
@ -233,8 +234,10 @@ class TestCompilerOnRanges {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
""").assertFailure()
|
""", errors, false).assertFailure()
|
||||||
//TODO("test exact compile error(s)")
|
assertEquals(2, errors.errors.size)
|
||||||
|
assertEquals("range expression from value must be integer", errors.errors[0])
|
||||||
|
assertEquals("range expression to value must be integer", errors.errors[1])
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -7,6 +7,7 @@ import prog8.ast.base.DataType
|
|||||||
import prog8.ast.statements.Block
|
import prog8.ast.statements.Block
|
||||||
import prog8.ast.statements.Subroutine
|
import prog8.ast.statements.Subroutine
|
||||||
import prog8.compiler.target.C64Target
|
import prog8.compiler.target.C64Target
|
||||||
|
import prog8tests.helpers.ErrorReporterForTests
|
||||||
import prog8tests.helpers.assertFailure
|
import prog8tests.helpers.assertFailure
|
||||||
import prog8tests.helpers.assertSuccess
|
import prog8tests.helpers.assertSuccess
|
||||||
import prog8tests.helpers.compileText
|
import prog8tests.helpers.compileText
|
||||||
@ -32,8 +33,11 @@ class TestSubroutines {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
val result = compileText(C64Target, false, text).assertFailure("currently str type in signature is invalid") // TODO should not be invalid
|
val errors = ErrorReporterForTests()
|
||||||
// TODO: check for specific error message(s)
|
compileText(C64Target, false, text, errors, false).assertFailure("currently str type in signature is invalid") // TODO should not be invalid
|
||||||
|
assertEquals(0, errors.warnings.size)
|
||||||
|
// TODO fix extra error "string var must be initialized with a string literal"
|
||||||
|
assertTrue(errors.errors.single().startsWith("Pass-by-reference types (str, array) cannot occur as a parameter type directly."))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -53,8 +57,10 @@ class TestSubroutines {
|
|||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
|
|
||||||
val result = compileText(C64Target, false, text).assertFailure("currently array dt in signature is invalid") // TODO should not be invalid?
|
val errors = ErrorReporterForTests()
|
||||||
// TODO: check for specific error message(s)
|
compileText(C64Target, false, text, errors, false).assertFailure("currently array dt in signature is invalid") // TODO should not be invalid?
|
||||||
|
assertEquals(0, errors.warnings.size)
|
||||||
|
assertTrue(errors.errors.single().startsWith("Pass-by-reference types (str, array) cannot occur as a parameter type directly."))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -82,7 +88,7 @@ class TestSubroutines {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
val result = compileText(C64Target, false, text).assertSuccess()
|
val result = compileText(C64Target, false, text, writeAssembly = false).assertSuccess()
|
||||||
val module = result.programAst.toplevelModule
|
val module = result.programAst.toplevelModule
|
||||||
val mainBlock = module.statements.single() as Block
|
val mainBlock = module.statements.single() as Block
|
||||||
val asmfunc = mainBlock.statements.filterIsInstance<Subroutine>().single { it.name=="asmfunc"}
|
val asmfunc = mainBlock.statements.filterIsInstance<Subroutine>().single { it.name=="asmfunc"}
|
||||||
@ -121,7 +127,7 @@ class TestSubroutines {
|
|||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
|
|
||||||
val result = compileText(C64Target, false, text).assertSuccess()
|
val result = compileText(C64Target, false, text, writeAssembly = false).assertSuccess()
|
||||||
val module = result.programAst.toplevelModule
|
val module = result.programAst.toplevelModule
|
||||||
val mainBlock = module.statements.single() as Block
|
val mainBlock = module.statements.single() as Block
|
||||||
val asmfunc = mainBlock.statements.filterIsInstance<Subroutine>().single { it.name=="asmfunc"}
|
val asmfunc = mainBlock.statements.filterIsInstance<Subroutine>().single { it.name=="asmfunc"}
|
||||||
|
@ -3,7 +3,7 @@ package prog8tests.helpers
|
|||||||
import prog8.ast.base.Position
|
import prog8.ast.base.Position
|
||||||
import prog8.compiler.IErrorReporter
|
import prog8.compiler.IErrorReporter
|
||||||
|
|
||||||
class ErrorReporterForTests: IErrorReporter {
|
class ErrorReporterForTests(private val throwExceptionAtReportIfErrors: Boolean=true): IErrorReporter {
|
||||||
|
|
||||||
|
|
||||||
val errors = mutableListOf<String>()
|
val errors = mutableListOf<String>()
|
||||||
@ -20,6 +20,8 @@ class ErrorReporterForTests: IErrorReporter {
|
|||||||
override fun noErrors(): Boolean = errors.isEmpty()
|
override fun noErrors(): Boolean = errors.isEmpty()
|
||||||
|
|
||||||
override fun report() {
|
override fun report() {
|
||||||
|
if(throwExceptionAtReportIfErrors)
|
||||||
|
finalizeNumErrors(errors.size, warnings.size)
|
||||||
errors.clear()
|
errors.clear()
|
||||||
warnings.clear()
|
warnings.clear()
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
package prog8tests.helpers
|
package prog8tests.helpers
|
||||||
|
|
||||||
import prog8.compiler.CompilationResult
|
import prog8.compiler.CompilationResult
|
||||||
|
import prog8.compiler.ErrorReporter
|
||||||
|
import prog8.compiler.IErrorReporter
|
||||||
import prog8.compiler.compileProgram
|
import prog8.compiler.compileProgram
|
||||||
import prog8.compiler.target.ICompilationTarget
|
import prog8.compiler.target.ICompilationTarget
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
@ -28,18 +30,21 @@ internal fun compileFile(
|
|||||||
optimize: Boolean,
|
optimize: Boolean,
|
||||||
fileDir: Path,
|
fileDir: Path,
|
||||||
fileName: String,
|
fileName: String,
|
||||||
outputDir: Path = prog8tests.helpers.outputDir
|
outputDir: Path = prog8tests.helpers.outputDir,
|
||||||
|
errors: IErrorReporter? = null,
|
||||||
|
writeAssembly: Boolean = true
|
||||||
) : CompilationResult {
|
) : CompilationResult {
|
||||||
val filepath = fileDir.resolve(fileName)
|
val filepath = fileDir.resolve(fileName)
|
||||||
assumeReadableFile(filepath)
|
assumeReadableFile(filepath)
|
||||||
return compileProgram(
|
return compileProgram(
|
||||||
filepath,
|
filepath,
|
||||||
optimize,
|
optimize,
|
||||||
writeAssembly = true,
|
writeAssembly = writeAssembly,
|
||||||
slowCodegenWarnings = false,
|
slowCodegenWarnings = false,
|
||||||
platform.name,
|
platform.name,
|
||||||
sourceDirs = listOf(),
|
sourceDirs = listOf(),
|
||||||
outputDir
|
outputDir,
|
||||||
|
errors = errors ?: ErrorReporter()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -51,10 +56,12 @@ internal fun compileFile(
|
|||||||
internal fun compileText(
|
internal fun compileText(
|
||||||
platform: ICompilationTarget,
|
platform: ICompilationTarget,
|
||||||
optimize: Boolean,
|
optimize: Boolean,
|
||||||
sourceText: String
|
sourceText: String,
|
||||||
|
errors: IErrorReporter? = null,
|
||||||
|
writeAssembly: Boolean = true
|
||||||
) : CompilationResult {
|
) : CompilationResult {
|
||||||
val filePath = outputDir.resolve("on_the_fly_test_" + sourceText.hashCode().toUInt().toString(16) + ".p8")
|
val filePath = outputDir.resolve("on_the_fly_test_" + sourceText.hashCode().toUInt().toString(16) + ".p8")
|
||||||
// we don't assumeNotExists(filePath) - should be ok to just overwrite it
|
// we don't assumeNotExists(filePath) - should be ok to just overwrite it
|
||||||
filePath.toFile().writeText(sourceText)
|
filePath.toFile().writeText(sourceText)
|
||||||
return compileFile(platform, optimize, filePath.parent, filePath.name)
|
return compileFile(platform, optimize, filePath.parent, filePath.name, errors=errors, writeAssembly=writeAssembly)
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user