aboutsummaryrefslogtreecommitdiff
path: root/plugins
diff options
context:
space:
mode:
authorAndrzej Ratajczak <andrzej.ratajczak98@gmail.com>2020-07-02 11:33:52 +0200
committerPaweł Marks <Kordyjan@users.noreply.github.com>2020-07-08 11:48:29 +0200
commitf80d5938ccafcf5bd41d73f98bebe2d9699faa95 (patch)
tree8d0df46b4f806bdcc092c2f38af5face44e026bb /plugins
parent5647b4221604a9084194949d9c582a57da920220 (diff)
downloaddokka-f80d5938ccafcf5bd41d73f98bebe2d9699faa95.tar.gz
dokka-f80d5938ccafcf5bd41d73f98bebe2d9699faa95.tar.bz2
dokka-f80d5938ccafcf5bd41d73f98bebe2d9699faa95.zip
Add GFM renderer tests
Diffstat (limited to 'plugins')
-rw-r--r--plugins/base/build.gradle.kts6
-rw-r--r--plugins/base/src/main/kotlin/renderers/DefaultRenderer.kt19
-rw-r--r--plugins/base/src/main/kotlin/renderers/html/HtmlRenderer.kt33
-rw-r--r--plugins/base/src/test/kotlin/renderers/RenderingOnlyTestBase.kt77
-rw-r--r--plugins/base/src/test/kotlin/renderers/defaultSourceSet.kt (renamed from plugins/base/src/test/kotlin/renderers/html/defaultSourceSet.kt)4
-rw-r--r--plugins/base/src/test/kotlin/renderers/html/DivergentTest.kt2
-rw-r--r--plugins/base/src/test/kotlin/renderers/html/GroupWrappingTest.kt2
-rw-r--r--plugins/base/src/test/kotlin/renderers/html/HtmlRenderingOnlyTestBase.kt78
-rw-r--r--plugins/base/src/test/kotlin/renderers/html/SourceSetDependentHintTest.kt6
-rw-r--r--plugins/gfm/build.gradle.kts2
-rw-r--r--plugins/gfm/src/main/kotlin/GfmPlugin.kt70
-rw-r--r--plugins/gfm/src/test/kotlin/renderers/gfm/DivergentTest.kt375
-rw-r--r--plugins/gfm/src/test/kotlin/renderers/gfm/GfmRenderingOnlyTestBase.kt32
-rw-r--r--plugins/gfm/src/test/kotlin/renderers/gfm/GroupWrappingTest.kt77
-rw-r--r--plugins/gfm/src/test/kotlin/renderers/gfm/SourceSetDependentHintTest.kt137
15 files changed, 805 insertions, 115 deletions
diff --git a/plugins/base/build.gradle.kts b/plugins/base/build.gradle.kts
index 02babd4d..08d1054a 100644
--- a/plugins/base/build.gradle.kts
+++ b/plugins/base/build.gradle.kts
@@ -4,6 +4,8 @@ plugins {
id("com.jfrog.bintray")
}
+val testUtils by configurations.creating
+
dependencies {
val coroutines_version: String by project
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutines_version")
@@ -12,6 +14,8 @@ dependencies {
implementation("org.jsoup:jsoup:1.12.1")
implementation("org.jetbrains.kotlinx:kotlinx-html-jvm:0.6.10")
testImplementation(project(":test-tools"))
+
+ testUtils(sourceSets.test.get().output)
}
task("copy_frontend", Copy::class) {
@@ -38,4 +42,4 @@ publishing {
}
}
-configureBintrayPublication("basePlugin")
+configureBintrayPublication("basePlugin") \ No newline at end of file
diff --git a/plugins/base/src/main/kotlin/renderers/DefaultRenderer.kt b/plugins/base/src/main/kotlin/renderers/DefaultRenderer.kt
index f2fce191..57a3d8d1 100644
--- a/plugins/base/src/main/kotlin/renderers/DefaultRenderer.kt
+++ b/plugins/base/src/main/kotlin/renderers/DefaultRenderer.kt
@@ -170,6 +170,23 @@ abstract class DefaultRenderer<T>(
renderPages(newRoot)
}
}
+
+ protected fun ContentDivergentGroup.groupDivergentInstances(
+ pageContext: ContentPage,
+ beforeTransformer: (ContentDivergentInstance, ContentPage, DokkaSourceSet) -> String,
+ afterTransformer: (ContentDivergentInstance, ContentPage, DokkaSourceSet) -> String
+ ): Map<Pair<String, String>, List<Pair<ContentDivergentInstance, DokkaSourceSet>>> =
+ children.flatMap { instance ->
+ instance.sourceSets.map { sourceSet ->
+ Pair(instance, sourceSet) to Pair(
+ beforeTransformer(instance, pageContext, sourceSet),
+ afterTransformer(instance, pageContext, sourceSet)
+ )
+ }
+ }.groupBy(
+ Pair<Pair<ContentDivergentInstance, DokkaSourceSet>, Pair<String, String>>::second,
+ Pair<Pair<ContentDivergentInstance, DokkaSourceSet>, Pair<String, String>>::first
+ )
}
-fun ContentPage.sourceSets() = this.content.sourceSets
+fun ContentPage.sourceSets() = this.content.sourceSets \ No newline at end of file
diff --git a/plugins/base/src/main/kotlin/renderers/html/HtmlRenderer.kt b/plugins/base/src/main/kotlin/renderers/html/HtmlRenderer.kt
index a950667f..595dc8d2 100644
--- a/plugins/base/src/main/kotlin/renderers/html/HtmlRenderer.kt
+++ b/plugins/base/src/main/kotlin/renderers/html/HtmlRenderer.kt
@@ -222,26 +222,21 @@ open class HtmlRenderer(
}
override fun FlowContent.buildDivergent(node: ContentDivergentGroup, pageContext: ContentPage) {
+
val distinct =
- node.children.flatMap { instance ->
- instance.sourceSets.map { sourceSet ->
- Pair(instance, sourceSet) to Pair(
- createHTML(prettyPrint = false).div {
- instance.before?.let { before ->
- buildContentNode(before, pageContext, setOf(sourceSet))
- }
- }.stripDiv(),
- createHTML(prettyPrint = false).div {
- instance.after?.let { after ->
- buildContentNode(after, pageContext, setOf(sourceSet))
- }
- }.stripDiv()
- )
- }
- }.groupBy(
- Pair<Pair<ContentDivergentInstance, DokkaSourceSet>, Pair<String, String>>::second,
- Pair<Pair<ContentDivergentInstance, DokkaSourceSet>, Pair<String, String>>::first
- )
+ node.groupDivergentInstances(pageContext, { instance, contentPage, sourceSet ->
+ createHTML(prettyPrint = false).div {
+ instance.before?.let { before ->
+ buildContentNode(before, pageContext, setOf(sourceSet))
+ }
+ }.stripDiv()
+ }, { instance, contentPage, sourceSet ->
+ createHTML(prettyPrint = false).div {
+ instance.after?.let { after ->
+ buildContentNode(after, pageContext, setOf(sourceSet))
+ }
+ }.stripDiv()
+ })
distinct.forEach {
val groupedDivergent = it.value.groupBy { it.second }
diff --git a/plugins/base/src/test/kotlin/renderers/RenderingOnlyTestBase.kt b/plugins/base/src/test/kotlin/renderers/RenderingOnlyTestBase.kt
index 21a70802..8e58bbcd 100644
--- a/plugins/base/src/test/kotlin/renderers/RenderingOnlyTestBase.kt
+++ b/plugins/base/src/test/kotlin/renderers/RenderingOnlyTestBase.kt
@@ -1,50 +1,19 @@
package renderers
-import org.jetbrains.dokka.DokkaConfiguration.DokkaSourceSet
-import org.jetbrains.dokka.DokkaConfigurationImpl
-import org.jetbrains.dokka.base.DokkaBase
-import org.jetbrains.dokka.base.renderers.RootCreator
-import org.jetbrains.dokka.base.resolvers.external.DokkaExternalLocationProviderFactory
-import org.jetbrains.dokka.base.resolvers.external.JavadocExternalLocationProviderFactory
-import org.jetbrains.dokka.base.resolvers.local.DefaultLocationProviderFactory
import org.jetbrains.dokka.base.signatures.KotlinSignatureProvider
-import org.jetbrains.dokka.base.transformers.pages.comments.CommentsToContentConverter
import org.jetbrains.dokka.base.translators.documentables.PageContentBuilder
import org.jetbrains.dokka.links.DRI
import org.jetbrains.dokka.model.Documentable
-import org.jetbrains.dokka.model.doc.DocTag
-import org.jetbrains.dokka.model.properties.PropertyContainer
-import org.jetbrains.dokka.pages.*
+import org.jetbrains.dokka.pages.ContentNode
+import org.jetbrains.dokka.pages.ContentPage
+import org.jetbrains.dokka.pages.PageNode
+import org.jetbrains.dokka.pages.RootPageNode
import org.jetbrains.dokka.testApi.context.MockContext
import org.jetbrains.dokka.utilities.DokkaConsoleLogger
-import org.jsoup.Jsoup
-import org.jsoup.nodes.Element
-import org.jsoup.nodes.Node
-import org.jsoup.nodes.TextNode
-import utils.TestOutputWriter
+import renderers.html.EmptyCommentConverter
abstract class RenderingOnlyTestBase {
- val files = TestOutputWriter()
- val context = MockContext(
- DokkaBase().outputWriter to { _ -> files },
- DokkaBase().locationProviderFactory to ::DefaultLocationProviderFactory,
- DokkaBase().htmlPreprocessors to { _ -> RootCreator },
- DokkaBase().externalLocationProviderFactory to { ::JavadocExternalLocationProviderFactory },
- DokkaBase().externalLocationProviderFactory to { ::DokkaExternalLocationProviderFactory },
- testConfiguration = DokkaConfigurationImpl(
- "", "", null, false, emptyList(), emptyList(), emptyMap(), emptyList(), false
- )
- )
-
- protected val renderedContent: Element by lazy {
- files.contents.getValue("test-page.html").let { Jsoup.parse(it) }.select("#content").single()
- }
-
- protected fun linesAfterContentTag() =
- files.contents.getValue("test-page.html").lines()
- .dropWhile { !it.contains("""<div id="content">""") }
- .joinToString(separator = "") { it.trim() }
-
+ abstract val context: MockContext
}
class TestPage(callback: PageContentBuilder.DocumentableContentBuilder.() -> Unit) : RootPageNode(), ContentPage {
@@ -76,37 +45,3 @@ class TestPage(callback: PageContentBuilder.DocumentableContentBuilder.() -> Uni
override fun modified(name: String, children: List<PageNode>) = this
}
-
-fun Element.match(vararg matchers: Any): Unit =
- childNodes()
- .filter { it !is TextNode || it.text().isNotBlank() }
- .let { it.drop(it.size - matchers.size) }
- .zip(matchers)
- .forEach { (n, m) -> m.accepts(n) }
-
-open class Tag(val name: String, vararg val matchers: Any)
-class Div(vararg matchers: Any) : Tag("div", *matchers)
-class P(vararg matchers: Any) : Tag("p", *matchers)
-class Span(vararg matchers: Any) : Tag("span", *matchers)
-
-private fun Any.accepts(n: Node) {
- when (this) {
- is String -> assert(n is TextNode && n.text().trim() == this.trim()) { "\"$this\" expected but found: $n" }
- is Tag -> {
- assert(n is Element && n.tagName() == name) { "Tag $name expected but found: $n" }
- if (n is Element && matchers.isNotEmpty()) n.match(*matchers)
- }
- else -> throw IllegalArgumentException("$this is not proper matcher")
- }
-}
-
-
-internal object EmptyCommentConverter : CommentsToContentConverter {
- override fun buildContent(
- docTag: DocTag,
- dci: DCI,
- sourceSets: Set<DokkaSourceSet>,
- styles: Set<Style>,
- extras: PropertyContainer<ContentNode>
- ): List<ContentNode> = emptyList()
-} \ No newline at end of file
diff --git a/plugins/base/src/test/kotlin/renderers/html/defaultSourceSet.kt b/plugins/base/src/test/kotlin/renderers/defaultSourceSet.kt
index a9be1cfd..7358d2c2 100644
--- a/plugins/base/src/test/kotlin/renderers/html/defaultSourceSet.kt
+++ b/plugins/base/src/test/kotlin/renderers/defaultSourceSet.kt
@@ -1,10 +1,10 @@
-package renderers.html
+package renderers
import org.jetbrains.dokka.DokkaSourceSetID
import org.jetbrains.dokka.DokkaSourceSetImpl
import org.jetbrains.dokka.Platform
-internal val defaultSourceSet = DokkaSourceSetImpl(
+val defaultSourceSet = DokkaSourceSetImpl(
moduleDisplayName = "DEFAULT",
displayName = "DEFAULT",
sourceSetID = DokkaSourceSetID("DEFAULT", "DEFAULT"),
diff --git a/plugins/base/src/test/kotlin/renderers/html/DivergentTest.kt b/plugins/base/src/test/kotlin/renderers/html/DivergentTest.kt
index d4778a8e..f5565b48 100644
--- a/plugins/base/src/test/kotlin/renderers/html/DivergentTest.kt
+++ b/plugins/base/src/test/kotlin/renderers/html/DivergentTest.kt
@@ -8,7 +8,7 @@ import org.jetbrains.dokka.pages.ContentDivergentGroup
import org.junit.jupiter.api.Test
import renderers.*
-class DivergentTest : RenderingOnlyTestBase() {
+class DivergentTest : HtmlRenderingOnlyTestBase() {
private val js = defaultSourceSet.copy(
"root",
"JS",
diff --git a/plugins/base/src/test/kotlin/renderers/html/GroupWrappingTest.kt b/plugins/base/src/test/kotlin/renderers/html/GroupWrappingTest.kt
index 43eccae6..59150e18 100644
--- a/plugins/base/src/test/kotlin/renderers/html/GroupWrappingTest.kt
+++ b/plugins/base/src/test/kotlin/renderers/html/GroupWrappingTest.kt
@@ -5,7 +5,7 @@ import org.jetbrains.dokka.pages.TextStyle
import org.junit.jupiter.api.Test
import renderers.*
-class GroupWrappingTest: RenderingOnlyTestBase() {
+class GroupWrappingTest : HtmlRenderingOnlyTestBase() {
@Test
fun notWrapped() {
diff --git a/plugins/base/src/test/kotlin/renderers/html/HtmlRenderingOnlyTestBase.kt b/plugins/base/src/test/kotlin/renderers/html/HtmlRenderingOnlyTestBase.kt
new file mode 100644
index 00000000..69025947
--- /dev/null
+++ b/plugins/base/src/test/kotlin/renderers/html/HtmlRenderingOnlyTestBase.kt
@@ -0,0 +1,78 @@
+package renderers.html
+
+import org.jetbrains.dokka.DokkaConfiguration
+import org.jetbrains.dokka.DokkaConfigurationImpl
+import org.jetbrains.dokka.base.DokkaBase
+import org.jetbrains.dokka.base.renderers.RootCreator
+import org.jetbrains.dokka.base.resolvers.external.DokkaExternalLocationProviderFactory
+import org.jetbrains.dokka.base.resolvers.external.JavadocExternalLocationProviderFactory
+import org.jetbrains.dokka.base.resolvers.local.DefaultLocationProviderFactory
+import org.jetbrains.dokka.base.transformers.pages.comments.CommentsToContentConverter
+import org.jetbrains.dokka.model.doc.DocTag
+import org.jetbrains.dokka.model.properties.PropertyContainer
+import org.jetbrains.dokka.pages.*
+import org.jetbrains.dokka.testApi.context.MockContext
+import org.jsoup.Jsoup
+import org.jsoup.nodes.Element
+import org.jsoup.nodes.Node
+import org.jsoup.nodes.TextNode
+import renderers.RenderingOnlyTestBase
+import utils.TestOutputWriter
+
+abstract class HtmlRenderingOnlyTestBase : RenderingOnlyTestBase() {
+
+ val files = TestOutputWriter()
+ override val context = MockContext(
+ DokkaBase().outputWriter to { _ -> files },
+ DokkaBase().locationProviderFactory to ::DefaultLocationProviderFactory,
+ DokkaBase().htmlPreprocessors to { _ -> RootCreator },
+ DokkaBase().externalLocationProviderFactory to { ::JavadocExternalLocationProviderFactory },
+ DokkaBase().externalLocationProviderFactory to { ::DokkaExternalLocationProviderFactory },
+ testConfiguration = DokkaConfigurationImpl(
+ "", "", null, false, emptyList(), emptyList(), emptyMap(), emptyList(), false
+ )
+ )
+
+ protected val renderedContent: Element by lazy {
+ files.contents.getValue("test-page.html").let { Jsoup.parse(it) }.select("#content").single()
+ }
+
+ protected fun linesAfterContentTag() =
+ files.contents.getValue("test-page.html").lines()
+ .dropWhile { !it.contains("""<div id="content">""") }
+ .joinToString(separator = "") { it.trim() }
+}
+
+fun Element.match(vararg matchers: Any): Unit =
+ childNodes()
+ .filter { it !is TextNode || it.text().isNotBlank() }
+ .let { it.drop(it.size - matchers.size) }
+ .zip(matchers)
+ .forEach { (n, m) -> m.accepts(n) }
+
+open class Tag(val name: String, vararg val matchers: Any)
+class Div(vararg matchers: Any) : Tag("div", *matchers)
+class P(vararg matchers: Any) : Tag("p", *matchers)
+class Span(vararg matchers: Any) : Tag("span", *matchers)
+
+private fun Any.accepts(n: Node) {
+ when (this) {
+ is String -> assert(n is TextNode && n.text().trim() == this.trim()) { "\"$this\" expected but found: $n" }
+ is Tag -> {
+ assert(n is Element && n.tagName() == name) { "Tag $name expected but found: $n" }
+ if (n is Element && matchers.isNotEmpty()) n.match(*matchers)
+ }
+ else -> throw IllegalArgumentException("$this is not proper matcher")
+ }
+}
+
+
+internal object EmptyCommentConverter : CommentsToContentConverter {
+ override fun buildContent(
+ docTag: DocTag,
+ dci: DCI,
+ sourceSets: Set<DokkaConfiguration.DokkaSourceSet>,
+ styles: Set<Style>,
+ extras: PropertyContainer<ContentNode>
+ ): List<ContentNode> = emptyList()
+} \ No newline at end of file
diff --git a/plugins/base/src/test/kotlin/renderers/html/SourceSetDependentHintTest.kt b/plugins/base/src/test/kotlin/renderers/html/SourceSetDependentHintTest.kt
index ea1ea9ae..87c67842 100644
--- a/plugins/base/src/test/kotlin/renderers/html/SourceSetDependentHintTest.kt
+++ b/plugins/base/src/test/kotlin/renderers/html/SourceSetDependentHintTest.kt
@@ -5,12 +5,10 @@ import org.jetbrains.dokka.SourceRootImpl
import org.jetbrains.dokka.base.renderers.html.HtmlRenderer
import org.jetbrains.dokka.pages.TextStyle
import org.junit.jupiter.api.Test
-import renderers.Div
-import renderers.RenderingOnlyTestBase
import renderers.TestPage
-import renderers.match
+import renderers.defaultSourceSet
-class SourceSetDependentHintTest : RenderingOnlyTestBase() {
+class SourceSetDependentHintTest : HtmlRenderingOnlyTestBase() {
private val pl1 = defaultSourceSet.copy(
"root",
diff --git a/plugins/gfm/build.gradle.kts b/plugins/gfm/build.gradle.kts
index ffa12cba..7bea1b97 100644
--- a/plugins/gfm/build.gradle.kts
+++ b/plugins/gfm/build.gradle.kts
@@ -9,4 +9,6 @@ publishing {
dependencies {
compileOnly(project(":plugins:base"))
+ testImplementation(project(":plugins:base"))
+ testImplementation(project(":plugins:base", configuration = "testUtils"))
}
diff --git a/plugins/gfm/src/main/kotlin/GfmPlugin.kt b/plugins/gfm/src/main/kotlin/GfmPlugin.kt
index 32c0b7b7..7db06bb2 100644
--- a/plugins/gfm/src/main/kotlin/GfmPlugin.kt
+++ b/plugins/gfm/src/main/kotlin/GfmPlugin.kt
@@ -62,6 +62,11 @@ open class CommonmarkRenderer(
childrenCallback()
buildNewLine()
}
+ node.hasStyle(TextStyle.Paragraph) -> {
+ buildParagraph()
+ childrenCallback()
+ buildParagraph()
+ }
else -> childrenCallback()
}
}
@@ -74,9 +79,9 @@ open class CommonmarkRenderer(
}
override fun StringBuilder.buildLink(address: String, content: StringBuilder.() -> Unit) {
- append("""<a href="$address">""")
+ append("[")
content()
- append("</a>")
+ append("]($address)")
}
override fun StringBuilder.buildList(
@@ -136,7 +141,7 @@ open class CommonmarkRenderer(
buildContentNode(content, pageContext)
} else {
val distinct = sourceSets.map {
- it to StringBuilder().apply { buildContentNode(content, pageContext, setOf(it)) }.toString()
+ it to buildString { buildContentNode(content, pageContext, setOf(it)) }
}.groupBy(Pair<DokkaSourceSet, String>::second, Pair<DokkaSourceSet, String>::first)
distinct.filter { it.key.isNotBlank() }.forEach { (text, platforms) ->
@@ -222,28 +227,61 @@ open class CommonmarkRenderer(
}
override fun buildPage(page: ContentPage, content: (StringBuilder, ContentPage) -> Unit): String =
- StringBuilder().apply {
+ buildString {
content(this, page)
- }.toString()
+ }
override fun buildError(node: ContentNode) {
context.logger.warn("Markdown renderer has encountered problem. The unmatched node is $node")
}
- override fun StringBuilder.buildDivergentInstance(node: ContentDivergentInstance, pageContext: ContentPage) {
- node.before?.let {
- buildPlatformDependentItem(it, it.sourceSets, pageContext)
+ override fun StringBuilder.buildDivergent(node: ContentDivergentGroup, pageContext: ContentPage) {
+
+ val distinct =
+ node.groupDivergentInstances(pageContext, { instance, contentPage, sourceSet ->
+ instance.before?.let { before ->
+ buildString { buildContentNode(before, pageContext, setOf(sourceSet)) }
+ } ?: ""
+ }, { instance, contentPage, sourceSet ->
+ instance.after?.let { after ->
+ buildString { buildContentNode(after, pageContext, setOf(sourceSet)) }
+ } ?: ""
+ })
+
+ distinct.values.forEach { entry ->
+ val (instance, sourceSets) = entry.getInstanceAndSourceSets()
+
+ append(sourceSets.joinToString(prefix = "#### [", postfix = "]") { "${it.moduleName}/${it.sourceSetID}" })
buildNewLine()
- }
- node.divergent.build(this, pageContext)
- buildNewLine()
- node.after?.let {
- buildPlatformDependentItem(it, it.sourceSets, pageContext)
+ instance.before?.let {
+ append("##### Brief description")
+ buildNewLine()
+ buildContentNode(it, pageContext)
+ buildNewLine()
+ }
+
+ append("##### Content")
buildNewLine()
+ entry.groupBy { buildString { buildContentNode(it.first.divergent, pageContext, setOf(it.second)) } }
+ .values.forEach { innerEntry ->
+ val (innerInstance, innerSourceSets) = innerEntry.getInstanceAndSourceSets()
+ if(sourceSets.size > 1) {
+ append(innerSourceSets.joinToString(prefix = "###### [", postfix = "]") { "${it.moduleName}/${it.sourceSetID}" })
+ buildNewLine()
+ }
+ innerInstance.divergent.build(this@buildDivergent, pageContext)
+ buildNewLine()
+ }
+ instance.after?.let {
+ append("##### More info")
+ buildNewLine()
+ buildContentNode(it, pageContext)
+ buildNewLine()
+ }
}
}
- private fun decorators(styles: Set<Style>) = StringBuilder().apply {
+ private fun decorators(styles: Set<Style>) = buildString {
styles.forEach {
when (it) {
TextStyle.Bold -> append("**")
@@ -253,7 +291,7 @@ open class CommonmarkRenderer(
else -> Unit
}
}
- }.toString()
+ }
private val PageNode.isNavigable: Boolean
get() = this !is RendererSpecificPage || strategy != RenderingStrategy.DoNothing
@@ -280,6 +318,8 @@ open class CommonmarkRenderer(
}
private fun String.withEntersAsHtml(): String = replace("\n", "<br>")
+
+ private fun List<Pair<ContentDivergentInstance, DokkaSourceSet>>.getInstanceAndSourceSets() = this.let { Pair(it.first().first, it.map { it.second }.toSet()) }
}
class MarkdownLocationProviderFactory(val context: DokkaContext) : LocationProviderFactory {
diff --git a/plugins/gfm/src/test/kotlin/renderers/gfm/DivergentTest.kt b/plugins/gfm/src/test/kotlin/renderers/gfm/DivergentTest.kt
new file mode 100644
index 00000000..13231c43
--- /dev/null
+++ b/plugins/gfm/src/test/kotlin/renderers/gfm/DivergentTest.kt
@@ -0,0 +1,375 @@
+package renderers.gfm
+
+import org.jetbrains.dokka.Platform
+import org.jetbrains.dokka.SourceRootImpl
+import org.jetbrains.dokka.gfm.CommonmarkRenderer
+import org.jetbrains.dokka.links.DRI
+import org.jetbrains.dokka.pages.ContentDivergentGroup
+import org.junit.jupiter.api.Test
+import renderers.gfm.GfmRenderingOnlyTestBase
+import renderers.defaultSourceSet
+import renderers.TestPage
+
+class DivergentTest : GfmRenderingOnlyTestBase() {
+ private val js = defaultSourceSet.copy(
+ "root",
+ "JS",
+ "js",
+ analysisPlatform = Platform.js,
+ sourceRoots = listOf(SourceRootImpl("pl1"))
+ )
+ private val jvm = defaultSourceSet.copy(
+ "root",
+ "JVM",
+ "jvm",
+
+ analysisPlatform = Platform.jvm,
+ sourceRoots = listOf(SourceRootImpl("pl1"))
+ )
+ private val native = defaultSourceSet.copy(
+ "root",
+ "NATIVE",
+ "native",
+ analysisPlatform = Platform.native,
+ sourceRoots = listOf(SourceRootImpl("pl1"))
+ )
+
+ @Test
+ fun simpleWrappingCase() {
+ val page = TestPage {
+ divergentGroup(ContentDivergentGroup.GroupID("test")) {
+ instance(setOf(DRI("test", "Test")), setOf(js)) {
+ divergent {
+ text("a")
+ }
+ }
+ }
+ }
+ val expect = "//[testPage](test-page.md)\n\n#### [root/js] \n##### Content \na \n"
+ CommonmarkRenderer(context).render(page)
+ assert(renderedContent == expect)
+ }
+
+ @Test
+ fun noPlatformHintCase() {
+ val page = TestPage {
+ divergentGroup(ContentDivergentGroup.GroupID("test"), implicitlySourceSetHinted = false) {
+ instance(setOf(DRI("test", "Test")), setOf(js)) {
+ divergent {
+ text("a")
+ }
+ }
+ }
+ }
+ val expect = "//[testPage](test-page.md)\n\n#### [root/js] \n##### Content \na \n"
+ CommonmarkRenderer(context).render(page)
+ assert(renderedContent == expect)
+ }
+
+ @Test
+ fun divergentBetweenSourceSets() {
+ val page = TestPage {
+ divergentGroup(ContentDivergentGroup.GroupID("test")) {
+ instance(setOf(DRI("test", "Test")), setOf(js)) {
+ divergent {
+ text("a")
+ }
+ }
+ instance(setOf(DRI("test", "Test")), setOf(jvm)) {
+ divergent {
+ text("b")
+ }
+ }
+ instance(setOf(DRI("test", "Test")), setOf(native)) {
+ divergent {
+ text("c")
+ }
+ }
+ }
+ }
+ val expect = "//[testPage](test-page.md)\n\n#### [root/js, root/jvm, root/native] \n##### Content \n###### [root/js] \na \n###### [root/jvm] \nb \n###### [root/native] \nc \n"
+ CommonmarkRenderer(context).render(page)
+ assert(renderedContent == expect)
+ }
+
+ @Test
+ fun divergentInOneSourceSet() {
+ val page = TestPage {
+ divergentGroup(ContentDivergentGroup.GroupID("test")) {
+ instance(setOf(DRI("test", "Test")), setOf(js)) {
+ divergent {
+ text("a")
+ }
+ }
+ instance(setOf(DRI("test", "Test2")), setOf(js)) {
+ divergent {
+ text("b")
+ }
+ }
+ instance(setOf(DRI("test", "Test3")), setOf(js)) {
+ divergent {
+ text("c")
+ }
+ }
+ }
+ }
+ val expect = "//[testPage](test-page.md)\n\n#### [root/js] \n##### Content \na \nb \nc \n"
+ CommonmarkRenderer(context).render(page)
+ assert(renderedContent == expect)
+ }
+
+ @Test
+ fun divergentInAndBetweenSourceSets() {
+ val page = TestPage {
+ divergentGroup(ContentDivergentGroup.GroupID("test")) {
+ instance(setOf(DRI("test", "Test")), setOf(native)) {
+ divergent {
+ text("a")
+ }
+ }
+ instance(setOf(DRI("test", "Test")), setOf(js)) {
+ divergent {
+ text("b")
+ }
+ }
+ instance(setOf(DRI("test", "Test")), setOf(jvm)) {
+ divergent {
+ text("c")
+ }
+ }
+ instance(setOf(DRI("test", "Test2")), setOf(js)) {
+ divergent {
+ text("d")
+ }
+ }
+ instance(setOf(DRI("test", "Test3")), setOf(native)) {
+ divergent {
+ text("e")
+ }
+ }
+ }
+ }
+ val expect = "//[testPage](test-page.md)\n\n#### [root/native, root/js, root/jvm] \n##### Content \n###### [root/native] \na \n###### [root/js] \nb \n###### [root/jvm] \nc \n###### [root/js] \nd \n###### [root/native] \ne \n"
+ CommonmarkRenderer(context).render(page)
+ assert(renderedContent == expect)
+ }
+
+ @Test
+ fun divergentInAndBetweenSourceSetsWithGrouping() {
+ val page = TestPage {
+ divergentGroup(ContentDivergentGroup.GroupID("test")) {
+ instance(setOf(DRI("test", "Test")), setOf(native)) {
+ divergent {
+ text("a")
+ }
+ after {
+ text("a+")
+ }
+ }
+ instance(setOf(DRI("test", "Test")), setOf(js)) {
+ divergent {
+ text("b")
+ }
+ after {
+ text("bd+")
+ }
+ }
+ instance(setOf(DRI("test", "Test")), setOf(jvm)) {
+ divergent {
+ text("c")
+ }
+ }
+ instance(setOf(DRI("test", "Test2")), setOf(js)) {
+ divergent {
+ text("d")
+ }
+ after {
+ text("bd+")
+ }
+ }
+ instance(setOf(DRI("test", "Test3")), setOf(native)) {
+ divergent {
+ text("e")
+ }
+ after {
+ text("e+")
+ }
+ }
+ }
+ }
+ val expect = "//[testPage](test-page.md)\n\n#### [root/native] \n##### Content \na \n##### More info \na+ \n#### [root/js] \n##### Content \nb \nd \n##### More info \nbd+ \n#### [root/jvm] \n##### Content \nc \n#### [root/native] \n##### Content \ne \n##### More info \ne+ \n"
+ CommonmarkRenderer(context).render(page)
+ assert(renderedContent == expect)
+ }
+
+ @Test
+ fun divergentSameBefore() {
+ val page = TestPage {
+ divergentGroup(ContentDivergentGroup.GroupID("test")) {
+ instance(setOf(DRI("test", "Test")), setOf(native)) {
+ before {
+ text("ab-")
+ }
+ divergent {
+ text("a")
+ }
+ }
+ instance(setOf(DRI("test", "Test2")), setOf(native)) {
+ before {
+ text("ab-")
+ }
+ divergent {
+ text("b")
+ }
+ }
+ }
+ }
+ val expect = "//[testPage](test-page.md)\n\n#### [root/native] \n##### Brief description \nab- \n##### Content \na \nb \n"
+ CommonmarkRenderer(context).render(page)
+ assert(renderedContent == expect)
+ }
+
+ @Test
+ fun divergentSameAfter() {
+ val page = TestPage {
+ divergentGroup(ContentDivergentGroup.GroupID("test")) {
+ instance(setOf(DRI("test", "Test")), setOf(native)) {
+ divergent {
+ text("a")
+ }
+ after {
+ text("ab+")
+ }
+ }
+ instance(setOf(DRI("test", "Test2")), setOf(native)) {
+ divergent {
+ text("b")
+ }
+ after {
+ text("ab+")
+ }
+ }
+ }
+ }
+ val expect = "//[testPage](test-page.md)\n\n#### [root/native] \n##### Content \na \nb \n##### More info \nab+ \n"
+ CommonmarkRenderer(context).render(page)
+ assert(renderedContent == expect)
+ }
+
+ @Test
+ fun divergentGroupedByBeforeAndAfter() {
+ val page = TestPage {
+ divergentGroup(ContentDivergentGroup.GroupID("test")) {
+ instance(setOf(DRI("test", "Test")), setOf(native)) {
+ before {
+ text("ab-")
+ }
+ divergent {
+ text("a")
+ }
+ after {
+ text("ab+")
+ }
+ }
+ instance(setOf(DRI("test", "Test2")), setOf(native)) {
+ before {
+ text("ab-")
+ }
+ divergent {
+ text("b")
+ }
+ after {
+ text("ab+")
+ }
+ }
+ }
+ }
+ val expect = "//[testPage](test-page.md)\n\n#### [root/native] \n##### Brief description \nab- \n##### Content \na \nb \n##### More info \nab+ \n"
+ CommonmarkRenderer(context).render(page)
+ assert(renderedContent == expect)
+ }
+
+ @Test
+ fun divergentDifferentBeforeAndAfter() {
+ val page = TestPage {
+ divergentGroup(ContentDivergentGroup.GroupID("test")) {
+ instance(setOf(DRI("test", "Test")), setOf(native)) {
+ before {
+ text("a-")
+ }
+ divergent {
+ text("a")
+ }
+ after {
+ text("ab+")
+ }
+ }
+ instance(setOf(DRI("test", "Test2")), setOf(native)) {
+ before {
+ text("b-")
+ }
+ divergent {
+ text("b")
+ }
+ after {
+ text("ab+")
+ }
+ }
+ }
+ }
+ val expect = "//[testPage](test-page.md)\n\n#### [root/native] \n##### Brief description \na- \n##### Content \na \n##### More info \nab+ \n#### [root/native] \n##### Brief description \nb- \n##### Content \nb \n##### More info \nab+ \n"
+ CommonmarkRenderer(context).render(page)
+ assert(renderedContent == expect)
+ }
+
+ @Test
+ fun divergentInAndBetweenSourceSetsWithGroupingAncCommonParts() {
+ val page = TestPage {
+ divergentGroup(ContentDivergentGroup.GroupID("test")) {
+ instance(setOf(DRI("test", "Test")), setOf(native)) {
+ divergent {
+ text("a")
+ }
+ after {
+ text("a+")
+ }
+ }
+ instance(setOf(DRI("test", "Test")), setOf(js)) {
+ divergent {
+ text("b")
+ }
+ after {
+ text("bd+")
+ }
+ }
+ instance(setOf(DRI("test", "Test")), setOf(jvm)) {
+ divergent {
+ text("c")
+ }
+ after {
+ text("bd+")
+ }
+ }
+ instance(setOf(DRI("test", "Test2")), setOf(js)) {
+ divergent {
+ text("d")
+ }
+ after {
+ text("bd+")
+ }
+ }
+ instance(setOf(DRI("test", "Test3")), setOf(native)) {
+ divergent {
+ text("e")
+ }
+ after {
+ text("e+")
+ }
+ }
+ }
+ }
+ val expect = "//[testPage](test-page.md)\n\n#### [root/native] \n##### Content \na \n##### More info \na+ \n#### [root/js, root/jvm] \n##### Content \n###### [root/js] \nb \n###### [root/jvm] \nc \n###### [root/js] \nd \n##### More info \nbd+ \n#### [root/native] \n##### Content \ne \n##### More info \ne+ \n"
+ CommonmarkRenderer(context).render(page)
+ assert(renderedContent == expect)
+ }
+} \ No newline at end of file
diff --git a/plugins/gfm/src/test/kotlin/renderers/gfm/GfmRenderingOnlyTestBase.kt b/plugins/gfm/src/test/kotlin/renderers/gfm/GfmRenderingOnlyTestBase.kt
new file mode 100644
index 00000000..3636bf26
--- /dev/null
+++ b/plugins/gfm/src/test/kotlin/renderers/gfm/GfmRenderingOnlyTestBase.kt
@@ -0,0 +1,32 @@
+package renderers.gfm
+
+import org.jetbrains.dokka.DokkaConfigurationImpl
+import org.jetbrains.dokka.gfm.GfmPlugin
+import org.jetbrains.dokka.gfm.MarkdownLocationProviderFactory
+import org.jetbrains.dokka.testApi.context.MockContext
+import org.jetbrains.dokka.base.DokkaBase
+import org.jetbrains.dokka.base.renderers.RootCreator
+import org.jetbrains.dokka.base.resolvers.external.DokkaExternalLocationProviderFactory
+import org.jetbrains.dokka.base.resolvers.external.JavadocExternalLocationProviderFactory
+import renderers.RenderingOnlyTestBase
+import utils.TestOutputWriter
+
+abstract class GfmRenderingOnlyTestBase : RenderingOnlyTestBase() {
+
+ val files = TestOutputWriter()
+ override val context = MockContext(
+ DokkaBase().outputWriter to { _ -> files },
+ DokkaBase().locationProviderFactory to ::MarkdownLocationProviderFactory,
+ DokkaBase().externalLocationProviderFactory to { ::JavadocExternalLocationProviderFactory },
+ DokkaBase().externalLocationProviderFactory to { ::DokkaExternalLocationProviderFactory },
+ GfmPlugin().gfmPreprocessors to { _ -> RootCreator },
+
+ testConfiguration = DokkaConfigurationImpl(
+ "", "", null, false, emptyList(), emptyList(), emptyMap(), emptyList(), false
+ )
+ )
+
+ protected val renderedContent: String by lazy {
+ files.contents.getValue("test-page.md")
+ }
+} \ No newline at end of file
diff --git a/plugins/gfm/src/test/kotlin/renderers/gfm/GroupWrappingTest.kt b/plugins/gfm/src/test/kotlin/renderers/gfm/GroupWrappingTest.kt
new file mode 100644
index 00000000..2e1dc83a
--- /dev/null
+++ b/plugins/gfm/src/test/kotlin/renderers/gfm/GroupWrappingTest.kt
@@ -0,0 +1,77 @@
+package renderers.gfm
+
+import org.jetbrains.dokka.gfm.CommonmarkRenderer
+import renderers.gfm.GfmRenderingOnlyTestBase
+import org.jetbrains.dokka.pages.TextStyle
+import org.junit.jupiter.api.Test
+import renderers.*
+
+class GroupWrappingTest : GfmRenderingOnlyTestBase() {
+
+ @Test
+ fun notWrapped() {
+ val page = TestPage {
+ group {
+ text("a")
+ text("b")
+ }
+ text("c")
+ }
+
+ CommonmarkRenderer(context).render(page)
+
+ assert(renderedContent == "//[testPage](test-page.md)\n\nabc")
+ }
+
+ @Test
+ fun paragraphWrapped() {
+ val page = TestPage {
+ group(styles = setOf(TextStyle.Paragraph)) {
+ text("a")
+ text("b")
+ }
+ text("c")
+ }
+
+ CommonmarkRenderer(context).render(page)
+
+ assert(renderedContent == "//[testPage](test-page.md)\n\n\n\nab\n\nc")
+ }
+
+ @Test
+ fun blockWrapped() {
+ val page = TestPage {
+ group(styles = setOf(TextStyle.Block)) {
+ text("a")
+ text("b")
+ }
+ text("c")
+ }
+
+ CommonmarkRenderer(context).render(page)
+
+ assert(renderedContent == "//[testPage](test-page.md)\n\nab \nc")
+ }
+
+ @Test
+ fun nested() {
+ val page = TestPage {
+ group(styles = setOf(TextStyle.Block)) {
+ text("a")
+ group(styles = setOf(TextStyle.Block)) {
+ group(styles = setOf(TextStyle.Block)) {
+ text("b")
+ text("c")
+ }
+ }
+ text("d")
+ }
+ }
+
+ CommonmarkRenderer(context).render(page)
+
+// renderedContent.match(Div("a", Div(Div("bc")), "d"))
+ assert(renderedContent == "//[testPage](test-page.md)\n\nabc \n \nd \n")
+ }
+
+}
diff --git a/plugins/gfm/src/test/kotlin/renderers/gfm/SourceSetDependentHintTest.kt b/plugins/gfm/src/test/kotlin/renderers/gfm/SourceSetDependentHintTest.kt
new file mode 100644
index 00000000..64664d4a
--- /dev/null
+++ b/plugins/gfm/src/test/kotlin/renderers/gfm/SourceSetDependentHintTest.kt
@@ -0,0 +1,137 @@
+package renderers.gfm
+
+import org.jetbrains.dokka.Platform
+import org.jetbrains.dokka.SourceRootImpl
+import org.jetbrains.dokka.gfm.CommonmarkRenderer
+import renderers.gfm.GfmRenderingOnlyTestBase
+import org.jetbrains.dokka.pages.TextStyle
+import org.junit.jupiter.api.Test
+import renderers.TestPage
+import renderers.defaultSourceSet
+
+class SourceSetDependentHintTest : GfmRenderingOnlyTestBase() {
+
+ private val pl1 = defaultSourceSet.copy(
+ "root",
+ "pl1",
+ "pl1",
+ analysisPlatform = Platform.js,
+ sourceRoots = listOf(SourceRootImpl("pl1"))
+ )
+ private val pl2 = defaultSourceSet.copy(
+ "root",
+ "pl2",
+ "pl2",
+ analysisPlatform = Platform.jvm,
+ sourceRoots = listOf(SourceRootImpl("pl1"))
+ )
+ private val pl3 = defaultSourceSet.copy(
+ "root",
+ "pl3",
+ "pl3",
+ analysisPlatform = Platform.native,
+ sourceRoots = listOf(SourceRootImpl("pl1"))
+ )
+
+ @Test
+ fun platformIndependentCase() {
+ val page = TestPage {
+ sourceSetDependentHint(sourceSets = setOf(pl1, pl2, pl3), styles = setOf(TextStyle.Block)) {
+ text("a")
+ text("b")
+ text("c")
+ }
+ }
+
+ CommonmarkRenderer(context).render(page)
+ assert(renderedContent == "//[testPage](test-page.md)\n\n [root/pl1, root/pl2, root/pl3] abc \n ")
+ }
+
+ @Test
+ fun completelyDivergentCase() {
+ val page = TestPage {
+ sourceSetDependentHint(sourceSets = setOf(pl1, pl2, pl3), styles = setOf(TextStyle.Block)) {
+ text("a", sourceSets = setOf(pl1))
+ text("b", sourceSets = setOf(pl2))
+ text("c", sourceSets = setOf(pl3))
+ }
+ }
+
+ CommonmarkRenderer(context).render(page)
+ assert(renderedContent == "//[testPage](test-page.md)\n\n [root/pl1] a \n [root/pl2] b \n [root/pl3] c \n ")
+ }
+
+ @Test
+ fun overlappingCase() {
+ val page = TestPage {
+ sourceSetDependentHint(sourceSets = setOf(pl1, pl2), styles = setOf(TextStyle.Block)) {
+ text("a", sourceSets = setOf(pl1))
+ text("b", sourceSets = setOf(pl1, pl2))
+ text("c", sourceSets = setOf(pl2))
+ }
+ }
+
+ CommonmarkRenderer(context).render(page)
+ assert(renderedContent == "//[testPage](test-page.md)\n\n [root/pl1] ab \n [root/pl2] bc \n ")
+ }
+
+ @Test
+ fun caseThatCanBeSimplified() {
+ val page = TestPage {
+ sourceSetDependentHint(sourceSets = setOf(pl1, pl2), styles = setOf(TextStyle.Block)) {
+ text("a", sourceSets = setOf(pl1, pl2))
+ text("b", sourceSets = setOf(pl1))
+ text("b", sourceSets = setOf(pl2))
+ }
+ }
+
+ CommonmarkRenderer(context).render(page)
+ assert(renderedContent == "//[testPage](test-page.md)\n\n [root/pl1, root/pl2] ab \n ")
+ }
+
+ @Test
+ fun caseWithGroupBreakingSimplification() {
+ val page = TestPage {
+ sourceSetDependentHint(sourceSets = setOf(pl1, pl2), styles = setOf(TextStyle.Block)) {
+ group(styles = setOf(TextStyle.Block)) {
+ text("a", sourceSets = setOf(pl1, pl2))
+ text("b", sourceSets = setOf(pl1))
+ }
+ text("b", sourceSets = setOf(pl2))
+ }
+ }
+
+ CommonmarkRenderer(context).render(page)
+ assert(renderedContent == "//[testPage](test-page.md)\n\n [root/pl1] ab \n \n [root/pl2] a \nb \n ")
+ }
+
+ @Test
+ fun caseWithGroupNotBreakingSimplification() {
+ val page = TestPage {
+ sourceSetDependentHint(sourceSets = setOf(pl1, pl2)) {
+ group {
+ text("a", sourceSets = setOf(pl1, pl2))
+ text("b", sourceSets = setOf(pl1))
+ }
+ text("b", sourceSets = setOf(pl2))
+ }
+ }
+
+ CommonmarkRenderer(context).render(page)
+ assert(renderedContent == "//[testPage](test-page.md)\n\n [root/pl1, root/pl2] ab ")
+ }
+
+ @Test
+ fun partiallyUnifiedCase() {
+ val page = TestPage {
+ sourceSetDependentHint(sourceSets = setOf(pl1, pl2, pl3), styles = setOf(TextStyle.Block)) {
+ text("a", sourceSets = setOf(pl1))
+ text("a", sourceSets = setOf(pl2))
+ text("b", sourceSets = setOf(pl3))
+ }
+ }
+
+ CommonmarkRenderer(context).render(page)
+ assert(renderedContent == "//[testPage](test-page.md)\n\n [root/pl1, root/pl2] a \n [root/pl3] b \n ")
+ }
+} \ No newline at end of file