From 8e5c63d035ef44a269b8c43430f43f5c8eebfb63 Mon Sep 17 00:00:00 2001 From: Ignat Beresnev Date: Fri, 10 Nov 2023 11:46:54 +0100 Subject: Restructure the project to utilize included builds (#3174) * Refactor and simplify artifact publishing * Update Gradle to 8.4 * Refactor and simplify convention plugins and build scripts Fixes #3132 --------- Co-authored-by: Adam <897017+aSemy@users.noreply.github.com> Co-authored-by: Oleg Yukhnevich --- .../dokka/gradle/AbstractDokkaParentTaskTest.kt | 204 --------- .../dokka/gradle/AndroidAutoConfigurationTest.kt | 86 ---- .../jetbrains/dokka/gradle/AutomagicProxyTest.kt | 52 --- .../dokka/gradle/CheckSourceSetDependenciesTest.kt | 71 --- .../gradle/ConfigureWithKotlinSourceSetGistTest.kt | 170 ------- .../dokka/gradle/DokkaConfigurationJsonTest.kt | 72 --- .../gradle/DokkaConfigurationSerializableTest.kt | 78 ---- .../dokka/gradle/DokkaMultiModuleFileLayoutTest.kt | 138 ------ .../jetbrains/dokka/gradle/DokkaPluginApplyTest.kt | 153 ------- .../dokka/gradle/GradleDokkaSourceSetBuilder.kt | 14 - .../gradle/GradleDokkaSourceSetBuilderTest.kt | 494 --------------------- .../gradle/KotlinDslDokkaTaskConfigurationTest.kt | 103 ----- .../dokka/gradle/KotlinSourceSetGistTest.kt | 248 ----------- .../gradle/kotlin/KotlinGradlePluginVersionTest.kt | 79 ---- .../dokka/gradle/tasks/DokkaCollectorTaskTest.kt | 113 ----- .../dokka/gradle/tasks/DokkaMultiModuleTaskTest.kt | 244 ---------- .../jetbrains/dokka/gradle/tasks/DokkaTaskTest.kt | 51 --- .../gradle/utils/samWithReceiverWorkarounds.kt | 73 --- 18 files changed, 2443 deletions(-) delete mode 100644 runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/AbstractDokkaParentTaskTest.kt delete mode 100644 runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/AndroidAutoConfigurationTest.kt delete mode 100644 runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/AutomagicProxyTest.kt delete mode 100644 runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/CheckSourceSetDependenciesTest.kt delete mode 100644 runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/ConfigureWithKotlinSourceSetGistTest.kt delete mode 100644 runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/DokkaConfigurationJsonTest.kt delete mode 100644 runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/DokkaConfigurationSerializableTest.kt delete mode 100644 runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/DokkaMultiModuleFileLayoutTest.kt delete mode 100644 runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/DokkaPluginApplyTest.kt delete mode 100644 runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/GradleDokkaSourceSetBuilder.kt delete mode 100644 runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/GradleDokkaSourceSetBuilderTest.kt delete mode 100644 runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/KotlinDslDokkaTaskConfigurationTest.kt delete mode 100644 runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/KotlinSourceSetGistTest.kt delete mode 100644 runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/kotlin/KotlinGradlePluginVersionTest.kt delete mode 100644 runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/tasks/DokkaCollectorTaskTest.kt delete mode 100644 runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/tasks/DokkaMultiModuleTaskTest.kt delete mode 100644 runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/tasks/DokkaTaskTest.kt delete mode 100644 runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/utils/samWithReceiverWorkarounds.kt (limited to 'runners/gradle-plugin/src/test/kotlin/org') diff --git a/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/AbstractDokkaParentTaskTest.kt b/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/AbstractDokkaParentTaskTest.kt deleted file mode 100644 index 02b7a0f9..00000000 --- a/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/AbstractDokkaParentTaskTest.kt +++ /dev/null @@ -1,204 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -@file:Suppress("DEPRECATION") - -package org.jetbrains.dokka.gradle - -import org.gradle.api.Project -import org.gradle.kotlin.dsl.create -import org.gradle.kotlin.dsl.getByName -import org.gradle.testfixtures.ProjectBuilder -import org.jetbrains.dokka.DokkaConfigurationImpl -import org.jetbrains.dokka.gradle.utils.subprojects_ -import kotlin.test.Test -import kotlin.test.assertEquals -import kotlin.test.assertFailsWith - -class AbstractDokkaParentTaskTest { - - private val rootProject = ProjectBuilder.builder().build() - private val subproject0 = ProjectBuilder.builder().withName("subproject0").withParent(rootProject).build() - private val subproject1 = ProjectBuilder.builder().withName("subproject1").withParent(rootProject).build() - private val subSubproject0 = ProjectBuilder.builder().withName("subSubproject0").withParent(subproject0).build() - - init { - rootProject.subprojects_ { - tasks.create("dokkaTask") - } - } - - private val parentTask = rootProject.tasks.create("parent") - - - @Test - fun `add and remove tasks by reference`() { - assertEquals( - emptySet(), parentTask.childDokkaTasks, - "Expected no childDokkaTasks by default" - ) - - parentTask.addChildTask(subproject0.dokkaTask) - assertEquals( - setOf(subproject0.dokkaTask), parentTask.childDokkaTasks, - "Expected ${subproject0.dokkaTask.path} being registered as child task" - ) - - parentTask.addChildTask(subproject1.dokkaTask) - assertEquals( - setOf(subproject0.dokkaTask, subproject1.dokkaTask), parentTask.childDokkaTasks, - "Expected both dokka tasks being present" - ) - - parentTask.removeChildTask(subproject0.dokkaTask) - assertEquals( - setOf(subproject1.dokkaTask), parentTask.childDokkaTasks, - "Expected ${subproject0.dokkaTask.path} being removed from child tasks" - ) - - parentTask.addChildTask(subSubproject0.dokkaTask) - assertEquals( - setOf(subproject1.dokkaTask, subSubproject0.dokkaTask), parentTask.childDokkaTasks, - "Expected ${subSubproject0.dokkaTask.path} being added as child task" - ) - - parentTask.addChildTask(subSubproject0.dokkaTask) - assertEquals( - setOf(subproject1.dokkaTask, subSubproject0.dokkaTask), parentTask.childDokkaTasks, - "Expected no effect for adding a task twice" - ) - } - - @Test - fun `add and remove by absolute path`() { - parentTask.addChildTask(":subproject0:dokkaTask") - assertEquals( - setOf(subproject0.dokkaTask), parentTask.childDokkaTasks, - "Expected ${subproject0.dokkaTask.path} as child task" - ) - - parentTask.addChildTask(":subproject0:subSubproject0:dokkaTask") - assertEquals( - setOf(subproject0.dokkaTask, subSubproject0.dokkaTask), parentTask.childDokkaTasks, - "Expected ${subSubproject0.dokkaTask.path} being added as child task" - ) - - parentTask.removeChildTask(":subproject0:dokkaTask") - assertEquals( - setOf(subSubproject0.dokkaTask), parentTask.childDokkaTasks, - "Expected ${subproject0.dokkaTask.path} being removed as child task" - ) - } - - @Test - fun `add and remove by relative path`() { - parentTask.addChildTask("subproject0:dokkaTask") - assertEquals( - setOf(subproject0.dokkaTask), parentTask.childDokkaTasks, - "Expected ${subproject0.dokkaTask.path} as child task" - ) - - parentTask.addChildTask("subproject0:subSubproject0:dokkaTask") - assertEquals( - setOf(subproject0.dokkaTask, subSubproject0.dokkaTask), parentTask.childDokkaTasks, - "Expected ${subSubproject0.dokkaTask.path} being added as child task" - ) - - parentTask.removeChildTask("subproject0:dokkaTask") - assertEquals( - setOf(subSubproject0.dokkaTask), parentTask.childDokkaTasks, - "Expected ${subproject0.dokkaTask.path} being removed as child task" - ) - } - - @Test - fun `add and remove by relative path ob subproject0`() { - val parentTask = subproject0.tasks.create("parent") - - parentTask.addChildTask("subSubproject0:dokkaTask") - assertEquals( - setOf(subSubproject0.dokkaTask), parentTask.childDokkaTasks, - "Expected ${subSubproject0.dokkaTask.path} being registered as child" - ) - - parentTask.removeChildTask("subSubproject0:dokkaTask") - assertEquals( - emptySet(), parentTask.childDokkaTasks, - "Expected ${subSubproject0.dokkaTask.path} being removed as child" - ) - } - - @Test - fun `add and remove by project and name`() { - parentTask.addChildTasks(rootProject.subprojects, "dokkaTask") - assertEquals( - setOf(subproject0.dokkaTask, subproject1.dokkaTask, subSubproject0.dokkaTask), parentTask.childDokkaTasks, - "Expected all subproject tasks being registered as child task" - ) - - parentTask.removeChildTasks(rootProject.subprojects, "dokkaTask") - assertEquals( - emptySet(), parentTask.childDokkaTasks, - "Expected all tasks being removed" - ) - - parentTask.addChildTasks(listOf(subproject0), "dokkaTask") - assertEquals( - setOf(subproject0.dokkaTask), parentTask.childDokkaTasks, - "Expected only ${subproject0.dokkaTask.path} being registered as child" - ) - - parentTask.addSubprojectChildTasks("dokkaTask") - assertEquals( - setOf(subproject0.dokkaTask, subproject1.dokkaTask, subSubproject0.dokkaTask), parentTask.childDokkaTasks, - "Expected all subproject tasks being registered as child task" - ) - - parentTask.removeSubprojectChildTasks("dokkaTask") - assertEquals( - emptySet(), parentTask.childDokkaTasks, - "Expected all tasks being removed" - ) - - parentTask.addSubprojectChildTasks("dokkaTask") - assertEquals( - setOf(subproject0.dokkaTask, subproject1.dokkaTask, subSubproject0.dokkaTask), parentTask.childDokkaTasks, - "Expected all subproject tasks being registered as child task" - ) - - parentTask.removeChildTasks(subproject0) - assertEquals( - setOf(subproject1.dokkaTask, subSubproject0.dokkaTask), parentTask.childDokkaTasks, - "Expected only ${subproject0.dokkaTask.path} being removed" - ) - - parentTask.addSubprojectChildTasks("dokkaTask") - parentTask.removeChildTasks(listOf(subproject0, subproject1)) - assertEquals( - setOf(subSubproject0.dokkaTask), parentTask.childDokkaTasks, - "Expected ${subproject0.dokkaTask.path} and ${subproject1.dokkaTask.path} being removed" - ) - } - - @Test - fun `adding invalid path will not throw exception`() { - parentTask.addChildTask(":some:stupid:path") - parentTask.childDokkaTasks - } - - @Test - fun `adding non dokka task will throw exception`() { - val badTask = rootProject.tasks.create("badTask") - parentTask.addChildTask(badTask.path) - assertFailsWith { parentTask.childDokkaTasks } - } -} - -internal abstract class TestDokkaParentTask : AbstractDokkaParentTask() { - override fun buildDokkaConfiguration(): DokkaConfigurationImpl { - throw NotImplementedError() - } -} - -private val Project.dokkaTask: DokkaTask get() = tasks.getByName("dokkaTask") diff --git a/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/AndroidAutoConfigurationTest.kt b/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/AndroidAutoConfigurationTest.kt deleted file mode 100644 index 8e00c96c..00000000 --- a/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/AndroidAutoConfigurationTest.kt +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package org.jetbrains.dokka.gradle - -import com.android.build.gradle.LibraryExtension -import org.gradle.api.artifacts.ResolveException -import org.gradle.api.internal.project.ProjectInternal -import org.gradle.kotlin.dsl.configure -import org.gradle.kotlin.dsl.withType -import org.gradle.testfixtures.ProjectBuilder -import kotlin.test.* - -class AndroidAutoConfigurationTest { - - private val project = ProjectBuilder.builder().build().also { project -> - project.plugins.apply("com.android.library") - project.plugins.apply("org.jetbrains.kotlin.android") - project.plugins.apply("org.jetbrains.dokka") - project.extensions.configure { - compileSdkVersion(28) - } - } - - @Test - fun `at least one dokka task created`() { - val dokkaTasks = project.tasks.withType().toList() - assertTrue(dokkaTasks.isNotEmpty(), "Expected at least one dokka task") - } - - @Test - fun `all default source sets are present in dokka`() { - val dokkaTasks = project.tasks.withType().toList() - dokkaTasks.forEach { task -> - val sourceSets = task.dokkaSourceSets.toList() - assertEquals( - listOf( - "androidTest", "androidTestDebug", "debug", "main", - "release", "test", "testDebug", "testRelease", "androidTestRelease" - ).sorted(), - sourceSets.map { it.name }.sorted(), - "Expected all default source sets being registered" - ) - } - } - - @Test - fun `test source sets are suppressed`() { - val dokkaTasks = project.tasks.withType().toList() - project as ProjectInternal - project.evaluate() - dokkaTasks.flatMap { it.dokkaSourceSets }.forEach { sourceSet -> - if ("test" in sourceSet.name.toLowerCase()) { - assertTrue( - sourceSet.suppress.get(), - "Expected source set `${sourceSet.name}` to be suppressed by default" - ) - } else { - assertFalse( - sourceSet.suppress.get(), - "Expected source set `${sourceSet.name}`to not be suppressed by default" - ) - } - } - } - - @Test - fun `source sets have non-empty classpath`() { - val dokkaTasks = project.tasks.withType().toList() - project as ProjectInternal - project.evaluate() - - dokkaTasks.flatMap { it.dokkaSourceSets } - .filterNot { it.name == "androidTestRelease" && it.suppress.get() } // androidTestRelease has empty classpath, but it makes no sense for suppressed source set - .forEach { sourceSet -> - /* - - There is no better way of checking for empty classpath at the moment (without resolving dependencies). - We assume, that an empty classpath can be resolved - We assume, that a non-empty classpath will not be able to resolve (no repositories defined) - */ - assertFailsWith("SourceSet: " + sourceSet.name) { sourceSet.classpath.files } - } - } -} diff --git a/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/AutomagicProxyTest.kt b/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/AutomagicProxyTest.kt deleted file mode 100644 index c8f58f27..00000000 --- a/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/AutomagicProxyTest.kt +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package org.jetbrains.dokka.gradle - -import org.jetbrains.dokka.DokkaBootstrap -import org.jetbrains.dokka.gradle.AutomagicProxyTest.TestInterface -import java.util.function.BiConsumer -import kotlin.test.Test -import kotlin.test.assertEquals -import kotlin.test.assertFailsWith - - -class AutomagicProxyTest { - - private class TestException(message: String, cause: Throwable?) : Exception(message, cause) - - private fun interface TestInterface { - @Throws(Throwable::class) - operator fun invoke(): Int - } - - @Test - fun `simple method invocation`() { - val instance = TestInterface { 0 } - val proxy = automagicTypedProxy(instance.javaClass.classLoader, instance) - assertEquals(0, proxy()) - } - - @Test - fun `exception throw in DokkaBootstrap is not wrapped inside UndeclaredThrowableException`() { - val instanceThrowingTestException = object : DokkaBootstrap { - override fun configure(serializedConfigurationJSON: String, logger: BiConsumer) = Unit - override fun generate() { - throw TestException("Test Exception Message", Exception("Cause Exception Message")) - } - } - - val proxy = automagicTypedProxy( - instanceThrowingTestException.javaClass.classLoader, - instanceThrowingTestException - ) - - val exception = assertFailsWith { - proxy.generate() - } - - assertEquals("Test Exception Message", exception.message) - assertEquals("Cause Exception Message", exception.cause?.message) - } -} diff --git a/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/CheckSourceSetDependenciesTest.kt b/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/CheckSourceSetDependenciesTest.kt deleted file mode 100644 index 92adc0e5..00000000 --- a/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/CheckSourceSetDependenciesTest.kt +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package org.jetbrains.dokka.gradle - -import org.gradle.testfixtures.ProjectBuilder -import java.lang.IllegalArgumentException -import kotlin.test.Test -import kotlin.test.assertFailsWith -import kotlin.test.assertTrue - -class CheckSourceSetDependenciesTest { - - private val project = ProjectBuilder.builder().build() - - @Test - fun `passes when properly configured`() { - val sourceSets = listOf( - GradleDokkaSourceSetBuilder("common", project), - GradleDokkaSourceSetBuilder("jvmAndJsCommon", project).apply { - dependsOn("common") - }, - GradleDokkaSourceSetBuilder("jvm", project).apply { - dependsOn("jvmAndJsCommon") - }, - GradleDokkaSourceSetBuilder("js", project).apply { - dependsOn("jvmAndJsCommon") - } - ) - checkSourceSetDependencies(sourceSets) - } - - @Test - fun `throws exception when dependent source set id cant be found`() { - val sourceSets = listOf( - GradleDokkaSourceSetBuilder("main", project), - GradleDokkaSourceSetBuilder("bad", project).apply { - dependsOn("missing") - } - ) - - val exception = assertFailsWith { - checkSourceSetDependencies(sourceSets) - } - - assertTrue("bad" in exception.message.orEmpty(), "Expected name of source set mentioned") - assertTrue("missing" in exception.message.orEmpty(), "Expected name of missing source set mentioned") - } - - @Test - fun `throws exception when documented source set depends on suppressed source set`() { - val sourceSets = listOf( - GradleDokkaSourceSetBuilder("common", project), - GradleDokkaSourceSetBuilder("intermediate", project).apply { - dependsOn("common") - suppress.set(true) - }, - GradleDokkaSourceSetBuilder("jvm", project).apply { - dependsOn("intermediate") - } - ) - - val exception = assertFailsWith { - checkSourceSetDependencies(sourceSets) - } - - assertTrue("intermediate" in exception.message.orEmpty()) - assertTrue("jvm" in exception.message.orEmpty()) - } -} diff --git a/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/ConfigureWithKotlinSourceSetGistTest.kt b/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/ConfigureWithKotlinSourceSetGistTest.kt deleted file mode 100644 index 55acbf2f..00000000 --- a/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/ConfigureWithKotlinSourceSetGistTest.kt +++ /dev/null @@ -1,170 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package org.jetbrains.dokka.gradle - -import org.gradle.api.artifacts.FileCollectionDependency -import org.gradle.kotlin.dsl.get -import org.gradle.testfixtures.ProjectBuilder -import org.jetbrains.dokka.Platform -import org.jetbrains.dokka.gradle.kotlin.KotlinSourceSetGist -import org.jetbrains.kotlin.gradle.dsl.KotlinJvmProjectExtension -import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType -import kotlin.test.Test -import kotlin.test.assertEquals -import org.jetbrains.dokka.gradle.utils.withDependencies_ -import kotlin.test.assertTrue - -class ConfigureWithKotlinSourceSetGistTest { - @Test - fun `example gist`() { - val project = ProjectBuilder.builder().build() - - val f1Jar = project.file("f1.jar") - val f2Jar = project.file("f2.jar") - assertTrue(f1Jar.createNewFile()) - assertTrue(f2Jar.createNewFile()) - - val customSourceRoot = project.file("customSourceRoot") - assertTrue(customSourceRoot.mkdirs()) - - val gist = KotlinSourceSetGist( - name = "customName", - platform = project.provider { KotlinPlatformType.common }, - isMain = project.provider { true }, - classpath = project.provider { project.files(f1Jar, f2Jar) }, - sourceRoots = project.files(customSourceRoot), - dependentSourceSetNames = project.provider { setOf("customRootSourceSet") } - ) - - val sourceSet = GradleDokkaSourceSetBuilder("", project) - sourceSet.configureWithKotlinSourceSetGist(gist) - - assertEquals( - "common", sourceSet.build().displayName, - "Expected platform being used as default displayName for source set" - ) - - assertEquals( - Platform.common, sourceSet.build().analysisPlatform, - "Expected common platform being set" - ) - - assertEquals( - listOf(f1Jar, f2Jar), sourceSet.build().classpath, - "Expected classpath being present" - ) - - assertEquals( - setOf(sourceSet.DokkaSourceSetID("customRootSourceSet")), sourceSet.build().dependentSourceSets, - "Expected customRootSourceSet being present in dependentSourceSets after build" - ) - - assertEquals( - setOf(customSourceRoot), sourceSet.build().sourceRoots, - "Expected customSourceRoot being present in sourceRoots after build" - ) - } - - @Test - fun `display name for source set customMain`() { - val project = ProjectBuilder.builder().build() - - val gist = KotlinSourceSetGist( - name = "customMain", - platform = project.provider { KotlinPlatformType.common }, - isMain = project.provider { true }, - classpath = project.provider { project.files() }, - sourceRoots = project.files(), - dependentSourceSetNames = project.provider { emptySet() } - ) - - val sourceSet = GradleDokkaSourceSetBuilder("", project) - sourceSet.configureWithKotlinSourceSetGist(gist) - - assertEquals( - "custom", sourceSet.build().displayName, - "Expected 'Main' being trimmed from source set name and used as display name" - ) - } - - @Suppress("UnstableApiUsage") - @Test - fun `configuration with kotlin source set is live`() { - val project = ProjectBuilder.builder().build() - project.plugins.apply("org.jetbrains.kotlin.jvm") - val kotlin = project.kotlin as KotlinJvmProjectExtension - val mainSourceSet = kotlin.sourceSets["main"] - - /* Make sure that the source roots exist on filesystem */ - mainSourceSet.kotlin.sourceDirectories.elements.get().map { it.asFile }.forEach { it.mkdirs() } - - /* Make sure to remove dependencies that cannot be resolved during test */ - project.configurations.configureEach { - withDependencies_ { - removeIf { dependency -> dependency !is FileCollectionDependency } - } - } - - val dokkaSourceSet = GradleDokkaSourceSetBuilder("main", project) - dokkaSourceSet.kotlinSourceSet(mainSourceSet) - - assertEquals( - listOf(project.file("src/main/kotlin"), project.file("src/main/java")), - dokkaSourceSet.sourceRoots.elements.get().map { it.asFile }, - "Expected default source roots being present in dokkaSourceSet" - ) - - val customSourceRoot = project.file("src/main/customRoot") - assertTrue(customSourceRoot.mkdirs()) - mainSourceSet.kotlin.srcDir(customSourceRoot) - - assertEquals( - listOf(project.file("src/main/kotlin"), project.file("src/main/java"), project.file("src/main/customRoot")), - dokkaSourceSet.sourceRoots.elements.get().map { it.asFile }, - "Expected customRoot being added to source roots in dokkaSourceSet" - ) - } - - @Test - fun `changing classpath`() { - val project = ProjectBuilder.builder().build() - val dokkaSourceSet = GradleDokkaSourceSetBuilder("main", project) - var classpath = project.files() - - dokkaSourceSet.configureWithKotlinSourceSetGist( - KotlinSourceSetGist( - name = "gist", - platform = project.provider { KotlinPlatformType.common }, - isMain = project.provider { true }, - dependentSourceSetNames = project.provider { emptySet() }, - sourceRoots = project.files(), - classpath = project.provider { classpath } - ) - ) - - dokkaSourceSet.classpath.from("base.jar") - classpath.from("f1.jar") - classpath.from("f2.jar") - assertEquals( - setOf(project.file("f1.jar"), project.file("f2.jar"), project.file("base.jar")), - dokkaSourceSet.classpath.files, - "Expected files from initial gist classpath and manually added file base.jar to be present in classpath" - ) - - /* - Swapping the original file collection in favour of a new one. - We expect that the base.jar is still present, as it was configured on the dokka source set. - We also expect, that the new files from the new file collection are replacing old ones - */ - classpath = project.files("f3.jar", "f4.jar") - assertEquals( - setOf(project.file("f3.jar"), project.file("f4.jar"), project.file("base.jar")), - dokkaSourceSet.classpath.files, - "Expected files from changed gist classpath and manually added file base.jar to be present in classpath" - ) - } - - -} diff --git a/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/DokkaConfigurationJsonTest.kt b/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/DokkaConfigurationJsonTest.kt deleted file mode 100644 index c2a05eb5..00000000 --- a/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/DokkaConfigurationJsonTest.kt +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package org.jetbrains.dokka.gradle - -import org.gradle.kotlin.dsl.withType -import org.gradle.testfixtures.ProjectBuilder -import org.jetbrains.dokka.DokkaConfiguration -import org.jetbrains.dokka.DokkaConfigurationImpl -import org.jetbrains.dokka.PluginConfigurationImpl -import org.jetbrains.dokka.gradle.utils.create_ -import org.jetbrains.dokka.gradle.utils.externalDocumentationLink_ -import org.jetbrains.dokka.gradle.utils.withDependencies_ -import org.jetbrains.dokka.toCompactJsonString -import java.io.File -import java.net.URL -import kotlin.test.Test -import kotlin.test.assertEquals - -class DokkaConfigurationJsonTest { - - @Test - fun `DokkaTask configuration toJsonString then parseJson`() { - val project = ProjectBuilder.builder().build() - project.plugins.apply("org.jetbrains.dokka") - val dokkaTask = project.tasks.withType().first() - dokkaTask.plugins.withDependencies_ { clear() } - dokkaTask.apply { - this.failOnWarning.set(true) - this.offlineMode.set(true) - this.outputDirectory.set(File("customOutputDir")) - this.cacheRoot.set(File("customCacheRoot")) - this.pluginsConfiguration.add( - PluginConfigurationImpl( - "A", - DokkaConfiguration.SerializationFormat.JSON, - """ { "key" : "value1" } """ - ) - ) - this.pluginsConfiguration.add( - PluginConfigurationImpl( - "B", - DokkaConfiguration.SerializationFormat.JSON, - """ { "key" : "value2" } """ - ) - ) - this.dokkaSourceSets.create_("main") { - displayName.set("customSourceSetDisplayName") - reportUndocumented.set(true) - - externalDocumentationLink_ { - packageListUrl.set(URL("http://some.url")) - url.set(URL("http://some.other.url")) - } - perPackageOption { - includeNonPublic.set(true) - reportUndocumented.set(true) - skipDeprecated.set(true) - documentedVisibilities.set(setOf(DokkaConfiguration.Visibility.PRIVATE)) - } - } - } - - val sourceConfiguration = dokkaTask.buildDokkaConfiguration() - val configurationJson = sourceConfiguration.toCompactJsonString() - val parsedConfiguration = DokkaConfigurationImpl(configurationJson) - - assertEquals(sourceConfiguration, parsedConfiguration) - println(parsedConfiguration) - } -} diff --git a/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/DokkaConfigurationSerializableTest.kt b/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/DokkaConfigurationSerializableTest.kt deleted file mode 100644 index 02fd728b..00000000 --- a/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/DokkaConfigurationSerializableTest.kt +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package org.jetbrains.dokka.gradle - -import org.gradle.kotlin.dsl.withType -import org.gradle.testfixtures.ProjectBuilder -import org.jetbrains.dokka.DokkaConfiguration -import org.jetbrains.dokka.PluginConfigurationImpl -import org.jetbrains.dokka.gradle.utils.create_ -import org.jetbrains.dokka.gradle.utils.externalDocumentationLink_ -import org.jetbrains.dokka.gradle.utils.withDependencies_ -import org.junit.jupiter.api.io.TempDir -import java.io.File -import java.io.ObjectInputStream -import java.io.ObjectOutputStream -import java.net.URL -import kotlin.test.Test -import kotlin.test.assertEquals - -class DokkaConfigurationSerializableTest { - - @Test - fun `DokkaTask configuration write to file then parse`(@TempDir tempDirectory: File) { - val project = ProjectBuilder.builder().build() - project.plugins.apply("org.jetbrains.dokka") - val dokkaTask = project.tasks.withType().first() - dokkaTask.plugins.withDependencies_ { clear() } - dokkaTask.apply { - this.failOnWarning.set(true) - this.offlineMode.set(true) - this.outputDirectory.set(File("customOutputDir")) - this.cacheRoot.set(File("customCacheRoot")) - this.pluginsConfiguration.add( - PluginConfigurationImpl( - "A", - DokkaConfiguration.SerializationFormat.JSON, - """ { "key" : "value1" } """ - ) - ) - this.pluginsConfiguration.add( - PluginConfigurationImpl( - "B", - DokkaConfiguration.SerializationFormat.JSON, - """ { "key" : "value2" } """ - ) - ) - this.dokkaSourceSets.create_("main") { - displayName.set("customSourceSetDisplayName") - reportUndocumented.set(true) - - externalDocumentationLink_ { - packageListUrl.set(URL("http://some.url")) - url.set(URL("http://some.other.url")) - } - - perPackageOption { - includeNonPublic.set(true) - reportUndocumented.set(true) - skipDeprecated.set(true) - documentedVisibilities.set(setOf(DokkaConfiguration.Visibility.PRIVATE)) - } - } - } - - val sourceConfiguration = dokkaTask.buildDokkaConfiguration() - val configurationFile = tempDirectory.resolve("config.bin") - ObjectOutputStream(configurationFile.outputStream()).use { stream -> - stream.writeObject(sourceConfiguration) - } - val parsedConfiguration = ObjectInputStream(configurationFile.inputStream()).use { stream -> - stream.readObject() as DokkaConfiguration - } - - assertEquals(sourceConfiguration, parsedConfiguration) - } -} diff --git a/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/DokkaMultiModuleFileLayoutTest.kt b/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/DokkaMultiModuleFileLayoutTest.kt deleted file mode 100644 index 8acd3547..00000000 --- a/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/DokkaMultiModuleFileLayoutTest.kt +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package org.jetbrains.dokka.gradle - -import org.gradle.kotlin.dsl.create -import org.gradle.testfixtures.ProjectBuilder -import org.jetbrains.dokka.DokkaException -import org.jetbrains.dokka.gradle.DokkaMultiModuleFileLayout.CompactInParent -import org.jetbrains.dokka.gradle.DokkaMultiModuleFileLayout.NoCopy -import java.io.File -import kotlin.test.Test -import kotlin.test.assertEquals -import kotlin.test.assertFailsWith -import kotlin.test.assertTrue - -class DokkaMultiModuleFileLayoutTest { - - @Test - fun `no copy`() { - val project = ProjectBuilder.builder().build() - project.plugins.apply("org.jetbrains.dokka") - - val child = project.tasks.create("child") - val parent = project.tasks.create("parent") - child.outputDirectory.set(File("some/path")) - - assertEquals( - File("some/path"), - NoCopy.targetChildOutputDirectory(parent, child).get().asFile.relativeTo(project.projectDir), - "Expected original file path returned" - ) - } - - @Test - fun `compact in parent`() { - val rootProject = ProjectBuilder.builder().build() - - val parentProject = ProjectBuilder.builder().withName("parent").withParent(rootProject).build() - parentProject.plugins.apply("org.jetbrains.dokka") - - val intermediateProject = ProjectBuilder.builder().withName("intermediate").withParent(parentProject).build() - val childProject = ProjectBuilder.builder().withName("child").withParent(intermediateProject).build() - childProject.plugins.apply("org.jetbrains.dokka") - - val parentTask = parentProject.tasks.create("parentTask") - val childTask = childProject.tasks.create("childTask") - - val targetOutputDirectory = CompactInParent.targetChildOutputDirectory(parentTask, childTask) - assertEquals( - parentTask.outputDirectory.get().asFile.resolve("intermediate/child"), - targetOutputDirectory.get().asFile, - "Expected nested file structure representing project structure" - ) - } - - @Test - fun copyChildOutputDirectory() { - /* Prepare */ - val project = ProjectBuilder.builder().build() - project.plugins.apply("org.jetbrains.dokka") - - val childTask = project.tasks.create("child") - val parentTask = project.tasks.create("parent") - - val sourceOutputDirectory = childTask.outputDirectory.get().asFile - sourceOutputDirectory.mkdirs() - sourceOutputDirectory.resolve("some.file").writeText("some text") - val subFolder = sourceOutputDirectory.resolve("subFolder") - subFolder.mkdirs() - subFolder.resolve("other.file").writeText("other text") - - parentTask.fileLayout.set(DokkaMultiModuleFileLayout { parent, _ -> - parent.project.provider { parent.project.layout.projectDirectory.dir("target/output") } - }) - parentTask.copyChildOutputDirectory(childTask) - - /* Assertions */ - val targetOutputDirectory = project.file("target/output") - assertTrue( - targetOutputDirectory.exists() && targetOutputDirectory.isDirectory, - "Expected target output directory ${targetOutputDirectory.path} to exist" - ) - - val targetSomeFile = targetOutputDirectory.resolve("some.file") - assertTrue( - targetSomeFile.exists() && targetSomeFile.isFile, - "Expected sample file to exist in target output directory" - ) - - assertEquals( - "some text", targetSomeFile.readText(), - "Expected content to be written into sample file" - ) - - val targetSubFolder = targetOutputDirectory.resolve("subFolder") - assertTrue( - targetSubFolder.exists() && targetSubFolder.isDirectory, - "Expected sub folder being present in target output directory" - ) - - val targetOtherFile = targetSubFolder.resolve("other.file") - assertTrue( - targetOtherFile.exists() && targetOtherFile.isFile, - "Expected nested 'other.file' being copied into target" - ) - - assertEquals( - "other text", targetOtherFile.readText(), - "Expected content to be written into 'other.file'" - ) - } - - @Test - fun `copyChildOutputDirectory target output directory within itself throws DokkaException`() { - val project = ProjectBuilder.builder().build() - project.plugins.apply("org.jetbrains.dokka") - - val childTask = project.tasks.create("child") - val parentTask = project.tasks.create("parent") - parentTask.fileLayout.set(DokkaMultiModuleFileLayout { _, child -> - child.outputDirectory.dir("subfolder") - }) - assertFailsWith { parentTask.copyChildOutputDirectory(childTask) } - } - - @Test - fun `copyChildOutputDirectory NoCopy`() { - val project = ProjectBuilder.builder().build() - project.plugins.apply("org.jetbrains.dokka") - - val childTask = project.tasks.create("child") - val parentTask = project.tasks.create("parent") - parentTask.fileLayout.set(NoCopy) - parentTask.copyChildOutputDirectory(childTask) - } -} diff --git a/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/DokkaPluginApplyTest.kt b/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/DokkaPluginApplyTest.kt deleted file mode 100644 index d41ba672..00000000 --- a/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/DokkaPluginApplyTest.kt +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package org.jetbrains.dokka.gradle - -import org.gradle.api.plugins.JavaBasePlugin -import org.gradle.api.tasks.TaskContainer -import org.gradle.kotlin.dsl.withType -import org.gradle.testfixtures.ProjectBuilder -import kotlin.test.Test -import kotlin.test.assertEquals -import kotlin.test.assertSame -import kotlin.test.assertTrue - -class DokkaPluginApplyTest { - - @Test - fun `one task per format is registered`() { - val project = ProjectBuilder.builder().build() - project.plugins.apply("org.jetbrains.dokka") - - assertTrue( - project.tasks.findByName("dokkaHtml") is DokkaTask, - "Expected DokkaTask: dokkaHtml" - ) - - assertTrue( - project.tasks.findByName("dokkaGfm") is DokkaTask, - "Expected DokkaTask: dokkaGfm" - ) - - assertTrue( - project.tasks.findByName("dokkaJekyll") is DokkaTask, - "Expected DokkaTask: dokkaJekyll" - ) - - assertTrue( - project.tasks.findByName("dokkaJavadoc") is DokkaTask, - "Expected DokkaTask: dokkaJavadoc" - ) - } - - @Test - fun `dokka plugin configurations extend dokkaPlugin`() { - val project = ProjectBuilder.builder().build() - project.plugins.apply("org.jetbrains.dokka") - - val dokkaPluginsConfiguration = project.maybeCreateDokkaDefaultPluginConfiguration() - - project.tasks.withType().forEach { dokkaTask -> - assertSame( - dokkaTask.plugins.extendsFrom.single(), dokkaPluginsConfiguration, - "Expected dokka plugins configuration to extend default ${dokkaPluginsConfiguration.name} configuration" - ) - } - } - - @Test - fun `all dokka tasks are part of the documentation group`() { - val project = ProjectBuilder.builder().build() - project.plugins.apply("org.jetbrains.dokka") - assertDokkaTasksHaveDocumentationGroup(project.tasks) - } - - @Test - fun `all dokka tasks are part of the documentation group in a multi module setup`() { - val root = ProjectBuilder.builder().withName("root").build() - val child = ProjectBuilder.builder().withName("child").withParent(root).build() - root.plugins.apply("org.jetbrains.dokka") - child.plugins.apply("org.jetbrains.dokka") - assertDokkaTasksHaveDocumentationGroup(root.tasks) - assertDokkaTasksHaveDocumentationGroup(child.tasks) - } - - @Test - fun `old dokka tasks are part of the deprecated group in a multi module setup`() { - val root = ProjectBuilder.builder().withName("root").build() - val child = ProjectBuilder.builder().withName("child").withParent(root).build() - root.plugins.apply("org.jetbrains.dokka") - child.plugins.apply("org.jetbrains.dokka") - assertOldDokkaTasksHaveDeprecatedGroup(root.tasks) - assertOldDokkaTasksHaveDeprecatedGroup(child.tasks) - } - - @Test - fun `all dokka tasks provide a task description`() { - val project = ProjectBuilder.builder().build() - project.plugins.apply("org.jetbrains.dokka") - assertDokkaTasksHaveDescription(project.tasks) - } - - @Test - fun `all dokka tasks provide a task description in a multi module setup`() { - val root = ProjectBuilder.builder().withName("root").build() - val child = ProjectBuilder.builder().withName("child").withParent(root).build() - root.plugins.apply("org.jetbrains.dokka") - child.plugins.apply("org.jetbrains.dokka") - assertDokkaTasksHaveDescription(root.tasks) - assertDokkaTasksHaveDescription(child.tasks) - } - - @Test - fun `parent dokka tasks have children configured`() { - val root = ProjectBuilder.builder().withName("root").build() - val child = ProjectBuilder.builder().withName("child").withParent(root).build() - root.plugins.apply("org.jetbrains.dokka") - child.plugins.apply("org.jetbrains.dokka") - - val parentTasks = root.tasks.withType() - assertTrue(parentTasks.isNotEmpty(), "Expected at least one parent task being created") - - parentTasks.toList().forEach { parentTask -> - assertEquals(1, parentTask.childDokkaTasks.size, "Expected one child dokka task") - assertEquals( - child, parentTask.childDokkaTasks.single().project, - "Expected child dokka task from child project" - ) - } - } -} - -private fun assertDokkaTasksHaveDocumentationGroup(taskContainer: TaskContainer) { - taskContainer.withType().forEach { dokkaTask -> - assertEquals( - JavaBasePlugin.DOCUMENTATION_GROUP, - dokkaTask.group, - "Expected task: ${dokkaTask.path} group to be \"${JavaBasePlugin.DOCUMENTATION_GROUP}\"" - ) - } -} - -private fun assertOldDokkaTasksHaveDeprecatedGroup(taskContainer: TaskContainer) { - taskContainer.names.filter { "Multimodule" in it }.forEach { dokkaTaskName -> - val dokkaTask = taskContainer.getByName(dokkaTaskName) - val expectedGroup = "deprecated" - assertEquals( - expectedGroup, - dokkaTask.group, - "Expected task: ${dokkaTask.path} group to be \"${expectedGroup}\"" - ) - } -} - -private fun assertDokkaTasksHaveDescription(taskContainer: TaskContainer) { - taskContainer.withType().forEach { dokkaTask -> - assertTrue( - @Suppress("UselessCallOnNotNull") // Task.description is nullable, but not inherited as Kotlin sees it. - dokkaTask.description.orEmpty().isNotEmpty(), - "Expected description for task ${dokkaTask.name}" - ) - } -} diff --git a/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/GradleDokkaSourceSetBuilder.kt b/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/GradleDokkaSourceSetBuilder.kt deleted file mode 100644 index b973ba53..00000000 --- a/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/GradleDokkaSourceSetBuilder.kt +++ /dev/null @@ -1,14 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package org.jetbrains.dokka.gradle - -import org.gradle.api.Project -import org.jetbrains.dokka.DokkaSourceSetID - -@Suppress("TestFunctionName") -fun GradleDokkaSourceSetBuilder(name: String, project: Project, sourceSetScopeId: String = "${project.path}:test"): - GradleDokkaSourceSetBuilder { - return GradleDokkaSourceSetBuilder(name, project) { DokkaSourceSetID(sourceSetScopeId, it) } -} diff --git a/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/GradleDokkaSourceSetBuilderTest.kt b/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/GradleDokkaSourceSetBuilderTest.kt deleted file mode 100644 index 76f6f58e..00000000 --- a/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/GradleDokkaSourceSetBuilderTest.kt +++ /dev/null @@ -1,494 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package org.jetbrains.dokka.gradle - -import com.android.build.gradle.internal.api.DefaultAndroidSourceSet -import org.gradle.api.Project -import org.gradle.kotlin.dsl.closureOf -import org.gradle.testfixtures.ProjectBuilder -import org.jetbrains.dokka.* -import org.jetbrains.kotlin.gradle.plugin.sources.DefaultKotlinSourceSet -import java.net.URL -import kotlin.test.* - -class GradleDokkaSourceSetBuilderTest { - - private val project = ProjectBuilder.builder().withName("root").build() - - @Test - fun sourceSetId() { - val sourceSet = GradleDokkaSourceSetBuilder("myName", project, "scopeId") - assertEquals( - DokkaSourceSetID("scopeId", "myName"), sourceSet.sourceSetID, - "Expected sourceSet.sourceSetID to match output of DokkaSourceSetID factory function" - ) - - assertEquals( - "scopeId/myName", sourceSet.sourceSetID.toString(), - "Expected SourceSetId's string representation" - ) - } - - @Test - fun classpath() { - val sourceSet = GradleDokkaSourceSetBuilder("", project) - sourceSet.classpath.from(project.file("path/to/file.jar")) - sourceSet.classpath.from(project.file("path/to/other.jar")) - - assertEquals( - listOf(project.file("path/to/file.jar"), project.file("path/to/other.jar")), sourceSet.classpath.toList(), - "Expected both file paths being present in classpath" - ) - - assertEquals( - listOf(project.file("path/to/file.jar"), project.file("path/to/other.jar")), - sourceSet.build().classpath.toList(), - "Expected both file paths being present in built classpath" - ) - } - - @Test - fun displayName() { - val sourceSet = GradleDokkaSourceSetBuilder("myName", project) - assertNull( - sourceSet.displayName.orNull, - "Expected no ${GradleDokkaSourceSetBuilder::displayName.name} being set by default" - ) - - assertEquals( - "myName", sourceSet.build().displayName, - "Expected source set name being used for ${DokkaConfiguration.DokkaSourceSet::displayName.name} " + - "after building source set with no ${GradleDokkaSourceSetBuilder::displayName.name} being set" - ) - - sourceSet.displayName.set("displayName") - assertEquals( - "displayName", sourceSet.build().displayName, - "Expected previously set ${GradleDokkaSourceSetBuilder::displayName.name} to be present after build" - ) - } - - @Test - fun `displayName default for sourceSet ending with Main`() { - val sourceSet = GradleDokkaSourceSetBuilder("jvmMain", project) - assertEquals( - "jvm", sourceSet.build().displayName, - "Expected 'Main' being stripped for source set display name after build" - ) - } - - @Test - fun sourceRoots() { - val sourceSet = GradleDokkaSourceSetBuilder("", project) - sourceSet.sourceRoots.from(project.file("root1")) - sourceSet.sourceRoot(project.file("root2")) - sourceSet.sourceRoot(project.file("root3").absolutePath) - sourceSet.sourceRoot("root4") - - assertEquals( - listOf("root1", "root2", "root3", "root4").map(project::file).toSet(), - sourceSet.build().sourceRoots, - "Expected all files being present" - ) - - sourceSet.build().sourceRoots.forEach { root -> - assertTrue( - root.startsWith(project.projectDir), - "Expected all roots to be inside the projectDir\n" + - "projectDir: ${project.projectDir}\n" + - "root: ${root.absolutePath})" - ) - } - } - - @Test - fun dependentSourceSets() { - val sourceSet = GradleDokkaSourceSetBuilder("", project) - assertEquals(emptySet(), sourceSet.build().dependentSourceSets, "Expected no dependent sourceSets by default") - - sourceSet.dependentSourceSets.add(sourceSet.DokkaSourceSetID("s1")) - sourceSet.dependsOn("s2") - sourceSet.dependsOn(sourceSet.DokkaSourceSetID("s3")) - sourceSet.dependsOn(GradleDokkaSourceSetBuilder("s4", project)) - sourceSet.dependsOn(GradleDokkaSourceSetBuilder("s5", project).build()) - sourceSet.dependsOn(createDefaultKotlinSourceSet("s6")) - sourceSet.dependsOn(DefaultAndroidSourceSet("s7", project, false)) - - assertEquals( - listOf(":/s1", ":/s2", ":/s3", ":/s4", ":/s5", ":/s6", ":/s7"), - sourceSet.build().dependentSourceSets.map { it.toString() }, - "Expected all source sets being registered" - ) - } - - private fun createDefaultKotlinSourceSet(displayName: String): DefaultKotlinSourceSet { - return project.objects.newInstance(DefaultKotlinSourceSet::class.java, project, displayName) - } - - @Test - fun samples() { - val sourceSet = GradleDokkaSourceSetBuilder("", project) - assertEquals(emptySet(), sourceSet.build().samples, "Expected no default samples") - sourceSet.samples.from(project.file("s1")) - sourceSet.samples.from(project.file("s2")) - assertEquals( - setOf(project.file("s1"), project.file("s2")), sourceSet.build().samples, - "Expected all samples being present after build" - ) - } - - @Test - fun includes() { - val sourceSet = GradleDokkaSourceSetBuilder("", project) - assertEquals(emptySet(), sourceSet.build().includes, "Expected no default includees") - sourceSet.includes.from(project.file("i1")) - sourceSet.includes.from(project.file("i2")) - assertEquals( - setOf(project.file("i1"), project.file("i2")), sourceSet.build().includes, - "Expected all includes being present after build" - ) - } - - @Test - @Suppress("DEPRECATION") - fun includeNonPublic() { - val sourceSet = GradleDokkaSourceSetBuilder("", project) - assertEquals( - DokkaDefaults.includeNonPublic, sourceSet.build().includeNonPublic, - "Expected default value for ${GradleDokkaSourceSetBuilder::includeNonPublic.name}" - ) - - sourceSet.includeNonPublic.set(!DokkaDefaults.includeNonPublic) - assertEquals( - !DokkaDefaults.includeNonPublic, sourceSet.build().includeNonPublic, - "Expected flipped value for ${GradleDokkaSourceSetBuilder::includeNonPublic.name}" - ) - } - - @Test - fun documentedVisibilities() { - val sourceSet = GradleDokkaSourceSetBuilder("", project) - assertEquals( - DokkaDefaults.documentedVisibilities, sourceSet.build().documentedVisibilities, - "Expected default value for ${GradleDokkaSourceSetBuilder::documentedVisibilities.name}" - ) - - val visibilities = setOf(DokkaConfiguration.Visibility.PRIVATE, DokkaConfiguration.Visibility.INTERNAL) - sourceSet.documentedVisibilities.set(visibilities) - assertEquals( - visibilities, sourceSet.build().documentedVisibilities, - "Expected to see previously set value for ${GradleDokkaSourceSetBuilder::includeNonPublic.name}" - ) - } - - @Test - fun reportUndocumented() { - val sourceSet = GradleDokkaSourceSetBuilder("", project) - assertEquals( - DokkaDefaults.reportUndocumented, sourceSet.build().reportUndocumented, - "Expected default value for ${GradleDokkaSourceSetBuilder::reportUndocumented.name}" - ) - - sourceSet.reportUndocumented.set(!DokkaDefaults.reportUndocumented) - assertEquals( - !DokkaDefaults.reportUndocumented, sourceSet.build().reportUndocumented, - "Expected flipped value for ${GradleDokkaSourceSetBuilder::reportUndocumented.name}" - ) - } - - @Test - fun jdkVersion() { - val sourceSet = GradleDokkaSourceSetBuilder("", project) - assertEquals( - DokkaDefaults.jdkVersion, sourceSet.build().jdkVersion, - "Expected default value for ${GradleDokkaSourceSetBuilder::jdkVersion.name}" - ) - - sourceSet.jdkVersion.set(DokkaDefaults.jdkVersion + 1) - assertEquals( - DokkaDefaults.jdkVersion + 1, sourceSet.build().jdkVersion, - "Expected increased value for ${GradleDokkaSourceSetBuilder::jdkVersion.name}" - ) - } - - @Test - fun sourceLinks() { - val sourceSet = GradleDokkaSourceSetBuilder("", project) - assertEquals(emptySet(), sourceSet.build().sourceLinks, "Expected no default source links") - - sourceSet.sourceLinks.add( - GradleSourceLinkBuilder(project).apply { - this.remoteLineSuffix.set("ls1") - this.localDirectory.set(project.file("p1")) - this.remoteUrl.set(URL("https://u1")) - }) - - sourceSet.sourceLink { - remoteLineSuffix.set("ls2") - localDirectory.set(project.file("p2")) - remoteUrl.set(URL("https://u2")) - } - - sourceSet.sourceLink(project.closureOf { - this.remoteLineSuffix.set("ls3") - this.localDirectory.set(project.file("p3")) - this.remoteUrl.set(URL("https://u3")) - }) - - assertEquals( - setOf( - SourceLinkDefinitionImpl( - remoteLineSuffix = "ls1", - localDirectory = project.file("p1").absolutePath, - remoteUrl = URL("https://u1") - ), - SourceLinkDefinitionImpl( - remoteLineSuffix = "ls2", - localDirectory = project.file("p2").absolutePath, - remoteUrl = URL("https://u2") - ), - SourceLinkDefinitionImpl( - remoteLineSuffix = "ls3", - localDirectory = project.file("p3").absolutePath, - remoteUrl = URL("https://u3") - ) - ), - sourceSet.build().sourceLinks, - "Expected all source links being present after build" - ) - } - - @Test - fun perPackageOptions() { - val sourceSet = GradleDokkaSourceSetBuilder("", project) - assertEquals(emptyList(), sourceSet.build().perPackageOptions, "Expected no default per package options") - - sourceSet.perPackageOptions.add(GradlePackageOptionsBuilder(project).apply { - this.matchingRegex.set("p1.*") - }) - - sourceSet.perPackageOption { - matchingRegex.set("p2.*") - } - - sourceSet.perPackageOption(project.closureOf { - this.matchingRegex.set("p3.*") - }) - - assertEquals( - listOf("p1.*", "p2.*", "p3.*").map { matchingRegex -> - PackageOptionsImpl( - matchingRegex = matchingRegex, - includeNonPublic = DokkaDefaults.includeNonPublic, - documentedVisibilities = DokkaDefaults.documentedVisibilities, - reportUndocumented = DokkaDefaults.reportUndocumented, - skipDeprecated = DokkaDefaults.skipDeprecated, - suppress = DokkaDefaults.suppress - ) - }, - sourceSet.build().perPackageOptions, - "Expected all package options being present after build" - ) - } - - @Test - fun externalDocumentationLink() { - val sourceSet = GradleDokkaSourceSetBuilder("", project) - sourceSet.noAndroidSdkLink.set(true) - sourceSet.noJdkLink.set(true) - sourceSet.noStdlibLink.set(true) - assertEquals( - emptySet(), sourceSet.build().externalDocumentationLinks, - "Expected no default external documentation links" - ) - - sourceSet.externalDocumentationLinks.add( - GradleExternalDocumentationLinkBuilder(project).apply { - this.url.set(URL("https://u1")) - this.packageListUrl.set(URL("https://pl1")) - } - ) - - sourceSet.externalDocumentationLink { - url.set(URL("https://u2")) - } - - sourceSet.externalDocumentationLink(project.closureOf { - url.set(URL("https://u3")) - }) - - sourceSet.externalDocumentationLink(url = "https://u4", packageListUrl = "https://pl4") - sourceSet.externalDocumentationLink(url = URL("https://u5")) - - assertEquals( - setOf( - ExternalDocumentationLinkImpl(URL("https://u1"), URL("https://pl1")), - ExternalDocumentationLinkImpl(URL("https://u2"), URL("https://u2/package-list")), - ExternalDocumentationLinkImpl(URL("https://u3"), URL("https://u3/package-list")), - ExternalDocumentationLinkImpl(URL("https://u4"), URL("https://pl4")), - ExternalDocumentationLinkImpl(URL("https://u5"), URL("https://u5/package-list")) - ), - sourceSet.build().externalDocumentationLinks, - "Expected all external documentation links being present after build" - ) - } - - @Test - fun languageVersion() { - val sourceSet = GradleDokkaSourceSetBuilder("", project) - assertNull(sourceSet.build().languageVersion, "Expected no language version being set by default") - - sourceSet.languageVersion.set("JAVA_20") - assertEquals( - "JAVA_20", sourceSet.build().languageVersion, - "Expected previously set language version to be present after build" - ) - } - - @Test - fun apiVersion() { - val sourceSet = GradleDokkaSourceSetBuilder("", project) - assertNull(sourceSet.build().apiVersion, "Expected no api version being set by default") - - sourceSet.apiVersion.set("20") - assertEquals( - "20", sourceSet.build().apiVersion, - "Expected previously set api version to be present after build" - ) - } - - @Test - fun noStdlibLink() { - val sourceSet = GradleDokkaSourceSetBuilder("", project) - assertFalse(sourceSet.noStdlibLink.get(), "Expected 'noStdlibLink' to be set to false by default") - - assertEquals(1, sourceSet.build().externalDocumentationLinks.count { - "https://kotlinlang.org/api" in it.url.toURI().toString() - }, "Expected kotlin stdlib in external documentation links") - - sourceSet.noStdlibLink.set(true) - - assertEquals( - 0, sourceSet.build().externalDocumentationLinks.count { - "https://kotlinlang.org/api" in it.url.toURI().toString() - }, "Expected no stdlib in external documentation link" - ) - } - - @Test - fun noJdkLink() { - val sourceSet = GradleDokkaSourceSetBuilder("", project) - assertFalse(sourceSet.noJdkLink.get(), "Expected 'noJdkLink' to be set to false by default") - - assertEquals(1, sourceSet.build().externalDocumentationLinks.count { - "https://docs.oracle.com/" in it.url.toURI().toString() - }, "Expected java jdk in external documentation links") - - sourceSet.noJdkLink.set(true) - - assertEquals( - 0, sourceSet.build().externalDocumentationLinks.count { - "https://docs.oracle.com/" in it.url.toURI().toString() - }, "Expected no java jdk in external documentation link" - ) - } - - - @Test - fun noAndroidSdkLink() { - val sourceSet = GradleDokkaSourceSetBuilder("", project) - assertFalse(sourceSet.noAndroidSdkLink.get(), "Expected 'noAndroidSdkLink' to be set to false by default") - - assertEquals(0, sourceSet.build().externalDocumentationLinks.count { - "https://developer.android.com/reference" in it.url.toURI().toString() - }, "Expected no android sdk in external documentation links (without android plugin)") - - assertEquals(0, sourceSet.build().externalDocumentationLinks.count { - "https://developer.android.com/reference/androidx" in it.packageListUrl.toURI().toString() - }, "Expected no androidx in external documentation links (without android plugin)") - - - project.plugins.apply("com.android.library") - - assertEquals(1, sourceSet.build().externalDocumentationLinks.count { - "https://developer.android.com/reference/kotlin/package-list" in it.packageListUrl.toURI().toString() - }, "Expected android sdk in external documentation links") - - assertEquals(1, sourceSet.build().externalDocumentationLinks.count { - "https://developer.android.com/reference/kotlin/androidx/package-list" in it.packageListUrl.toURI() - .toString() - }, "Expected androidx in external documentation links") - - - sourceSet.noAndroidSdkLink.set(true) - - assertEquals(0, sourceSet.build().externalDocumentationLinks.count { - "https://developer.android.com/reference" in it.url.toURI().toString() - }, "Expected no android sdk in external documentation links") - - assertEquals(0, sourceSet.build().externalDocumentationLinks.count { - "https://developer.android.com/reference/kotlin/androidx/package-list" in it.packageListUrl.toURI() - .toString() - }, "Expected no androidx in external documentation links") - } - - @Test - fun suppressedFiles() { - val sourceSet = GradleDokkaSourceSetBuilder("", project) - assertTrue(sourceSet.build().suppressedFiles.isEmpty(), "Expected no suppressed files by default") - - sourceSet.suppressedFiles.from(project.file("f1")) - sourceSet.suppressedFiles.from("f2") - - assertEquals( - setOf(project.file("f1"), project.file("f2")), sourceSet.build().suppressedFiles, - "Expected all suppressed files to be present after build" - ) - } - - @Test - fun suppressedFilesByDefault() { - val sourceSet = GradleDokkaSourceSetBuilder("", project) - assertTrue(sourceSet.build().suppressedFiles.isEmpty(), "Expected no suppressed files by default") - - val file = project.buildDir.resolve("generated").also { it.mkdirs() } - file.resolve("suppressed.kt").writeText("class A") - - sourceSet.sourceRoots.from(project.buildDir.resolve("generated")) - - val suppressedConfiguration = sourceSet.build() - sourceSet.suppressGeneratedFiles.set(false) - val unsuppressedConfiguration = sourceSet.build() - - assertEquals( - setOf( - project.buildDir.resolve("generated"), - project.buildDir.resolve("generated").resolve("suppressed.kt") - ), suppressedConfiguration.suppressedFiles, - "Expected all suppressed files to be present after build" - ) - - assertTrue( - unsuppressedConfiguration.suppressedFiles.isEmpty(), - "Expected no files to be suppressed by default" - ) - } - - @Test - fun platform() { - val sourceSet = GradleDokkaSourceSetBuilder("", project) - assertEquals(Platform.DEFAULT, sourceSet.build().analysisPlatform, "Expected default platform if not specified") - - sourceSet.platform.set(Platform.common) - assertEquals( - Platform.common, sourceSet.build().analysisPlatform, - "Expected previously set analysis platform being present after build" - ) - } -} - -@Suppress("TestFunctionName") -private fun GradleDokkaSourceSetBuilder(name: String, project: Project) = - GradleDokkaSourceSetBuilder(name, project, project.path) diff --git a/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/KotlinDslDokkaTaskConfigurationTest.kt b/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/KotlinDslDokkaTaskConfigurationTest.kt deleted file mode 100644 index f95dfdc2..00000000 --- a/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/KotlinDslDokkaTaskConfigurationTest.kt +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package org.jetbrains.dokka.gradle - -import org.gradle.kotlin.dsl.withType -import org.gradle.testfixtures.ProjectBuilder -import org.jetbrains.dokka.gradle.utils.configureEach_ -import org.jetbrains.dokka.gradle.utils.create_ -import org.jetbrains.kotlin.gradle.dsl.KotlinJvmProjectExtension -import java.io.File -import kotlin.test.Test -import kotlin.test.assertEquals - -class KotlinDslDokkaTaskConfigurationTest { - @Test - fun `configure dokka task`() { - val project = ProjectBuilder.builder().build() - project.plugins.apply("org.jetbrains.dokka") - project.tasks.withType().configureEach_ { - outputDirectory.set(File("test")) - } - - project.tasks.withType(DokkaTask::class.java).forEach { dokkaTask -> - assertEquals(File("test"), dokkaTask.outputDirectory.get().asFile.relativeTo(project.projectDir)) - } - } - - @Test - fun `sourceSet dependsOn by String`() { - val project = ProjectBuilder.builder().build() - project.plugins.apply("org.jetbrains.dokka") - - project.tasks.withType(DokkaTask::class.java).forEach { dokkaTask -> - dokkaTask.dokkaSourceSets.run { - val commonMain = create("commonMain") - val jvmMain = create_("jvmMain") { - dependsOn("commonMain") - } - - assertEquals( - 0, commonMain.dependentSourceSets.get().size, - "Expected no dependent source set in commonMain" - ) - - assertEquals( - 1, jvmMain.dependentSourceSets.get().size, - "Expected only one dependent source set in jvmMain" - ) - - assertEquals( - commonMain.sourceSetID, jvmMain.dependentSourceSets.get().single(), - "Expected jvmMain to depend on commonMain" - ) - - assertEquals( - DokkaSourceSetID(dokkaTask, "commonMain"), commonMain.sourceSetID - ) - } - } - } - - @Test - fun `sourceSet dependsOn by DokkaSourceSet`() { - val project = ProjectBuilder.builder().build() - project.plugins.apply("org.jetbrains.dokka") - - project.tasks.withType(DokkaTask::class.java).first().run { - dokkaSourceSets.run { - val commonMain = create("commonMain") - val jvmMain = create("jvmMain") { - dependsOn(commonMain) - } - - assertEquals( - commonMain.sourceSetID, jvmMain.dependentSourceSets.get().single() - ) - } - } - } - - @Test - fun `sourceSet dependsOn by KotlinSourceSet`() { - val project = ProjectBuilder.builder().build() - project.plugins.apply("org.jetbrains.dokka") - project.plugins.apply("org.jetbrains.kotlin.jvm") - - val kotlin = project.extensions.getByName("kotlin") as KotlinJvmProjectExtension - - project.tasks.withType(DokkaTask::class.java).first().apply { - dokkaSourceSets.run { - val special = create("special") { - dependsOn(kotlin.sourceSets.getByName("main")) - } - - assertEquals( - DokkaSourceSetID(this@apply, "main"), special.dependentSourceSets.get().single() - ) - } - } - } -} diff --git a/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/KotlinSourceSetGistTest.kt b/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/KotlinSourceSetGistTest.kt deleted file mode 100644 index 5c99502a..00000000 --- a/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/KotlinSourceSetGistTest.kt +++ /dev/null @@ -1,248 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package org.jetbrains.dokka.gradle - -import org.jetbrains.dokka.gradle.utils.withDependencies_ -import org.gradle.api.artifacts.FileCollectionDependency -import org.gradle.api.internal.project.DefaultProject -import org.gradle.kotlin.dsl.get -import org.gradle.testfixtures.ProjectBuilder -import org.jetbrains.dokka.gradle.kotlin.gistOf -import org.jetbrains.kotlin.gradle.dsl.KotlinJvmProjectExtension -import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension -import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType -import java.io.File -import kotlin.test.Test -import kotlin.test.assertEquals -import kotlin.test.assertFalse -import kotlin.test.assertTrue - -class KotlinSourceSetGistTest { - - @Test - fun `main source set with kotlin jvm`() { - val project = ProjectBuilder.builder().build() - project.plugins.apply("org.jetbrains.kotlin.jvm") - val kotlin = project.kotlin as KotlinJvmProjectExtension - - val mainSourceSet = kotlin.sourceSets.getByName("main") - val mainSourceSetGist = project.gistOf(mainSourceSet) - - assertEquals( - "main", mainSourceSetGist.name, - "Expected correct source set name" - ) - - assertEquals( - KotlinPlatformType.jvm, mainSourceSetGist.platform.get(), - "Expected correct platform" - ) - - assertTrue( - mainSourceSetGist.isMain.get(), - "Expected main sources to be marked as 'isMain'" - ) - - assertEquals( - emptySet(), mainSourceSetGist.dependentSourceSetNames.get(), - "Expected no dependent source sets" - ) - } - - @Test - fun `test source set with kotlin jvm`() { - val project = ProjectBuilder.builder().build() - project.plugins.apply("org.jetbrains.kotlin.jvm") - val kotlin = project.kotlin as KotlinJvmProjectExtension - - val testSourceSet = kotlin.sourceSets.getByName("test") - val testSourceSetGist = project.gistOf(testSourceSet) - - assertFalse( - testSourceSetGist.isMain.get(), - "Expected test source set not being marked as 'isMain'" - ) - - assertEquals( - emptySet(), - testSourceSetGist.dependentSourceSetNames.get(), - "Expected no dependent source sets" - ) - } - - @Test - fun `sourceRoots of main source set with kotlin jvm`() { - val project = ProjectBuilder.builder().build() - project.plugins.apply("org.jetbrains.kotlin.jvm") - val kotlin = project.kotlin as KotlinJvmProjectExtension - val mainSourceSet = kotlin.sourceSets.getByName("main") - val mainSourceSetGist = project.gistOf(mainSourceSet) - - assertEquals( - emptySet(), mainSourceSetGist.sourceRoots.files, - "Expected no sourceRoots, because default source root does not exist on filesystem yet" - ) - - // Create default source root on filesystem - val defaultSourceRoot = project.file("src/main/kotlin") - defaultSourceRoot.mkdirs() - - assertEquals( - setOf(defaultSourceRoot), mainSourceSetGist.sourceRoots.files, - "Expected default source root in source roots, since it is present on the filesystem" - ) - - // Create custom source set (and make sure it exists on filesystem) - val customSourceRoot = project.file("src/main/custom").also(File::mkdirs) - mainSourceSet.kotlin.srcDir(customSourceRoot) - - assertEquals( - setOf(defaultSourceRoot, customSourceRoot), mainSourceSetGist.sourceRoots.files, - "Expected recently registered custom source root to be present" - ) - - // removing default source root - mainSourceSet.kotlin.setSrcDirs(listOf(customSourceRoot)) - - assertEquals( - setOf(customSourceRoot), mainSourceSetGist.sourceRoots.files, - "Expected only custom source root being present in source roots" - ) - } - - @Suppress("UnstableApiUsage") - @Test - fun `classpath of main source set with kotlin jvm`() { - val project = ProjectBuilder.builder().build() - project.plugins.apply("org.jetbrains.kotlin.jvm") - val kotlin = project.kotlin as KotlinJvmProjectExtension - val mainSourceSet = kotlin.sourceSets.getByName("main") - val mainSourceSetGist = project.gistOf(mainSourceSet) - - /* Only work with file dependencies */ - project.configurations.forEach { configuration -> - configuration.withDependencies_ { - removeIf { dependency -> - dependency !is FileCollectionDependency - } - } - } - - val implementationJar = project.file("implementation.jar") - val compileOnlyJar = project.file("compileOnly.jar") - val apiJar = project.file("api.jar") - val runtimeOnlyJar = project.file("runtimeOnly.jar") - - - mainSourceSet.dependencies { - implementation(project.files(implementationJar)) - compileOnly(project.files(compileOnlyJar)) - api(project.files(apiJar)) - runtimeOnly(project.files(runtimeOnlyJar)) - } - - assertEquals( - emptySet(), mainSourceSetGist.classpath.get().files, - "Expected no files on the classpath, since no file exists" - ) - - /* Creating dependency files */ - assertTrue(implementationJar.createNewFile()) - assertTrue(compileOnlyJar.createNewFile()) - assertTrue(apiJar.createNewFile()) - assertTrue(runtimeOnlyJar.createNewFile()) - - assertEquals( - setOf(implementationJar, compileOnlyJar, apiJar), mainSourceSetGist.classpath.get().files, - "Expected implementation, compileOnly and api dependencies on classpath" - ) - } - - @Test - fun `common, jvm and macos source sets with kotlin multiplatform`() { - val project = ProjectBuilder.builder().build() - project.plugins.apply("org.jetbrains.kotlin.multiplatform") - val kotlin = project.kotlin as KotlinMultiplatformExtension - kotlin.jvm() - kotlin.macosX64("macos") - - (project as DefaultProject).evaluate() - val commonMainSourceSet = kotlin.sourceSets.getByName("commonMain") - val commonMainSourceSetGist = project.gistOf(commonMainSourceSet) - - val jvmMainSourceSet = kotlin.sourceSets.getByName("jvmMain") - val jvmMainSourceSetGist = project.gistOf(jvmMainSourceSet) - - val macosMainSourceSet = kotlin.sourceSets.getByName("macosMain") - val macosMainSourceSetGist = project.gistOf(macosMainSourceSet) - - assertEquals( - "commonMain", commonMainSourceSetGist.name, - "Expected correct source set name" - ) - - assertEquals( - "jvmMain", jvmMainSourceSetGist.name, - "Expected correct source set name" - ) - - assertEquals( - "macosMain", macosMainSourceSetGist.name, - "Expected correct source set name" - ) - - assertEquals( - KotlinPlatformType.common, commonMainSourceSetGist.platform.get(), - "Expected common platform for commonMain source set" - ) - - assertEquals( - KotlinPlatformType.jvm, jvmMainSourceSetGist.platform.get(), - "Expected jvm platform for jvmMain source set" - ) - - assertEquals( - KotlinPlatformType.native, macosMainSourceSetGist.platform.get(), - "Expected native platform for macosMain source set" - ) - - assertTrue( - commonMainSourceSetGist.isMain.get(), - "Expected commonMain to be marked with 'isMain'" - ) - - assertTrue( - jvmMainSourceSetGist.isMain.get(), - "Expected jvmMain to be marked with 'isMain'" - ) - - assertTrue( - macosMainSourceSetGist.isMain.get(), - "Expected macosMain to be marked with 'isMain'" - ) - - assertFalse( - project.gistOf(kotlin.sourceSets["commonTest"]).isMain.get(), - "Expected commonTest not being marked with 'isMain'" - ) - - assertFalse( - project.gistOf(kotlin.sourceSets["jvmTest"]).isMain.get(), - "Expected jvmTest not being marked with 'isMain'" - ) - - assertFalse( - project.gistOf(kotlin.sourceSets["macosTest"]).isMain.get(), - "Expected macosTest not being marked with 'isMain'" - ) - - // requires `project.evaluate()` - assertEquals( - setOf("commonMain"), jvmMainSourceSetGist.dependentSourceSetNames.get(), - "Expected jvmMain to depend on commonMain by default" - ) - } - -} diff --git a/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/kotlin/KotlinGradlePluginVersionTest.kt b/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/kotlin/KotlinGradlePluginVersionTest.kt deleted file mode 100644 index e0731687..00000000 --- a/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/kotlin/KotlinGradlePluginVersionTest.kt +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package org.jetbrains.dokka.gradle.kotlin - -import kotlin.test.* - -class KotlinGradlePluginVersionTest { - - @Test - fun `should parse versions`() { - assertParsedVersion(input = "1.7.22", expectedMajor = 1, expectedMinor = 7, expectedPatch = 22) - assertParsedVersion(input = "2.0.0", expectedMajor = 2, expectedMinor = 0, expectedPatch = 0) - assertParsedVersion(input = "1.8.22-RC2", expectedMajor = 1, expectedMinor = 8, expectedPatch = 22) - assertParsedVersion(input = "1.5.22-Beta", expectedMajor = 1, expectedMinor = 5, expectedPatch = 22) - assertParsedVersion(input = "2.7.22-mercury-500", expectedMajor = 2, expectedMinor = 7, expectedPatch = 22) - assertParsedVersion(input = "1.7.100-dev-800", expectedMajor = 1, expectedMinor = 7, expectedPatch = 100) - } - - @Test - fun `should return null on non parsable string`() { - assertNull(parse("1.7")) - assertNull(parse("1")) - assertNull(parse("6")) - assertNull(parse("17.0")) - assertNull(parse("1..7.0")) - assertNull(parse("1.7-Beta")) - assertNull(parse("1.7.0Beta")) - } - - @Test - fun `should compare simple versions`() { - assertEquals(0, KotlinGradlePluginVersion(1, 7, 0).compareTo(KotlinGradlePluginVersion(1, 7, 0))) - - assertTrue(KotlinGradlePluginVersion(1, 6, 10) >= KotlinGradlePluginVersion(1, 6, 10)) - assertTrue(KotlinGradlePluginVersion(1, 6, 10) < KotlinGradlePluginVersion(1, 6, 20)) - assertTrue(KotlinGradlePluginVersion(1, 6, 10) > KotlinGradlePluginVersion(1, 6, 0)) - - assertTrue(KotlinGradlePluginVersion(1, 4, 32) <= KotlinGradlePluginVersion(1, 4, 32)) - assertTrue(KotlinGradlePluginVersion(1, 4, 32) < KotlinGradlePluginVersion(1, 6, 20)) - assertTrue(KotlinGradlePluginVersion(1, 4, 32) > KotlinGradlePluginVersion(1, 3, 0)) - - assertTrue(KotlinGradlePluginVersion(2, 1, 0) > KotlinGradlePluginVersion(1, 8, 0)) - assertTrue(KotlinGradlePluginVersion(1, 5, 31) < KotlinGradlePluginVersion(1, 7, 0)) - } - - @Test - fun `should compare custom dev versions with trailing strings`() { - assertEquals(0, KotlinGradlePluginVersion(1, 7, 0).compareTo(parseNotNull("1.7.0"))) - - assertTrue(KotlinGradlePluginVersion(1, 6, 10) >= parseNotNull("1.6.10-Beta")) - assertTrue(KotlinGradlePluginVersion(1, 6, 10) < parseNotNull("1.6.20")) - assertTrue(KotlinGradlePluginVersion(1, 6, 10) > parseNotNull("1.6.0-RC2")) - - assertTrue(KotlinGradlePluginVersion(1, 4, 32) <= parseNotNull("1.4.32-dev-142")) - assertTrue(KotlinGradlePluginVersion(1, 4, 32) < parseNotNull("1.6.20-Beta")) - assertTrue(KotlinGradlePluginVersion(1, 4, 32) > parseNotNull("1.3.0-RC")) - - assertTrue(KotlinGradlePluginVersion(2, 1, 0) > parseNotNull("1.8.0-mercury-500")) - } - - private fun assertParsedVersion( - input: String, - expectedMajor: Int, - expectedMinor: Int, - expectedPatch: Int - ) { - val kgpVersion = parseNotNull(input) - assertEquals(expectedMajor, kgpVersion.major) - assertEquals(expectedMinor, kgpVersion.minor) - assertEquals(expectedPatch, kgpVersion.patch) - assertEquals(KotlinGradlePluginVersion(expectedMajor, expectedMinor, expectedPatch), kgpVersion) - } - - private fun parseNotNull(input: String): KotlinGradlePluginVersion = assertNotNull(parse(input)) - - private fun parse(input: String): KotlinGradlePluginVersion? = parseKotlinVersion(input) -} diff --git a/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/tasks/DokkaCollectorTaskTest.kt b/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/tasks/DokkaCollectorTaskTest.kt deleted file mode 100644 index 07cb04d2..00000000 --- a/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/tasks/DokkaCollectorTaskTest.kt +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package org.jetbrains.dokka.gradle.tasks - -import org.gradle.kotlin.dsl.create -import org.gradle.kotlin.dsl.withType -import org.gradle.testfixtures.ProjectBuilder -import org.jetbrains.dokka.DokkaConfigurationImpl -import org.jetbrains.dokka.DokkaException -import org.jetbrains.dokka.gradle.AbstractDokkaTask -import org.jetbrains.dokka.gradle.DokkaCollectorTask -import org.jetbrains.dokka.gradle.DokkaTask -import org.jetbrains.dokka.gradle.utils.all_ -import org.jetbrains.dokka.gradle.utils.allprojects_ -import org.jetbrains.dokka.gradle.utils.configureEach_ -import org.jetbrains.dokka.gradle.utils.withDependencies_ -import java.io.File -import kotlin.test.* - -class DokkaCollectorTaskTest { - - @Test - fun buildDokkaConfiguration() { - val rootProject = ProjectBuilder.builder().build() - val childProject = ProjectBuilder.builder().withParent(rootProject).build() - childProject.plugins.apply("org.jetbrains.kotlin.jvm") - - rootProject.allprojects_ { - plugins.apply("org.jetbrains.dokka") - tasks.withType().configureEach_ { - plugins.withDependencies_ { clear() } - } - tasks.withType().configureEach_ { - dokkaSourceSets.configureEach_ { - classpath.setFrom(emptyList()) - } - } - } - - val collectorTasks = rootProject.tasks.withType() - collectorTasks.configureEach_ { - moduleName.set("custom Module Name") - outputDirectory.set(File("customOutputDirectory")) - cacheRoot.set(File("customCacheRoot")) - failOnWarning.set(true) - offlineMode.set(true) - } - - assertTrue(collectorTasks.isNotEmpty(), "Expected at least one collector task") - - collectorTasks.forEach { task -> - val dokkaConfiguration = task.buildDokkaConfiguration() - assertEquals( - DokkaConfigurationImpl( - moduleName = "custom Module Name", - outputDir = rootProject.projectDir.resolve("customOutputDirectory"), - cacheRoot = rootProject.projectDir.resolve("customCacheRoot"), - failOnWarning = true, - offlineMode = true, - sourceSets = task.childDokkaTasks - .map { it.buildDokkaConfiguration() } - .map { it.sourceSets } - .reduce { acc, list -> acc + list }, - pluginsClasspath = task.childDokkaTasks - .map { it.plugins.resolve().toList() } - .reduce { acc, mutableSet -> acc + mutableSet } - ), - dokkaConfiguration, - ) - } - } - - @Test - fun `verify that cacheRoot is optional, and not required to build DokkaConfiguration`() { - val rootProject = ProjectBuilder.builder().build() - val childProject = ProjectBuilder.builder().withParent(rootProject).build() - childProject.plugins.apply("org.jetbrains.kotlin.jvm") - - rootProject.allprojects_ { - plugins.apply("org.jetbrains.dokka") - tasks.withType().configureEach_ { - plugins.withDependencies_ { clear() } - } - tasks.withType().configureEach_ { - dokkaSourceSets.configureEach_ { - classpath.setFrom(emptyList()) - } - } - } - - val collectorTasks = rootProject.tasks.withType() - collectorTasks.configureEach_ { - cacheRoot.set(null as File?) - } - - assertTrue(collectorTasks.isNotEmpty(), "Expected at least one collector task") - - collectorTasks.forEach { task -> - val dokkaConfiguration = task.buildDokkaConfiguration() - assertNull(dokkaConfiguration.cacheRoot, "Expect that cacheRoot is null") - } - } - - @Test - fun `with no child tasks throws DokkaException`() { - val project = ProjectBuilder.builder().build() - val collectorTask = project.tasks.create("collector") - project.configurations.all_ { withDependencies_ { clear() } } - assertFailsWith { collectorTask.generateDocumentation() } - } -} diff --git a/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/tasks/DokkaMultiModuleTaskTest.kt b/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/tasks/DokkaMultiModuleTaskTest.kt deleted file mode 100644 index a95af583..00000000 --- a/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/tasks/DokkaMultiModuleTaskTest.kt +++ /dev/null @@ -1,244 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -@file:Suppress("UnstableApiUsage", "DEPRECATION", "PackageDirectoryMismatch") - -package org.jetbrains.dokka.gradle - -import org.gradle.kotlin.dsl.create -import org.gradle.kotlin.dsl.withType -import org.gradle.testfixtures.ProjectBuilder -import org.jetbrains.dokka.* -import org.jetbrains.dokka.gradle.utils.allprojects_ -import org.jetbrains.dokka.gradle.utils.configureEach_ -import org.jetbrains.dokka.gradle.utils.create_ -import org.jetbrains.dokka.gradle.utils.withDependencies_ -import java.io.File -import kotlin.test.* - -class DokkaMultiModuleTaskTest { - - private val rootProject = ProjectBuilder.builder() - .withName("root") - .build() - - private val childProject = ProjectBuilder.builder() - .withName("child") - .withProjectDir(rootProject.projectDir.resolve("child")) - .withParent(rootProject).build() - - private val childDokkaTask = childProject.tasks.create("childDokkaTask") - - private val multiModuleTask = rootProject.tasks.create("multiModuleTask").apply { - addChildTask(childDokkaTask) - } - - init { - rootProject.plugins.apply("org.jetbrains.dokka") - childProject.plugins.apply("org.jetbrains.dokka") - rootProject.allprojects_ { - tasks.withType().configureEach_ { - plugins.withDependencies_ { clear() } - } - } - } - - @Test - fun `child project is withing root project`() { - assertEquals( - rootProject.projectDir, childProject.projectDir.parentFile, - "Expected child project being inside the root project" - ) - - assertEquals( - childProject.projectDir.name, "child", - "Expected folder of child project to be called 'child'" - ) - } - - @Test - fun buildDokkaConfiguration() { - val include1 = childDokkaTask.project.file("include1.md") - val include2 = childDokkaTask.project.file("include2.md") - val topLevelInclude = multiModuleTask.project.file("README.md") - - childDokkaTask.apply { - dokkaSourceSets.create("main") - dokkaSourceSets.create("test") - dokkaSourceSets.configureEach_ { - includes.from(include1, include2) - } - } - - multiModuleTask.apply { - moduleVersion.set("1.5.0") - moduleName.set("custom Module Name") - outputDirectory.set(project.buildDir.resolve("customOutputDirectory")) - cacheRoot.set(File("customCacheRoot")) - pluginsConfiguration.add( - PluginConfigurationImpl( - "pluginA", - DokkaConfiguration.SerializationFormat.JSON, - """ { "key" : "value2" } """ - ) - ) - failOnWarning.set(true) - offlineMode.set(true) - includes.from(listOf(topLevelInclude)) - } - - val dokkaConfiguration = multiModuleTask.buildDokkaConfiguration() - assertEquals( - DokkaConfigurationImpl( - moduleName = "custom Module Name", - moduleVersion = "1.5.0", - outputDir = multiModuleTask.project.buildDir.resolve("customOutputDirectory"), - cacheRoot = multiModuleTask.project.projectDir.resolve("customCacheRoot"), - pluginsConfiguration = mutableListOf( - PluginConfigurationImpl( - "pluginA", - DokkaConfiguration.SerializationFormat.JSON, - """ { "key" : "value2" } """ - ) - ), - pluginsClasspath = emptyList(), - failOnWarning = true, - offlineMode = true, - includes = setOf(topLevelInclude), - modules = listOf( - DokkaModuleDescriptionImpl( - name = "child", - relativePathToOutputDirectory = File("child"), - includes = setOf(include1, include2), - sourceOutputDirectory = childDokkaTask.outputDirectory.get().asFile - ) - ) - ), - dokkaConfiguration - ) - } - - @Test - fun `multimodule task should not include unspecified version`() { - childDokkaTask.apply { - dokkaSourceSets.create("main") - dokkaSourceSets.create("test") - } - - multiModuleTask.apply { - moduleVersion.set("unspecified") - } - - val dokkaConfiguration = multiModuleTask.buildDokkaConfiguration() - assertNull(dokkaConfiguration.moduleVersion) - } - - @Test - fun `setting dokkaTaskNames declares proper task dependencies`() { - val dependenciesInitial = multiModuleTask.taskDependencies.getDependencies(multiModuleTask).toSet() - assertEquals(1, dependenciesInitial.size, "Expected one dependency") - val dependency = dependenciesInitial.single() - - assertTrue( - dependency is DokkaTaskPartial, - "Expected dependency to be of Type ${DokkaTaskPartial::class.simpleName}" - ) - assertEquals(childProject, dependency.project, "Expected dependency from child project") - - - val customDokkaTask = childProject.tasks.create("customDokkaTask") - - multiModuleTask.addSubprojectChildTasks("customDokkaTask") - val dependenciesAfter = multiModuleTask.taskDependencies.getDependencies(multiModuleTask).toSet() - - assertEquals(2, dependenciesAfter.size, "Expected two dependencies") - assertTrue(customDokkaTask in dependenciesAfter, "Expected 'customDokkaTask' in dependencies") - - } - - @Test - fun `multimodule task with no child tasks throws DokkaException`() { - val project = ProjectBuilder.builder().build() - val multimodule = project.tasks.create("multimodule") - project.configurations.configureEach_ { withDependencies_ { clear() } } - assertFailsWith { multimodule.generateDocumentation() } - } - - @Test - fun childDokkaTaskIncludes() { - val childDokkaTaskInclude1 = childProject.file("include1") - val childDokkaTaskInclude2 = childProject.file("include2") - val childDokkaTaskInclude3 = childProject.file("include3") - - childDokkaTask.apply { - dokkaSourceSets.create_("main") { - includes.from(childDokkaTaskInclude1, childDokkaTaskInclude2) - } - dokkaSourceSets.create_("main2") { - includes.from(childDokkaTaskInclude3) - } - } - - val secondChildDokkaTaskInclude = childProject.file("include4") - val secondChildDokkaTask = childProject.tasks.create("secondChildDokkaTask") { - dokkaSourceSets.create_("main") { - includes.from(secondChildDokkaTaskInclude) - } - } - multiModuleTask.addChildTask(secondChildDokkaTask) - - assertEquals( - mapOf( - ":child:childDokkaTask" to setOf( - childDokkaTaskInclude1, - childDokkaTaskInclude2, - childDokkaTaskInclude3 - ), - ":child:secondChildDokkaTask" to setOf(secondChildDokkaTaskInclude) - ), - multiModuleTask.childDokkaTaskIncludes - ) - } - - @Test - fun sourceChildOutputDirectories() { - val parent = ProjectBuilder.builder().build() - parent.plugins.apply("org.jetbrains.dokka") - val child = ProjectBuilder.builder().withName("child").withParent(parent).build() - child.plugins.apply("org.jetbrains.dokka") - - val parentTask = parent.tasks.create("parent") - val childTask = child.tasks.create("child") - - parentTask.addChildTask(childTask) - childTask.outputDirectory.set(child.file("custom/output")) - - assertEquals( - listOf(parent.file("child/custom/output")), - parentTask.sourceChildOutputDirectories.files.toList(), - "Expected child output directory being present" - ) - } - - @Test - fun targetChildOutputDirectories() { - val parent = ProjectBuilder.builder().build() - val child = ProjectBuilder.builder().withName("child").withParent(parent).build() - - val parentTask = parent.tasks.create("parent") - val childTask = child.tasks.create("child") - - parentTask.addChildTask(childTask) - - parentTask.fileLayout.set(DokkaMultiModuleFileLayout { taskParent, taskChild -> - taskParent.project.layout.buildDirectory.dir(taskChild.name) - }) - - assertEquals( - listOf(parent.project.buildDir.resolve("child")), - parentTask.targetChildOutputDirectories.get().map { it.asFile }, - "Expected child target output directory being present" - ) - } -} diff --git a/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/tasks/DokkaTaskTest.kt b/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/tasks/DokkaTaskTest.kt deleted file mode 100644 index d86fa268..00000000 --- a/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/tasks/DokkaTaskTest.kt +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -@file:Suppress("PackageDirectoryMismatch") - -package org.jetbrains.dokka.gradle - -import org.gradle.kotlin.dsl.create -import org.gradle.testfixtures.ProjectBuilder -import org.jetbrains.dokka.gradle.utils.all_ -import org.jetbrains.dokka.gradle.utils.register_ -import org.jetbrains.dokka.gradle.utils.withDependencies_ -import kotlin.test.Test -import kotlin.test.assertEquals -import kotlin.test.assertNull - -class DokkaTaskTest { - @Test - fun `no suppressed source sets are present after in built configuration`() { - val project = ProjectBuilder.builder().build() - project.plugins.apply("org.jetbrains.dokka") - - val task = project.tasks.create("dokkaTask") - project.configurations.all_ { withDependencies_ { clear() } } - - task.dokkaSourceSets.register("main") - task.dokkaSourceSets.register("jvm") - task.dokkaSourceSets.register_("test") { - suppress.set(true) - } - - assertEquals( - listOf("main", "jvm").sorted(), - task.buildDokkaConfiguration().sourceSets.map { it.sourceSetID.sourceSetName }.sorted(), - "Expected only unsuppressed source sets `main` and `test` to be present in built configuration" - ) - } - - @Test - fun `module version is not present if not specified`() { - val project = ProjectBuilder.builder().build() - project.plugins.apply("org.jetbrains.dokka") - - val task = project.tasks.create("dokkaTask") - project.configurations.all_ { withDependencies_ { clear() } } - - task.dokkaSourceSets.register("main") - assertNull(task.buildDokkaConfiguration().moduleVersion) - } -} diff --git a/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/utils/samWithReceiverWorkarounds.kt b/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/utils/samWithReceiverWorkarounds.kt deleted file mode 100644 index 198f189e..00000000 --- a/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/utils/samWithReceiverWorkarounds.kt +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package org.jetbrains.dokka.gradle.utils - -import org.gradle.api.* -import org.gradle.api.artifacts.Configuration -import org.gradle.api.artifacts.DependencySet -import org.jetbrains.dokka.gradle.GradleDokkaSourceSetBuilder -import org.jetbrains.dokka.gradle.GradleExternalDocumentationLinkBuilder - - -/** - * Workarounds because `SamWithReceiver` not working in test sources - * https://youtrack.jetbrains.com/issue/KTIJ-14684 - * - * The `SamWithReceiver` plugin is automatically applied by the `kotlin-dsl` plugin. - * It converts all [org.gradle.api.Action] so the parameter is the receiver: - * - * ``` - * // with SamWithReceiver ✅ - * tasks.configureEach { - * val task: Task = this - * } - * - * // without SamWithReceiver - * tasks.configureEach { it -> - * val task: Task = it - * } - * ``` - * - * This is nice because it means that the Dokka Gradle Plugin more closely matches `build.gradle.kts` files. - * - * However, [IntelliJ is bugged](https://youtrack.jetbrains.com/issue/KTIJ-14684) and doesn't - * acknowledge that `SamWithReceiver` has been applied in test sources. The code works and compiles, - * but IntelliJ shows red errors. - * - * These functions are workarounds, and should be removed ASAP. - */ -@Suppress("unused") -private object Explain - -fun Project.subprojects_(configure: Project.() -> Unit) = - subprojects(configure) - -@Suppress("SpellCheckingInspection") -fun Project.allprojects_(configure: Project.() -> Unit) = - allprojects(configure) - -fun DomainObjectCollection.configureEach_(configure: T.() -> Unit) = - configureEach(configure) - -fun DomainObjectCollection.all_(configure: T.() -> Unit) = - all(configure) - -fun Configuration.withDependencies_(action: DependencySet.() -> Unit): Configuration = - withDependencies(action) - - -fun NamedDomainObjectContainer.create_(name: String, configure: T.() -> Unit): T = - create(name, configure) - -fun NamedDomainObjectContainer.register_( - name: String, - configure: T.() -> Unit -): NamedDomainObjectProvider = - register(name, configure) - - -fun GradleDokkaSourceSetBuilder.externalDocumentationLink_( - action: GradleExternalDocumentationLinkBuilder.() -> Unit -) = externalDocumentationLink(action) -- cgit