Verified Commit fd353f40 authored by Konstantin Kopper's avatar Konstantin Kopper
Browse files

Added compiler tests

parent b24e9394
Pipeline #7543 passed with stages
in 6 minutes and 6 seconds
[submodule "lib/pseuco-java-compiler"]
path = lib/pseuco-java-compiler
url = ../pseuco-java-compiler.git
[submodule "src/test/resources/pseuco-tests"]
path = src/test/resources/pseuco-tests
url = ../pseuco-tests.git
package pseuco.javaCompiler
import kotlinx.io.ByteArrayOutputStream
import kotlinx.serialization.CompositeDecoder
import kotlinx.serialization.Decoder
import kotlinx.serialization.KSerializer
import kotlinx.serialization.SerialDescriptor
import kotlinx.serialization.Serializable
import kotlinx.serialization.SerializationException
import kotlinx.serialization.Serializer
import kotlinx.serialization.UnstableDefault
import kotlinx.serialization.internal.SerialClassDescImpl
import kotlinx.serialization.json.Json
import kotlinx.serialization.list
import kotlinx.serialization.serializer
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Assertions.assertIterableEquals
import org.junit.jupiter.api.Assertions.assertTimeoutPreemptively
import org.junit.jupiter.api.Assumptions.assumeTrue
import org.junit.jupiter.api.DynamicTest.dynamicTest
import org.junit.jupiter.api.TestFactory
import org.junit.jupiter.api.condition.DisabledIfEnvironmentVariable
import org.junit.jupiter.api.fail
import pseuco.javaCompiler.runner.PseuCoRunner
import java.io.File
import java.time.Duration
import kotlin.reflect.full.functions
import kotlin.reflect.jvm.isAccessible
@UnstableDefault
@DisabledIfEnvironmentVariable(named = "CI", matches = "true")
class CompilerTests {
private val tests = File(this::class.java.getResource("/pseuco-tests/tests").toURI())
.listFiles { f -> f.extension == "json" }
.map { f ->
Json.parse(CompilerTestConfig.serializer(), f.readText()).let {
CompilerTest(File(f.absolutePath.replace(Regex("json$"), "pseuco")),
"${it.description} (${f.nameWithoutExtension})", it.correctnessProperties)
}
}
@TestFactory
fun compilerTests() = tests.map { test ->
test.correctnessProperties.map { cp ->
dynamicTest(test.description) {
assumeTrue(cp is CorrectnessProperty.DeterministicOutput) { "Correctness property '${cp.type}' is currently unsupported." }
val outStream = ByteArrayOutputStream()
val errStream = ByteArrayOutputStream()
val joinFunction = PseuCoCompilerTask::class.functions.find { it.name == "joinAgents" }!!.apply { isAccessible = true }
PseuCoRunner(test.file, outStream, errStream).apply {
onError { fail(it) }
assertTimeoutPreemptively(Duration.ofSeconds(2)) { run() }
}.also { joinFunction.call(it) }
val output = outStream.toString().lines().filter { it.isNotEmpty() }
when (cp) {
is CorrectnessProperty.DeterministicOutput -> {
assertEquals(cp.output.size, output.size)
assertIterableEquals(cp.output, output)
}
else -> fail { "Unsupported correctness property: '${cp.type}'" }
}
}
}
}.flatten()
private data class CompilerTest(val file: File, val description: String, val correctnessProperties: List<CorrectnessProperty>)
@Serializable
private data class CompilerTestConfig(val description: String, val correctnessProperties: List<CorrectnessProperty>)
@Serializable(with = CorrectnessProperty.Companion::class)
private sealed class CorrectnessProperty(val type: String) {
data class DeterministicOutput(val output: List<String>) : CorrectnessProperty("deterministicOutput")
data class PossibleOutputs(val possibilities: List<String>) : CorrectnessProperty("possibleOutputs")
@Serializer(forClass = CorrectnessProperty::class)
companion object : KSerializer<CorrectnessProperty> {
override val descriptor: SerialDescriptor = object : SerialClassDescImpl("CorrectnessProperty") {
init {
addElement("type")
addElement("output", isOptional = true)
addElement("possibilities", isOptional = true)
}
}
override fun deserialize(decoder: Decoder): CorrectnessProperty {
val structure = decoder.beginStructure(descriptor)
lateinit var type: String
lateinit var list: List<String>
tailrec fun decodeAttributes(): CorrectnessProperty {
when (val i = structure.decodeElementIndex(descriptor)) {
CompositeDecoder.READ_DONE -> {
structure.endStructure(descriptor)
return when (type) {
"deterministicOutput" -> DeterministicOutput(list)
"possibleOutputs" -> PossibleOutputs(list)
else -> throw SerializationException("Cannot deserialize unknown correctness property '$type'.")
}
}
0 -> type = structure.decodeStringElement(descriptor, i)
1, 2 -> list = structure.decodeSerializableElement(descriptor, i, String.serializer().list)
}
return decodeAttributes()
}
return decodeAttributes()
}
}
}
}
Subproject commit 49428dd6e424559c3d12fe6fc4fe7853d43385f7
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment