package model import org.jetbrains.dokka.base.transformers.documentables.CallableExtensions import org.jetbrains.dokka.model.DClass import org.jetbrains.dokka.model.DFunction import org.jetbrains.dokka.model.DInterface import org.jetbrains.dokka.model.Documentable import org.jetbrains.dokka.model.properties.WithExtraProperties import org.junit.jupiter.api.Test import utils.AbstractModelTest import utils.UsingJDK class ExtensionsTest : AbstractModelTest("/src/main/kotlin/classes/Test.kt", "classes") { private fun , R : Documentable> T.checkExtension(name: String = "extension") = with(extra[CallableExtensions]?.extensions) { this notNull "extensions" this counts 1 (this?.single() as? DFunction)?.name equals name } @Test fun `should be extension for subclasses`() { inlineModelTest( """ |open class A |open class B: A() |open class C: B() |open class D: C() |fun B.extension() = "" """ ) { with((this / "classes" / "B").cast()) { checkExtension() } with((this / "classes" / "C").cast()) { checkExtension() } with((this / "classes" / "D").cast()) { checkExtension() } with((this / "classes" / "A").cast()) { extra[CallableExtensions] equals null } } } @Test fun `should be extension for interfaces`() { inlineModelTest( """ |interface I |interface I2 : I |open class A: I2 |fun I.extension() = "" """ ) { with((this / "classes" / "A").cast()) { checkExtension() } with((this / "classes" / "I2").cast()) { checkExtension() } with((this / "classes" / "I").cast()) { checkExtension() } } } @UsingJDK @Test fun `should be extension for external classes`() { inlineModelTest( """ |abstract class A: AbstractList() |fun AbstractCollection.extension() {} | |class B:Exception() |fun Throwable.extension() = "" """ ) { with((this / "classes" / "A").cast()) { checkExtension() } with((this / "classes" / "B").cast()) { checkExtension() } } } @Test fun `should be extension for typealias`() { inlineModelTest( """ |open class A |open class B: A() |open class C: B() |open class D: C() |typealias B2 = B |fun B2.extension() = "" """ ) { with((this / "classes" / "B").cast()) { checkExtension() } with((this / "classes" / "C").cast()) { checkExtension() } with((this / "classes" / "D").cast()) { checkExtension() } with((this / "classes" / "A").cast()) { extra[CallableExtensions] equals null } } } @Test fun `should be extension for java classes`() { val testConfiguration = dokkaConfiguration { suppressObviousFunctions = false sourceSets { sourceSet { sourceRoots = listOf("src/main/kotlin/") classpath += jvmStdlibPath!! } } } testInline( """ |/src/main/kotlin/classes/Test.kt | package classes | fun A.extension() = "" | |/src/main/kotlin/classes/A.java | package classes; | public class A {} | | /src/main/kotlin/classes/B.java | package classes; | public class B extends A {} """, configuration = testConfiguration ) { documentablesTransformationStage = { it.run { with((this / "classes" / "B").cast()) { checkExtension() } with((this / "classes" / "A").cast()) { checkExtension() } } } } } }