improve data driven unit tests to use kotest withData()

This commit is contained in:
Irmen de Jong 2024-09-08 16:03:57 +02:00
parent c5b7edad82
commit edc5a5a94f
35 changed files with 115 additions and 123 deletions

View File

@ -0,0 +1,23 @@
<component name="libraryTable">
<library name="io.kotest.framework.datatest" type="repository">
<properties maven-id="io.kotest:kotest-framework-datatest:5.9.1" />
<CLASSES>
<root url="jar://$MAVEN_REPOSITORY$/io/kotest/kotest-framework-datatest/5.9.1/kotest-framework-datatest-5.9.1.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/io/kotest/kotest-framework-datatest-jvm/5.9.1/kotest-framework-datatest-jvm-5.9.1.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-stdlib/1.9.23/kotlin-stdlib-1.9.23.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/annotations/13.0/annotations-13.0.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/kotlinx/kotlinx-coroutines-core-jvm/1.8.0/kotlinx-coroutines-core-jvm-1.8.0.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/io/kotest/kotest-common-jvm/5.9.1/kotest-common-jvm-5.9.1.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-reflect/1.9.23/kotlin-reflect-1.9.23.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/io/kotest/kotest-framework-api-jvm/5.9.1/kotest-framework-api-jvm-5.9.1.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/io/kotest/kotest-assertions-shared-jvm/5.9.1/kotest-assertions-shared-jvm-5.9.1.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/io/kotest/kotest-assertions-api-jvm/5.9.1/kotest-assertions-api-jvm-5.9.1.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/kotlinx/kotlinx-coroutines-jdk8/1.8.0/kotlinx-coroutines-jdk8-1.8.0.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/io/github/java-diff-utils/java-diff-utils/4.12/java-diff-utils-4.12.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/opentest4j/opentest4j/1.3.0/opentest4j-1.3.0.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/kotlinx/kotlinx-coroutines-test-jvm/1.8.0/kotlinx-coroutines-test-jvm-1.8.0.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@ -28,6 +28,7 @@ dependencies {
implementation "com.michael-bull.kotlin-result:kotlin-result-jvm:2.0.0" implementation "com.michael-bull.kotlin-result:kotlin-result-jvm:2.0.0"
testImplementation 'io.kotest:kotest-runner-junit5-jvm:5.9.1' testImplementation 'io.kotest:kotest-runner-junit5-jvm:5.9.1'
testImplementation 'io.kotest:kotest-framework-datatest:5.9.1'
testImplementation 'org.junit.jupiter:junit-jupiter:5.9.2' testImplementation 'org.junit.jupiter:junit-jupiter:5.9.2'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher' testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
} }

View File

@ -14,5 +14,6 @@
<orderEntry type="library" name="michael.bull.kotlin.result.jvm" level="project" /> <orderEntry type="library" name="michael.bull.kotlin.result.jvm" level="project" />
<orderEntry type="library" name="io.kotest.assertions.core.jvm" level="project" /> <orderEntry type="library" name="io.kotest.assertions.core.jvm" level="project" />
<orderEntry type="library" name="io.kotest.runner.junit5.jvm" level="project" /> <orderEntry type="library" name="io.kotest.runner.junit5.jvm" level="project" />
<orderEntry type="library" name="io.kotest.framework.datatest" level="project" />
</component> </component>
</module> </module>

View File

@ -31,6 +31,7 @@ dependencies {
testImplementation 'io.kotest:kotest-runner-junit5-jvm:5.9.1' testImplementation 'io.kotest:kotest-runner-junit5-jvm:5.9.1'
testImplementation 'org.junit.jupiter:junit-jupiter:5.9.2' testImplementation 'org.junit.jupiter:junit-jupiter:5.9.2'
testImplementation 'io.kotest:kotest-framework-datatest:5.9.1'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher' testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
} }

View File

@ -14,6 +14,7 @@
<orderEntry type="module" module-name="intermediate" /> <orderEntry type="module" module-name="intermediate" />
<orderEntry type="library" name="io.kotest.assertions.core.jvm" level="project" /> <orderEntry type="library" name="io.kotest.assertions.core.jvm" level="project" />
<orderEntry type="library" name="io.kotest.runner.junit5.jvm" level="project" /> <orderEntry type="library" name="io.kotest.runner.junit5.jvm" level="project" />
<orderEntry type="library" name="io.kotest.framework.datatest" level="project" />
<orderEntry type="library" name="michael.bull.kotlin.result.jvm" level="project" /> <orderEntry type="library" name="michael.bull.kotlin.result.jvm" level="project" />
</component> </component>
</module> </module>

View File

@ -1,4 +1,4 @@
package prog8tests package prog8tests.compiler
import com.github.michaelbull.result.getErrorOrElse import com.github.michaelbull.result.getErrorOrElse
import com.github.michaelbull.result.getOrElse import com.github.michaelbull.result.getOrElse

View File

@ -1,4 +1,4 @@
package prog8tests package prog8tests.compiler
import io.kotest.core.config.AbstractProjectConfig import io.kotest.core.config.AbstractProjectConfig
import io.kotest.core.spec.SpecExecutionOrder import io.kotest.core.spec.SpecExecutionOrder

View File

@ -1,4 +1,4 @@
package prog8tests package prog8tests.compiler
import io.kotest.core.spec.style.FunSpec import io.kotest.core.spec.style.FunSpec
import io.kotest.matchers.shouldBe import io.kotest.matchers.shouldBe

View File

@ -1,4 +1,4 @@
package prog8tests package prog8tests.compiler
import io.kotest.assertions.withClue import io.kotest.assertions.withClue
import io.kotest.core.spec.style.FunSpec import io.kotest.core.spec.style.FunSpec

View File

@ -1,4 +1,4 @@
package prog8tests package prog8tests.compiler
import io.kotest.assertions.fail import io.kotest.assertions.fail
import io.kotest.assertions.withClue import io.kotest.assertions.withClue

View File

@ -1,6 +1,7 @@
package prog8tests package prog8tests.compiler
import io.kotest.core.spec.style.FunSpec import io.kotest.core.spec.style.FunSpec
import io.kotest.datatest.withData
import io.kotest.matchers.shouldNotBe import io.kotest.matchers.shouldNotBe
import prog8.code.core.ICompilationTarget import prog8.code.core.ICompilationTarget
import prog8.code.target.* import prog8.code.target.*
@ -11,7 +12,6 @@ import prog8tests.helpers.*
import java.nio.file.Path import java.nio.file.Path
import kotlin.io.path.absolute import kotlin.io.path.absolute
import kotlin.io.path.exists import kotlin.io.path.exists
import kotlin.io.path.readText
/** /**
@ -89,13 +89,14 @@ class TestCompilerOnExamplesC64: FunSpec({
listOf(false, true) listOf(false, true)
) )
onlyC64.forEach { val target = C64Target()
val (source, optimize) = it withData(
val target = C64Target() nameFn = { it.second.first },
val (displayName, filepath) = prepareTestFiles(source, optimize, target) onlyC64.map { it to prepareTestFiles(it.first, it.second, target) }
test(displayName) { ) { (params, prep) ->
compileTheThing(filepath, optimize, target) shouldNotBe null val filepath = prep.second
} val optimize = params.second
compileTheThing(filepath, optimize, target) shouldNotBe null
} }
}) })
@ -145,13 +146,14 @@ class TestCompilerOnExamplesCx16: FunSpec({
listOf(false, true) listOf(false, true)
) )
onlyCx16.forEach { val target = Cx16Target()
val (source, optimize) = it withData(
val target = Cx16Target() nameFn = { it.second.first },
val (displayName, filepath) = prepareTestFiles(source, optimize, target) onlyCx16.map { it to prepareTestFiles(it.first, it.second, target) }
test(displayName) { ) { (params, prep) ->
compileTheThing(filepath, optimize, target) shouldNotBe null val filepath = prep.second
} val optimize = params.second
compileTheThing(filepath, optimize, target) shouldNotBe null
} }
}) })
@ -181,40 +183,39 @@ class TestCompilerOnExamplesBothC64andCx16: FunSpec({
"tehtriz", "tehtriz",
"textelite", "textelite",
), ),
listOf(false, true) listOf(false, true),
listOf(C64Target(), Cx16Target())
) )
bothCx16AndC64.forEach { withData(
val (source, optimize) = it nameFn = { it.third.first },
val c64target = C64Target() bothCx16AndC64.map { Triple(it.second, it.third, prepareTestFiles(it.first, it.second, it.third)) }
val cx16target = Cx16Target() ) { params ->
val (displayNameC64, filepathC64) = prepareTestFiles(source, optimize, c64target) val filepath = params.third.second
val (displayNameCx16, filepathCx16) = prepareTestFiles(source, optimize, cx16target) val optimize = params.first
test(displayNameC64) { compileTheThing(filepath, optimize, params.second) shouldNotBe null
compileTheThing(filepathC64, optimize, c64target) shouldNotBe null
}
test(displayNameCx16) {
compileTheThing(filepathCx16, optimize, cx16target) shouldNotBe null
}
} }
}) })
class TestCompilerOnExamplesVirtual: FunSpec({ class TestCompilerOnExamplesVirtual: FunSpec({
val onlyVirtual = listOf( val onlyVirtual = cartesianProduct(
listOf(
"bouncegfx", "bouncegfx",
"bsieve", "bsieve",
"pixelshader", "pixelshader",
"sincos" "sincos"
) ),
listOf(false, true)
)
onlyVirtual.forEach { val target = VMTarget()
val target = VMTarget() withData(
val (displayName, filepath) = prepareTestFiles(it, false, target) nameFn = { it.second.first },
test(displayName) { onlyVirtual.map { it to prepareTestFiles(it.first, it.second, target) }
val src = filepath.readText() ) { (params, prep) ->
compileText(target, false, src, writeAssembly = true) shouldNotBe null val filepath = prep.second
compileText(target, true, src, writeAssembly = true) shouldNotBe null val optimize = params.second
} compileTheThing(filepath, optimize, target) shouldNotBe null
} }
}) })

View File

@ -1,4 +1,4 @@
package prog8tests package prog8tests.compiler
import io.kotest.assertions.withClue import io.kotest.assertions.withClue
import io.kotest.core.spec.style.FunSpec import io.kotest.core.spec.style.FunSpec

View File

@ -1,7 +1,8 @@
package prog8tests package prog8tests.compiler
import io.kotest.assertions.withClue import io.kotest.assertions.withClue
import io.kotest.core.spec.style.FunSpec import io.kotest.core.spec.style.FunSpec
import io.kotest.datatest.withData
import io.kotest.matchers.shouldBe import io.kotest.matchers.shouldBe
import io.kotest.matchers.shouldNotBe import io.kotest.matchers.shouldNotBe
import io.kotest.matchers.string.shouldContain import io.kotest.matchers.string.shouldContain
@ -93,26 +94,26 @@ class TestCompilerOnRanges: FunSpec({
} }
context("floatArrayInitializerWithRange") { context("floatArrayInitializerWithRange") {
val combos = cartesianProduct( withData(
listOf("", "42", "41"), // sizeInDecl nameFn = {
listOf("%import floats", ""), // optEnableFloats when (it.first) {
listOf(Cx16Target(), C64Target()), // platform
listOf(false, true) // optimize
)
combos.forEach {
val (sizeInDecl, optEnableFloats, platform, optimize) = it
val displayName =
when (sizeInDecl) {
"" -> "no" "" -> "no"
"42" -> "correct" "42" -> "correct"
else -> "wrong" else -> "wrong"
} + " array size given" + } + " array size given" +
", " + (if (optEnableFloats == "") "without" else "with") + " %option enable_floats" + ", " + (if (it.second == "") "without" else "with") + " %option enable_floats" +
", ${platform.name}, optimize: $optimize" ", ${it.third.name}, optimize: ${it.fourth}"
},
cartesianProduct(
listOf("", "42", "41"), // sizeInDecl
listOf("%import floats", ""), // optEnableFloats
listOf(Cx16Target(), C64Target()), // platform
listOf(false, true) // optimize
)
) { seq ->
val (sizeInDecl, optEnableFloats, platform, optimize) = seq
test(displayName) { val result = compileText(platform, optimize, """
val result = compileText(platform, optimize, """
$optEnableFloats $optEnableFloats
main { main {
sub start() { sub start() {
@ -121,12 +122,10 @@ class TestCompilerOnRanges: FunSpec({
} }
} }
""") """)
if (optEnableFloats != "" && (sizeInDecl=="" || sizeInDecl=="42")) if (optEnableFloats != "" && (sizeInDecl=="" || sizeInDecl=="42"))
result shouldNotBe null result shouldNotBe null
else else
result shouldBe null result shouldBe null
}
} }
} }

View File

@ -1,4 +1,4 @@
package prog8tests package prog8tests.compiler
import io.kotest.core.spec.style.FunSpec import io.kotest.core.spec.style.FunSpec
import io.kotest.matchers.shouldNotBe import io.kotest.matchers.shouldNotBe

View File

@ -1,4 +1,4 @@
package prog8tests package prog8tests.compiler
import com.github.michaelbull.result.expectError import com.github.michaelbull.result.expectError
import com.github.michaelbull.result.getOrThrow import com.github.michaelbull.result.getOrThrow

View File

@ -1,4 +1,4 @@
package prog8tests package prog8tests.compiler
import io.kotest.assertions.withClue import io.kotest.assertions.withClue
import io.kotest.core.spec.style.FunSpec import io.kotest.core.spec.style.FunSpec

View File

@ -1,4 +1,4 @@
package prog8tests package prog8tests.compiler
import io.kotest.core.spec.style.FunSpec import io.kotest.core.spec.style.FunSpec
import prog8.code.target.VMTarget import prog8.code.target.VMTarget

View File

@ -1,4 +1,4 @@
package prog8tests package prog8tests.compiler
import io.kotest.assertions.throwables.shouldThrow import io.kotest.assertions.throwables.shouldThrow
import io.kotest.core.spec.style.FunSpec import io.kotest.core.spec.style.FunSpec

View File

@ -1,4 +1,4 @@
package prog8tests package prog8tests.compiler
import io.kotest.assertions.throwables.shouldThrow import io.kotest.assertions.throwables.shouldThrow
import io.kotest.core.spec.style.FunSpec import io.kotest.core.spec.style.FunSpec

View File

@ -1,4 +1,4 @@
package prog8tests package prog8tests.compiler
import io.kotest.assertions.throwables.shouldThrow import io.kotest.assertions.throwables.shouldThrow
import io.kotest.core.spec.style.FunSpec import io.kotest.core.spec.style.FunSpec

View File

@ -1,4 +1,4 @@
package prog8tests package prog8tests.compiler
import io.kotest.assertions.withClue import io.kotest.assertions.withClue
import io.kotest.core.spec.style.FunSpec import io.kotest.core.spec.style.FunSpec

View File

@ -1,4 +1,4 @@
package prog8tests package prog8tests.compiler
import io.kotest.assertions.throwables.shouldThrow import io.kotest.assertions.throwables.shouldThrow
import io.kotest.core.spec.style.FunSpec import io.kotest.core.spec.style.FunSpec

View File

@ -1,4 +1,4 @@
package prog8tests package prog8tests.compiler
import io.kotest.assertions.withClue import io.kotest.assertions.withClue
import io.kotest.core.spec.style.FunSpec import io.kotest.core.spec.style.FunSpec

View File

@ -1,4 +1,4 @@
package prog8tests package prog8tests.compiler
import com.github.michaelbull.result.Ok import com.github.michaelbull.result.Ok
import com.github.michaelbull.result.expectError import com.github.michaelbull.result.expectError

View File

@ -1,4 +1,4 @@
package prog8tests package prog8tests.compiler
import io.kotest.assertions.withClue import io.kotest.assertions.withClue
import io.kotest.core.spec.style.FunSpec import io.kotest.core.spec.style.FunSpec

View File

@ -1,4 +1,4 @@
package prog8tests package prog8tests.compiler
import io.kotest.assertions.fail import io.kotest.assertions.fail
import io.kotest.core.spec.style.FunSpec import io.kotest.core.spec.style.FunSpec

View File

@ -1,4 +1,4 @@
package prog8tests package prog8tests.compiler
import io.kotest.core.spec.style.FunSpec import io.kotest.core.spec.style.FunSpec
import io.kotest.matchers.ints.shouldBeGreaterThan import io.kotest.matchers.ints.shouldBeGreaterThan

View File

@ -1,4 +1,4 @@
package prog8tests package prog8tests.compiler
import com.github.michaelbull.result.expectError import com.github.michaelbull.result.expectError
import com.github.michaelbull.result.getOrElse import com.github.michaelbull.result.getOrElse

View File

@ -29,38 +29,3 @@ fun <T, U, V, W> cartesianProduct(
yield(Product(a, b, c, d)) yield(Product(a, b, c, d))
} }
} }
fun <A, B, R> mapCombinations(dim1: Iterable<A>, dim2: Iterable<B>, combine2: (A, B) -> R) =
sequence {
for (a in dim1)
for (b in dim2)
yield(combine2(a, b))
}.toList()
fun <A, B, C, R> mapCombinations(
dim1: Iterable<A>,
dim2: Iterable<B>,
dim3: Iterable<C>,
combine3: (A, B, C) -> R
) =
sequence {
for (a in dim1)
for (b in dim2)
for (c in dim3)
yield(combine3(a, b, c))
}.toList()
fun <A, B, C, D, R> mapCombinations(
dim1: Iterable<A>,
dim2: Iterable<B>,
dim3: Iterable<C>,
dim4: Iterable<D>,
combine4: (A, B, C, D) -> R
) =
sequence {
for (a in dim1)
for (b in dim2)
for (c in dim3)
for (d in dim4)
yield(combine4(a, b, c, d))
}.toList()

View File

@ -1,4 +1,4 @@
package prog8tests package prog8tests.compiler
import io.kotest.assertions.throwables.shouldThrow import io.kotest.assertions.throwables.shouldThrow
import io.kotest.assertions.withClue import io.kotest.assertions.withClue

View File

@ -1,10 +1,6 @@
TODO TODO
==== ====
convert example tests that loop over arrays, to data driven withData()
move those tests to a new separated module in the project so they're not always ran as part of compiler:test
Improve register load order in subroutine call args assignments: Improve register load order in subroutine call args assignments:
in certain situations, the "wrong" order of evaluation of function call arguments is done which results in certain situations, the "wrong" order of evaluation of function call arguments is done which results
in overwriting registers that already got their value, which requires a lot of stack juggling (especially on plain 6502 cpu!) in overwriting registers that already got their value, which requires a lot of stack juggling (especially on plain 6502 cpu!)

View File

@ -26,6 +26,7 @@ dependencies {
implementation project(':codeCore') implementation project(':codeCore')
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8" implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8"
testImplementation 'io.kotest:kotest-runner-junit5-jvm:5.9.1' testImplementation 'io.kotest:kotest-runner-junit5-jvm:5.9.1'
testImplementation 'io.kotest:kotest-framework-datatest:5.9.1'
testImplementation 'org.junit.jupiter:junit-jupiter:5.9.2' testImplementation 'org.junit.jupiter:junit-jupiter:5.9.2'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher' testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
} }

View File

@ -13,5 +13,6 @@
<orderEntry type="module" module-name="codeCore" /> <orderEntry type="module" module-name="codeCore" />
<orderEntry type="library" name="io.kotest.assertions.core.jvm" level="project" /> <orderEntry type="library" name="io.kotest.assertions.core.jvm" level="project" />
<orderEntry type="library" name="io.kotest.runner.junit5.jvm" level="project" /> <orderEntry type="library" name="io.kotest.runner.junit5.jvm" level="project" />
<orderEntry type="library" name="io.kotest.framework.datatest" level="project" />
</component> </component>
</module> </module>

View File

@ -28,6 +28,7 @@ dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8" implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8"
implementation "com.michael-bull.kotlin-result:kotlin-result-jvm:2.0.0" implementation "com.michael-bull.kotlin-result:kotlin-result-jvm:2.0.0"
testImplementation 'io.kotest:kotest-runner-junit5-jvm:5.9.1' testImplementation 'io.kotest:kotest-runner-junit5-jvm:5.9.1'
testImplementation 'io.kotest:kotest-framework-datatest:5.9.1'
testImplementation 'org.junit.jupiter:junit-jupiter:5.9.2' testImplementation 'org.junit.jupiter:junit-jupiter:5.9.2'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher' testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
} }

View File

@ -12,7 +12,8 @@
<orderEntry type="library" name="KotlinJavaRuntime" level="project" /> <orderEntry type="library" name="KotlinJavaRuntime" level="project" />
<orderEntry type="library" name="io.kotest.assertions.core.jvm" level="project" /> <orderEntry type="library" name="io.kotest.assertions.core.jvm" level="project" />
<orderEntry type="library" name="io.kotest.runner.junit5.jvm" level="project" /> <orderEntry type="library" name="io.kotest.runner.junit5.jvm" level="project" />
<orderEntry type="module" module-name="codeCore" /> <orderEntry type="library" name="io.kotest.framework.datatest" level="project" />
<orderEntry type="module" module-name="intermediate" /> <orderEntry type="module" module-name="intermediate" />
<orderEntry type="module" module-name="codeCore" />
</component> </component>
</module> </module>