package viaduct.codegen.km

import io.kotest.matchers.collections.shouldHaveSize
import kotlinx.metadata.ClassKind
import org.junit.jupiter.api.Test
import viaduct.codegen.utils.KmName
import viaduct.invariants.InvariantChecker

/** A few smoke tests of the inberiant checker using Kotlin metadata
 *  generated by [KmClassFilesBuilder].
 */
class KmClassInvariantsFromContext {
    @Test
    fun testSimpleGoodClass() {
        val ctx = KmClassFilesBuilder()
        ctx.customClassBuilder(ClassKind.CLASS, KmName("foo/bar/Baz"))
        val check = InvariantChecker().also { ctx.checkInvariants(it) }
        check.assertEmptyMultiline("KmClassFilesBuilder with foo/bar/Baz class should be empty")
    }

    // @Test
    fun testSimpleBadClass() {
        val ctx = KmClassFilesBuilder()
        val check = InvariantChecker().also { ctx.checkInvariants(it) }
        check.assertEmptyMultiline("KmClassFilesBuilder with no class should be empty")
    }

    @Test
    fun testGoodSupertype() {
        val ctx = KmClassFilesBuilder()
        val foo = ctx.customClassBuilder(ClassKind.INTERFACE, KmName("Foo"))
        ctx.customClassBuilder(ClassKind.CLASS, KmName("Bar")).apply {
            addSupertype(foo.kmType)
        }
        val check = InvariantChecker().also { ctx.checkInvariants(it) }
        check.assertEmptyMultiline("KmClassFilesBuilder with Foo interface should be empty")
    }

    @Test
    fun testBadSupertype() {
        val ctx = KmClassFilesBuilder()
        val foo = ctx.customClassBuilder(ClassKind.CLASS, KmName("Foo"))
        val bar = ctx.customClassBuilder(ClassKind.CLASS, KmName("Bar"))
        ctx.customClassBuilder(ClassKind.CLASS, KmName("Baz")).apply {
            addSupertype(foo.kmType)
            addSupertype(bar.kmType)
        }
        val check = InvariantChecker().also { ctx.checkInvariants(it) }
        check shouldHaveSize 1
    }
}
