(7.2) can now test for specific error messages, and specify to omit invoking assembler in tests

This commit is contained in:
Irmen de Jong 2021-10-22 01:25:26 +02:00
parent f4dfa60790
commit 2815a14bb5
7 changed files with 42 additions and 21 deletions

View File

@ -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) {

View File

@ -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 }

View File

@ -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

View File

@ -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

View File

@ -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"}

View File

@ -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()
} }

View File

@ -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)
} }