aboutsummaryrefslogtreecommitdiff
path: root/plugins/base/src/test/kotlin
diff options
context:
space:
mode:
authorIgnat Beresnev <ignat.beresnev@jetbrains.com>2023-02-10 15:10:05 +0100
committerGitHub <noreply@github.com>2023-02-10 15:10:05 +0100
commite2351ebcb15a745551fef47c707f0e4e65a707cd (patch)
tree6a4ddddce8118f3f8f3ec04abecb4e52c17cb013 /plugins/base/src/test/kotlin
parentf09b149b5bf6834609dec1eb70789539c5e61896 (diff)
downloaddokka-e2351ebcb15a745551fef47c707f0e4e65a707cd.tar.gz
dokka-e2351ebcb15a745551fef47c707f0e4e65a707cd.tar.bz2
dokka-e2351ebcb15a745551fef47c707f0e4e65a707cd.zip
Sort divergent elements deterministically (#2846)
Fixes #2784
Diffstat (limited to 'plugins/base/src/test/kotlin')
-rw-r--r--plugins/base/src/test/kotlin/pageMerger/PageNodeMergerTest.kt320
1 files changed, 273 insertions, 47 deletions
diff --git a/plugins/base/src/test/kotlin/pageMerger/PageNodeMergerTest.kt b/plugins/base/src/test/kotlin/pageMerger/PageNodeMergerTest.kt
index 46b13763..05ff55ee 100644
--- a/plugins/base/src/test/kotlin/pageMerger/PageNodeMergerTest.kt
+++ b/plugins/base/src/test/kotlin/pageMerger/PageNodeMergerTest.kt
@@ -1,52 +1,28 @@
package pageMerger
-import org.jetbrains.dokka.pages.ClasslikePageNode
-import org.jetbrains.dokka.pages.ContentPage
-import org.jetbrains.dokka.pages.PageNode
import org.junit.jupiter.api.Assertions.assertTrue
import org.junit.jupiter.api.Disabled
import org.junit.jupiter.api.Test
import org.jetbrains.dokka.base.testApi.testRunner.BaseAbstractTest
+import org.jetbrains.dokka.model.dfs
+import org.jetbrains.dokka.model.withDescendants
+import org.jetbrains.dokka.pages.*
+import org.junit.jupiter.api.RepeatedTest
+import java.lang.IllegalArgumentException
+import kotlin.test.assertEquals
class PageNodeMergerTest : BaseAbstractTest() {
- /* object SameNameStrategy : DokkaPlugin() {
- val strategy by extending { CoreExtensions.pageMergerStrategy with SameMethodNamePageMergerStrategy }
- }
-
- class DefaultStrategy(val strList: MutableList<String> = mutableListOf()) : DokkaPlugin(), DokkaLogger {
- val strategy by extending { CoreExtensions.pageMergerStrategy with DefaultPageMergerStrategy(this@DefaultStrategy) }
-
- override var warningsCount: Int = 0
- override var errorsCount: Int = 0
-
- override fun debug(message: String) = TODO()
-
- override fun info(message: String) = TODO()
-
- override fun progress(message: String) = TODO()
-
- override fun warn(message: String) {
- strList += message
+ private val defaultConfiguration = dokkaConfiguration {
+ sourceSets {
+ sourceSet {
+ sourceRoots = listOf("src/main/kotlin")
+ }
}
-
- override fun error(message: String) = TODO()
-
- override fun report() = TODO()
}
- */
@Test
fun sameNameStrategyTest() {
-
- val configuration = dokkaConfiguration {
- sourceSets {
- sourceSet {
- sourceRoots = listOf("src/main/kotlin/pageMerger/Test.kt")
- }
- }
- }
-
testInline(
"""
|/src/main/kotlin/pageMerger/Test.kt
@@ -60,8 +36,7 @@ class PageNodeMergerTest : BaseAbstractTest() {
| fun test(str: String): String = str
|}
""".trimMargin(),
- configuration/*,
- pluginOverrides = listOf(SameNameStrategy)*/
+ defaultConfiguration
) {
pagesTransformationStage = {
val allChildren = it.childrenRec().filterIsInstance<ContentPage>()
@@ -82,14 +57,6 @@ class PageNodeMergerTest : BaseAbstractTest() {
fun defaultStrategyTest() {
val strList: MutableList<String> = mutableListOf()
- val configuration = dokkaConfiguration {
- sourceSets {
- sourceSet {
- sourceRoots = listOf("src/main/kotlin/pageMerger/Test.kt")
- }
- }
- }
-
testInline(
"""
|/src/main/kotlin/pageMerger/Test.kt
@@ -103,8 +70,7 @@ class PageNodeMergerTest : BaseAbstractTest() {
| fun test(str: String): String = str
|}
""".trimMargin(),
- configuration/*,
- pluginOverrides = listOf(DefaultStrategy(strList)) */
+ defaultConfiguration
) {
pagesTransformationStage = { root ->
val allChildren = root.childrenRec().filterIsInstance<ContentPage>()
@@ -187,4 +153,264 @@ class PageNodeMergerTest : BaseAbstractTest() {
}
}
}
+
+ @RepeatedTest(3)
+ fun `should deterministically render same name property extensions`() {
+ testInline(
+ """
+ |/src/main/kotlin/test/Test.kt
+ |package test
+ |
+ |class ExtensionReceiver
+ |
+ |/**
+ | * Top level val extension
+ | */
+ |val ExtensionReceiver.foo: String get() = "bar"
+ |
+ |class Obj {
+ | companion object {
+ | /**
+ | * Companion val extension
+ | */
+ | val ExtensionReceiver.foo: String get() = "bar"
+ | }
+ |}
+ |
+ |/src/main/kotlin/test/nestedpackage/Pckg.kt
+ |package test.nestedpackage
+ |
+ |import test.ExtensionReceiver
+ |
+ |/**
+ | * From nested package int val extension
+ | */
+ |val ExtensionReceiver.foo: Int get() = 42
+ """.trimMargin(),
+ defaultConfiguration
+ ) {
+ renderingStage = { rootPageNode, _ ->
+ val extensions = rootPageNode.findExtensionsOfClass("ExtensionReceiver")
+
+ extensions.assertContainsKDocsInOrder(
+ "Top level val extension",
+ "Companion val extension",
+ "From nested package int val extension"
+ )
+ }
+ }
+ }
+
+ @RepeatedTest(3)
+ fun `should deterministically render parameterless same name function extensions`() {
+ testInline(
+ """
+ |/src/main/kotlin/test/Test.kt
+ |package test
+ |
+ |class ExtensionReceiver
+ |
+ |/**
+ | * Top level fun extension
+ | */
+ |fun ExtensionReceiver.bar(): String = "bar"
+ |
+ |class Obj {
+ |
+ | companion object {
+ | /**
+ | * Companion fun extension
+ | */
+ | fun ExtensionReceiver.bar(): String = "bar"
+ | }
+ |}
+ |
+ |/src/main/kotlin/test/nestedpackage/Pckg.kt
+ |package test.nestedpackage
+ |
+ |import test.ExtensionReceiver
+ |
+ |/**
+ | * From nested package fun extension
+ | */
+ |fun ExtensionReceiver.bar(): String = "bar"
+ """.trimMargin(),
+ defaultConfiguration
+ ) {
+ renderingStage = { rootPageNode, _ ->
+ val extensions = rootPageNode.findExtensionsOfClass("ExtensionReceiver")
+ extensions.assertContainsKDocsInOrder(
+ "Top level fun extension",
+ "Companion fun extension",
+ "From nested package fun extension"
+ )
+ }
+ }
+ }
+
+ @RepeatedTest(3)
+ fun `should deterministically render same name function extensions with parameters`() {
+ testInline(
+ """
+ |/src/main/kotlin/test/Test.kt
+ |package test
+ |
+ |class ExtensionReceiver
+ |
+ |/**
+ | * Top level fun extension with one string param
+ | */
+ |fun ExtensionReceiver.bar(one: String): String = "bar"
+ |
+ |/**
+ | * Top level fun extension with one int param
+ | */
+ |fun ExtensionReceiver.bar(one: Int): Int = 42
+ |
+ |class Obj {
+ |
+ | companion object {
+ | /**
+ | * Companion fun extension with two params
+ | */
+ | fun ExtensionReceiver.bar(one: String, two: String): String = "bar"
+ | }
+ |}
+ |
+ |/src/main/kotlin/test/nestedpackage/Pckg.kt
+ |package test.nestedpackage
+ |
+ |import test.ExtensionReceiver
+ |
+ |/**
+ | * From nested package fun extension with two params
+ | */
+ |fun ExtensionReceiver.bar(one: String, two: String): String = "bar"
+ |
+ |/**
+ | * From nested package fun extension with three params
+ | */
+ |fun ExtensionReceiver.bar(one: String, two: String, three: String): String = "bar"
+ |
+ |/**
+ | * From nested package fun extension with four params
+ | */
+ |fun ExtensionReceiver.bar(one: String, two: String, three: String, four: String): String = "bar"
+ """.trimMargin(),
+ defaultConfiguration
+ ) {
+ renderingStage = { rootPageNode, _ ->
+ val extensions = rootPageNode.findExtensionsOfClass("ExtensionReceiver")
+ extensions.assertContainsKDocsInOrder(
+ "Top level fun extension with one int param",
+ "Top level fun extension with one string param",
+ "Companion fun extension with two params",
+ "From nested package fun extension with two params",
+ "From nested package fun extension with three params",
+ "From nested package fun extension with four params"
+ )
+ }
+ }
+ }
+
+ @RepeatedTest(3)
+ fun `should deterministically render same name function extensions with different receiver and return type`() {
+ testInline(
+ """
+ |/src/main/kotlin/test/Test.kt
+ |package test
+ |
+ |/**
+ | * Top level fun extension string
+ | */
+ |fun Int.bar(): String = "bar"
+ |
+ |/**
+ | * Top level fun extension int
+ | */
+ |fun String.bar(): Int = 42
+ """.trimMargin(),
+ defaultConfiguration
+ ) {
+ renderingStage = { rootPageNode, _ ->
+ val packageFunctionBlocks = rootPageNode.findPackageFunctionBlocks(packageName = "test")
+ assertEquals(1, packageFunctionBlocks.size, "Expected to find only one group for the functions")
+
+ val functionsBlock = packageFunctionBlocks[0]
+ functionsBlock.assertContainsKDocsInOrder(
+ "Top level fun extension string",
+ "Top level fun extension int"
+ )
+ }
+ }
+ }
+
+ @Test
+ fun `should not ignore case when grouping by name`() {
+ testInline(
+ """
+ |/src/main/kotlin/test/Test.kt
+ |package test
+ |
+ |/**
+ | * Top level fun bAr
+ | */
+ |fun Int.bAr(): String = "bar"
+ |
+ |/**
+ | * Top level fun BaR
+ | */
+ |fun String.BaR(): Int = 42
+ """.trimMargin(),
+ defaultConfiguration
+ ) {
+ renderingStage = { rootPageNode, _ ->
+ val packageFunctionBlocks = rootPageNode.findPackageFunctionBlocks(packageName = "test")
+ assertEquals(2, packageFunctionBlocks.size, "Expected two separate function groups")
+
+ val firstGroup = packageFunctionBlocks[0]
+ firstGroup.assertContainsKDocsInOrder(
+ "Top level fun BaR",
+ )
+
+ val secondGroup = packageFunctionBlocks[1]
+ secondGroup.assertContainsKDocsInOrder(
+ "Top level fun bAr",
+ )
+ }
+ }
+ }
+
+ private fun RootPageNode.findExtensionsOfClass(name: String): ContentDivergentGroup {
+ val extensionReceiverPage = this.dfs { it is ClasslikePageNode && it.name == name } as ClasslikePageNode
+ return extensionReceiverPage.content
+ .dfs { it is ContentDivergentGroup && it.groupID.name == "Extensions" } as ContentDivergentGroup
+ }
+
+ private fun RootPageNode.findPackageFunctionBlocks(packageName: String): List<ContentDivergentGroup> {
+ val packagePage = this.dfs { it is PackagePage && it.name == packageName } as PackagePage
+ val packageFunctionTable = packagePage.content.dfs {
+ it is ContentTable && it.dci.kind == ContentKind.Functions
+ } as ContentTable
+
+ return packageFunctionTable.children.map { packageGroup ->
+ packageGroup.dfs { it is ContentDivergentGroup } as ContentDivergentGroup
+ }
+ }
+
+ private fun ContentDivergentGroup.assertContainsKDocsInOrder(vararg expectedKDocs: String) {
+ expectedKDocs.forEachIndexed { index, expectedKDoc ->
+ assertEquals(expectedKDoc, this.getElementKDocText(index))
+ }
+ }
+
+ private fun ContentDivergentGroup.getElementKDocText(index: Int): String {
+ val element = this.children.getOrNull(index) ?: throw IllegalArgumentException("No element with index $index")
+ val commentNode = element.after
+ ?.withDescendants()
+ ?.singleOrNull { it is ContentText && it.dci.kind == ContentKind.Comment }
+ ?: throw IllegalStateException("Expected the element to contain a single paragraph of text / comment")
+
+ return (commentNode as ContentText).text
+ }
}