diff options
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 |