aboutsummaryrefslogtreecommitdiff
path: root/dokka-subprojects/plugin-base/src/test/kotlin/transformers
diff options
context:
space:
mode:
authorIgnat Beresnev <ignat.beresnev@jetbrains.com>2023-11-10 11:46:54 +0100
committerGitHub <noreply@github.com>2023-11-10 11:46:54 +0100
commit8e5c63d035ef44a269b8c43430f43f5c8eebfb63 (patch)
tree1b915207b2b9f61951ddbf0ff2e687efd053d555 /dokka-subprojects/plugin-base/src/test/kotlin/transformers
parenta44efd4ba0c2e4ab921ff75e0f53fc9335aa79db (diff)
downloaddokka-8e5c63d035ef44a269b8c43430f43f5c8eebfb63.tar.gz
dokka-8e5c63d035ef44a269b8c43430f43f5c8eebfb63.tar.bz2
dokka-8e5c63d035ef44a269b8c43430f43f5c8eebfb63.zip
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 <whyoleg@gmail.com>
Diffstat (limited to 'dokka-subprojects/plugin-base/src/test/kotlin/transformers')
-rw-r--r--dokka-subprojects/plugin-base/src/test/kotlin/transformers/AbstractContextModuleAndPackageDocumentationReaderTest.kt27
-rw-r--r--dokka-subprojects/plugin-base/src/test/kotlin/transformers/CommentsToContentConverterTest.kt484
-rw-r--r--dokka-subprojects/plugin-base/src/test/kotlin/transformers/ContextModuleAndPackageDocumentationReaderTest1.kt187
-rw-r--r--dokka-subprojects/plugin-base/src/test/kotlin/transformers/ContextModuleAndPackageDocumentationReaderTest3.kt61
-rw-r--r--dokka-subprojects/plugin-base/src/test/kotlin/transformers/DivisionSwitchTest.kt126
-rw-r--r--dokka-subprojects/plugin-base/src/test/kotlin/transformers/InheritedEntriesDocumentableFilterTransfromerTest.kt162
-rw-r--r--dokka-subprojects/plugin-base/src/test/kotlin/transformers/InvalidContentModuleAndPackageDocumentationReaderTest.kt100
-rw-r--r--dokka-subprojects/plugin-base/src/test/kotlin/transformers/MergeImplicitExpectActualDeclarationsTest.kt386
-rw-r--r--dokka-subprojects/plugin-base/src/test/kotlin/transformers/ModuleAndPackageDocumentationTransformerFunctionalTest.kt137
-rw-r--r--dokka-subprojects/plugin-base/src/test/kotlin/transformers/ModuleAndPackageDocumentationTransformerUnitTest.kt260
-rw-r--r--dokka-subprojects/plugin-base/src/test/kotlin/transformers/ObviousAndInheritedFunctionsDocumentableFilterTest.kt229
-rw-r--r--dokka-subprojects/plugin-base/src/test/kotlin/transformers/ReportUndocumentedTransformerTest.kt927
-rw-r--r--dokka-subprojects/plugin-base/src/test/kotlin/transformers/SourceLinkTransformerTest.kt131
-rw-r--r--dokka-subprojects/plugin-base/src/test/kotlin/transformers/SuppressTagFilterTest.kt211
-rw-r--r--dokka-subprojects/plugin-base/src/test/kotlin/transformers/SuppressedByConfigurationDocumentableFilterTransformerTest.kt193
-rw-r--r--dokka-subprojects/plugin-base/src/test/kotlin/transformers/isExceptionTest.kt147
16 files changed, 3768 insertions, 0 deletions
diff --git a/dokka-subprojects/plugin-base/src/test/kotlin/transformers/AbstractContextModuleAndPackageDocumentationReaderTest.kt b/dokka-subprojects/plugin-base/src/test/kotlin/transformers/AbstractContextModuleAndPackageDocumentationReaderTest.kt
new file mode 100644
index 00000000..8ce9360f
--- /dev/null
+++ b/dokka-subprojects/plugin-base/src/test/kotlin/transformers/AbstractContextModuleAndPackageDocumentationReaderTest.kt
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
+ */
+
+package transformers
+
+import org.jetbrains.dokka.model.SourceSetDependent
+import org.jetbrains.dokka.model.doc.DocumentationNode
+import org.jetbrains.dokka.model.doc.Text
+import org.jetbrains.dokka.model.withDescendants
+import org.junit.jupiter.api.io.TempDir
+import java.nio.file.Path
+
+abstract class AbstractContextModuleAndPackageDocumentationReaderTest {
+ @TempDir
+ protected lateinit var temporaryDirectory: Path
+
+
+ companion object {
+ val SourceSetDependent<DocumentationNode>.texts: List<String>
+ get() = values.flatMap { it.withDescendants() }
+ .flatMap { it.children }
+ .flatMap { it.children }
+ .mapNotNull { it as? Text }
+ .map { it.body }
+ }
+}
diff --git a/dokka-subprojects/plugin-base/src/test/kotlin/transformers/CommentsToContentConverterTest.kt b/dokka-subprojects/plugin-base/src/test/kotlin/transformers/CommentsToContentConverterTest.kt
new file mode 100644
index 00000000..1387c0e0
--- /dev/null
+++ b/dokka-subprojects/plugin-base/src/test/kotlin/transformers/CommentsToContentConverterTest.kt
@@ -0,0 +1,484 @@
+/*
+ * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
+ */
+
+package transformers
+
+import matchers.content.*
+import org.jetbrains.dokka.base.transformers.pages.comments.DocTagToContentConverter
+import org.jetbrains.dokka.links.DRI
+import org.jetbrains.dokka.model.doc.*
+import org.jetbrains.dokka.pages.*
+import kotlin.test.Test
+import kotlin.test.assertEquals
+import kotlin.test.assertTrue
+
+class CommentsToContentConverterTest {
+ private val converter = DocTagToContentConverter()
+
+ private fun executeTest(
+ docTag: DocTag,
+ match: ContentMatcherBuilder<ContentComposite>.() -> Unit,
+ ) {
+ val dci = DCI(
+ setOf(
+ DRI("kotlin", "Any")
+ ),
+ ContentKind.Comment
+ )
+ converter.buildContent(
+ Li(
+ listOf(
+ docTag
+ )
+ ),
+ dci,
+ emptySet()
+ ).single().assertNode(match)
+ }
+
+ @Test
+ fun `simple text`() {
+ val docTag = P(listOf(Text("This is simple test of string Next line")))
+ executeTest(docTag) {
+ group { +"This is simple test of string Next line" }
+ }
+ }
+
+ @Test
+ fun `simple text with new line`() {
+ val docTag = P(
+ listOf(
+ Text("This is simple test of string"),
+ Br,
+ Text("Next line")
+ )
+ )
+ executeTest(docTag) {
+ group {
+ +"This is simple test of string"
+ node<ContentBreakLine>()
+ +"Next line"
+ }
+ }
+ }
+
+ @Test
+ fun `paragraphs`() {
+ val docTag = P(
+ listOf(
+ P(listOf(Text("Paragraph number one"))),
+ P(listOf(Text("Paragraph"), Br, Text("number two")))
+ )
+ )
+ executeTest(docTag) {
+ group {
+ group { +"Paragraph number one" }
+ group {
+ +"Paragraph"
+ node<ContentBreakLine>()
+ +"number two"
+ }
+ }
+ }
+ }
+
+ @Test
+ fun `unordered list with empty lines`() {
+ val docTag = Ul(
+ listOf(
+ Li(listOf(P(listOf(Text("list item 1 continue 1"))))),
+ Li(listOf(P(listOf(Text("list item 2"), Br, Text("continue 2")))))
+ )
+ )
+ executeTest(docTag) {
+ node<ContentList> {
+ group {
+ +"list item 1 continue 1"
+ }
+ group {
+ +"list item 2"
+ node<ContentBreakLine>()
+ +"continue 2"
+ }
+ }
+ }
+ }
+
+ @Test
+ fun `nested list`() {
+ val docTag = P(
+ listOf(
+ Ul(
+ listOf(
+ Li(listOf(P(listOf(Text("Outer first Outer next line"))))),
+ Li(listOf(P(listOf(Text("Outer second"))))),
+ Ul(
+ listOf(
+ Li(listOf(P(listOf(Text("Middle first Middle next line"))))),
+ Li(listOf(P(listOf(Text("Middle second"))))),
+ Ul(
+ listOf(
+ Li(listOf(P(listOf(Text("Inner first Inner next line")))))
+ )
+ ),
+ Li(listOf(P(listOf(Text("Middle third")))))
+ )
+ ),
+ Li(listOf(P(listOf(Text("Outer third")))))
+ )
+ ),
+ P(listOf(Text("New paragraph")))
+ )
+ )
+ executeTest(docTag) {
+ group {
+ node<ContentList> {
+ group { +"Outer first Outer next line" }
+ group { +"Outer second" }
+ node<ContentList> {
+ group { +"Middle first Middle next line" }
+ group { +"Middle second" }
+ node<ContentList> {
+ group { +"Inner first Inner next line" }
+ }
+ group { +"Middle third" }
+ }
+ group { +"Outer third" }
+ }
+ group { +"New paragraph" }
+ }
+ }
+ }
+
+ @Test
+ fun `header and paragraphs`() {
+ val docTag = P(
+ listOf(
+ H1(listOf(Text("Header 1"))),
+ P(listOf(Text("Following text"))),
+ P(listOf(Text("New paragraph")))
+ )
+ )
+ executeTest(docTag) {
+ group {
+ header(1) { +"Header 1" }
+ group { +"Following text" }
+ group { +"New paragraph" }
+ }
+ }
+ }
+
+ @Test
+ fun `header levels`() {
+ val docTag = P(
+ listOf(
+ H1(listOf(Text("Header 1"))),
+ P(listOf(Text("Text 1"))),
+ H2(listOf(Text("Header 2"))),
+ P(listOf(Text("Text 2"))),
+ H3(listOf(Text("Header 3"))),
+ P(listOf(Text("Text 3"))),
+ H4(listOf(Text("Header 4"))),
+ P(listOf(Text("Text 4"))),
+ H5(listOf(Text("Header 5"))),
+ P(listOf(Text("Text 5"))),
+ H6(listOf(Text("Header 6"))),
+ P(listOf(Text("Text 6")))
+ )
+ )
+ executeTest(docTag) {
+ group {
+ header(1) { +"Header 1" }
+ group { +"Text 1" }
+ header(2) { +"Header 2" }
+ group { +"Text 2" }
+ header(3) { +"Header 3" }
+ group { +"Text 3" }
+ header(4) { +"Header 4" }
+ group { +"Text 4" }
+ header(5) { +"Header 5" }
+ group { +"Text 5" }
+ header(6) { +"Header 6" }
+ group { +"Text 6" }
+ }
+ }
+ }
+
+ @Test
+ fun `block quotes`() {
+ val docTag = P(
+ listOf(
+ BlockQuote(
+ listOf(
+ P(
+ listOf(
+ Text("Blockquotes are very handy in email to emulate reply text. This line is part of the same quote.")
+ )
+ )
+ )
+ ),
+ P(listOf(Text("Quote break."))),
+ BlockQuote(
+ listOf(
+ P(listOf(Text("Quote")))
+ )
+ )
+ )
+ )
+ executeTest(docTag) {
+ group {
+ group {
+ group {
+ +"Blockquotes are very handy in email to emulate reply text. This line is part of the same quote."
+ }
+ }
+ group { +"Quote break." }
+ group {
+ group {
+ +"Quote"
+ }
+ }
+ }
+ }
+ }
+
+ @Test
+ fun `nested block quotes`() {
+ val docTag = P(
+ listOf(
+ BlockQuote(
+ listOf(
+ P(listOf(Text("text 1 text 2"))),
+ BlockQuote(
+ listOf(
+ P(listOf(Text("text 3 text 4")))
+ )
+ ),
+ P(listOf(Text("text 5")))
+ )
+ ),
+ P(listOf(Text("Quote break."))),
+ BlockQuote(
+ listOf(
+ P(listOf(Text("Quote")))
+ )
+ )
+ )
+ )
+ executeTest(docTag) {
+ group {
+ group {
+ group { +"text 1 text 2" }
+ group {
+ group { +"text 3 text 4" }
+ }
+ group { +"text 5" }
+ }
+ group { +"Quote break." }
+ group {
+ group { +"Quote" }
+ }
+ }
+ }
+ }
+
+ @Test
+ fun `multiline code`() {
+ val docTag = P(
+ listOf(
+ CodeBlock(
+ listOf(
+ Text("val x: Int = 0"), Br,
+ Text("val y: String = \"Text\""), Br, Br,
+ Text(" val z: Boolean = true"), Br,
+ Text("for(i in 0..10) {"), Br,
+ Text(" println(i)"), Br,
+ Text("}")
+ ),
+ mapOf("lang" to "kotlin")
+ ),
+ P(listOf(Text("Sample text")))
+ )
+ )
+ executeTest(docTag) {
+ group {
+ node<ContentCodeBlock> {
+ +"val x: Int = 0"
+ node<ContentBreakLine>()
+ +"val y: String = \"Text\""
+ node<ContentBreakLine>()
+ node<ContentBreakLine>()
+ +" val z: Boolean = true"
+ node<ContentBreakLine>()
+ +"for(i in 0..10) {"
+ node<ContentBreakLine>()
+ +" println(i)"
+ node<ContentBreakLine>()
+ +"}"
+ }
+ group { +"Sample text" }
+ }
+ }
+ }
+
+ @Test
+ fun `inline link`() {
+ val docTag = P(
+ listOf(
+ A(
+ listOf(Text("I'm an inline-style link")),
+ mapOf("href" to "https://www.google.com")
+ )
+ )
+ )
+ executeTest(docTag) {
+ group {
+ link {
+ +"I'm an inline-style link"
+ check {
+ assertEquals(
+ (this as? ContentResolvedLink)?.address ?: error("Link should be resolved"),
+ "https://www.google.com"
+ )
+ }
+ }
+ }
+ }
+ }
+
+
+ @Test
+ fun `ordered list`() {
+ val docTag =
+ Ol(
+ listOf(
+ Li(
+ listOf(
+ P(listOf(Text("test1"))),
+ P(listOf(Text("test2"))),
+ )
+ ),
+ Li(
+ listOf(
+ P(listOf(Text("test3"))),
+ P(listOf(Text("test4"))),
+ )
+ )
+ )
+ )
+ executeTest(docTag) {
+ node<ContentList> {
+ group {
+ +"test1"
+ +"test2"
+ }
+ group {
+ +"test3"
+ +"test4"
+ }
+ }
+ }
+ }
+
+ @Test
+ fun `nested ordered list`() {
+ val docTag = P(
+ listOf(
+ Ol(
+ listOf(
+ Li(listOf(P(listOf(Text("Outer first Outer next line"))))),
+ Li(listOf(P(listOf(Text("Outer second"))))),
+ Ol(
+ listOf(
+ Li(listOf(P(listOf(Text("Middle first Middle next line"))))),
+ Li(listOf(P(listOf(Text("Middle second"))))),
+ Ol(
+ listOf(
+ Li(listOf(P(listOf(Text("Inner first Inner next line")))))
+ ),
+ mapOf("start" to "1")
+ ),
+ Li(listOf(P(listOf(Text("Middle third")))))
+ ),
+ mapOf("start" to "1")
+ ),
+ Li(listOf(P(listOf(Text("Outer third")))))
+ ),
+ mapOf("start" to "1")
+ ),
+ P(listOf(Text("New paragraph")))
+ )
+ )
+ executeTest(docTag) {
+ group {
+ node<ContentList> {
+ group { +"Outer first Outer next line" }
+ group { +"Outer second" }
+ node<ContentList> {
+ group { +"Middle first Middle next line" }
+ group { +"Middle second" }
+ node<ContentList> {
+ +"Inner first Inner next line"
+ }
+ group { +"Middle third" }
+ }
+ group { +"Outer third" }
+ }
+ group {
+ +"New paragraph"
+ }
+ }
+ }
+ }
+
+ @Test
+ fun `description list`() {
+ val docTag =
+ Dl(
+ listOf(
+ Dt(
+ listOf(
+ Text("description list can have...")
+ )
+ ),
+ Dt(
+ listOf(
+ Text("... two consecutive description terms")
+ )
+ ),
+ Dd(
+ listOf(
+ Text("and usually has some sort of a description, like this one")
+ )
+ )
+ )
+ )
+
+ executeTest(docTag) {
+ composite<ContentList> {
+ check {
+ assertTrue(style.contains(ListStyle.DescriptionList), "Expected DL style")
+ }
+ group {
+ check {
+ assertTrue(style.contains(ListStyle.DescriptionTerm), "Expected DT style")
+ }
+ +"description list can have..."
+ }
+ group {
+ check {
+ assertTrue(style.contains(ListStyle.DescriptionTerm), "Expected DT style")
+ }
+ +"... two consecutive description terms"
+ }
+ group {
+ check {
+ assertTrue(style.contains(ListStyle.DescriptionDetails), "Expected DD style")
+ }
+ +"and usually has some sort of a description, like this one"
+ }
+ }
+ }
+ }
+}
diff --git a/dokka-subprojects/plugin-base/src/test/kotlin/transformers/ContextModuleAndPackageDocumentationReaderTest1.kt b/dokka-subprojects/plugin-base/src/test/kotlin/transformers/ContextModuleAndPackageDocumentationReaderTest1.kt
new file mode 100644
index 00000000..dfb3eff1
--- /dev/null
+++ b/dokka-subprojects/plugin-base/src/test/kotlin/transformers/ContextModuleAndPackageDocumentationReaderTest1.kt
@@ -0,0 +1,187 @@
+/*
+ * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
+ */
+
+package transformers
+
+import org.jetbrains.dokka.DokkaConfiguration.DokkaSourceSet
+import org.jetbrains.dokka.analysis.kotlin.internal.InternalKotlinAnalysisPlugin
+import org.jetbrains.dokka.links.DRI
+import org.jetbrains.dokka.model.doc.DocumentationNode
+import org.jetbrains.dokka.plugability.DokkaContext
+import org.jetbrains.dokka.plugability.plugin
+import org.jetbrains.dokka.plugability.querySingle
+import org.jetbrains.dokka.testApi.logger.TestLogger
+import org.jetbrains.dokka.utilities.DokkaConsoleLogger
+import org.jetbrains.dokka.utilities.LoggingLevel
+import testApi.testRunner.TestDokkaConfigurationBuilder
+import testApi.testRunner.dModule
+import testApi.testRunner.dPackage
+import kotlin.test.BeforeTest
+import kotlin.test.Test
+import kotlin.test.assertEquals
+import kotlin.test.assertFailsWith
+
+class ContextModuleAndPackageDocumentationReaderTest1 : AbstractContextModuleAndPackageDocumentationReaderTest() {
+
+
+ private val includeSourceSetA by lazy { temporaryDirectory.resolve("includeA.md").toFile() }
+ private val includeSourceSetB by lazy { temporaryDirectory.resolve("includeB.md").toFile() }
+
+ @BeforeTest
+ fun materializeIncludes() {
+ includeSourceSetA.writeText(
+ """
+ # Module moduleA
+ This is moduleA
+
+ # Package sample.a
+ This is package sample.a\r\n
+
+ # Package noise.b
+ This will just add some noise
+ """.trimIndent().replace("\n", "\r\n")
+ )
+
+ includeSourceSetB.writeText(
+ """
+ # Module moduleB
+ This is moduleB
+
+ # Package sample.b
+ This is package sample.b
+
+ # Package noise.b
+ This will just add some more noise
+ """.trimIndent()
+ )
+ }
+
+ private val configurationBuilder = TestDokkaConfigurationBuilder().apply {
+ moduleName = "moduleA"
+ }
+
+ private val sourceSetA by configurationBuilder.sourceSet {
+ name = "sourceSetA"
+ includes = listOf(includeSourceSetA.canonicalPath)
+ }
+
+
+ private val sourceSetB by configurationBuilder.sourceSet {
+ name = "sourceSetB"
+ includes = listOf(includeSourceSetB.canonicalPath)
+ }
+
+
+ private val sourceSetB2 by configurationBuilder.sourceSet {
+ name = "sourceSetB2"
+ includes = emptyList()
+ }
+
+
+ private val context by lazy {
+ DokkaContext.create(
+ configuration = configurationBuilder.build(),
+ logger = TestLogger(DokkaConsoleLogger(LoggingLevel.DEBUG)),
+ pluginOverrides = emptyList()
+ )
+ }
+
+ private val reader by lazy { context.plugin<InternalKotlinAnalysisPlugin>().querySingle { moduleAndPackageDocumentationReader } }
+
+ @Test
+ fun `assert moduleA with sourceSetA`() {
+ val documentation = reader.read(dModule(name = "moduleA", sourceSets = setOf(sourceSetA)))
+ assertEquals(
+ 1, documentation.keys.size,
+ "Expected moduleA only containing documentation in a single source set"
+ )
+ assertEquals(
+ "sourceSetA", documentation.keys.single().sourceSetID.sourceSetName,
+ "Expected moduleA documentation coming from sourceSetA"
+ )
+
+ assertEquals(
+ "This is moduleA", documentation.texts.single(),
+ "Expected moduleA documentation being present"
+ )
+ }
+
+ @Test
+ fun `assert moduleA with no source sets`() {
+ val documentation = reader.read(dModule("moduleA"))
+ assertEquals(
+ emptyMap(), documentation,
+ "Expected no documentation received for module not declaring a matching sourceSet"
+ )
+ }
+
+ @Test
+ fun `assert moduleA with unknown source set`() {
+ assertFailsWith<IllegalStateException>(
+ "Expected no documentation received for module with unknown sourceSet"
+ ) {
+ reader.read(
+ dModule("moduleA", sourceSets = setOf(configurationBuilder.unattachedSourceSet { name = "unknown" }))
+ )
+ }
+ }
+
+ @Test
+ fun `assert moduleA with all sourceSets`() {
+ val documentation = reader.read(dModule("moduleA", sourceSets = setOf(sourceSetA, sourceSetB, sourceSetB2)))
+ assertEquals(1, documentation.entries.size, "Expected only one entry from sourceSetA")
+ assertEquals(sourceSetA, documentation.keys.single(), "Expected only one entry from sourceSetA")
+ assertEquals("This is moduleA", documentation.texts.single())
+ }
+
+ @Test
+ fun `assert moduleB with sourceSetB and sourceSetB2`() {
+ val documentation = reader.read(dModule("moduleB", sourceSets = setOf(sourceSetB, sourceSetB2)))
+ assertEquals(1, documentation.keys.size, "Expected only one entry from sourceSetB")
+ assertEquals(sourceSetB, documentation.keys.single(), "Expected only one entry from sourceSetB")
+ assertEquals("This is moduleB", documentation.texts.single())
+ }
+
+ @Test
+ fun `assert sample_A in sourceSetA`() {
+ val documentation = reader.read(dPackage(DRI("sample.a"), sourceSets = setOf(sourceSetA)))
+ assertEquals(1, documentation.keys.size, "Expected only one entry from sourceSetA")
+ assertEquals(sourceSetA, documentation.keys.single(), "Expected only one entry from sourceSetA")
+ assertEquals("This is package sample.a\\r\\n", documentation.texts.single())
+ }
+
+ @Test
+ fun `assert sample_a_sub in sourceSetA`() {
+ val documentation = reader.read(dPackage(DRI("sample.a.sub"), sourceSets = setOf(sourceSetA)))
+ assertEquals(
+ emptyMap<DokkaSourceSet, DocumentationNode>(), documentation,
+ "Expected no documentation found for different package"
+ )
+ }
+
+ @Test
+ fun `assert sample_a in sourceSetB`() {
+ val documentation = reader.read(dPackage(DRI("sample.a"), sourceSets = setOf(sourceSetB)))
+ assertEquals(
+ emptyMap<DokkaSourceSet, DocumentationNode>(), documentation,
+ "Expected no documentation found for different sourceSet"
+ )
+ }
+
+ @Test
+ fun `assert sample_b in sourceSetB`() {
+ val documentation = reader.read(dPackage(DRI("sample.b"), sourceSets = setOf(sourceSetB)))
+ assertEquals(1, documentation.keys.size, "Expected only one entry from sourceSetB")
+ assertEquals(sourceSetB, documentation.keys.single(), "Expected only one entry from sourceSetB")
+ assertEquals("This is package sample.b", documentation.texts.single())
+ }
+
+ @Test
+ fun `assert sample_b in sourceSetB and sourceSetB2`() {
+ val documentation = reader.read(dPackage(DRI("sample.b"), sourceSets = setOf(sourceSetB, sourceSetB2)))
+ assertEquals(1, documentation.keys.size, "Expected only one entry from sourceSetB")
+ assertEquals(sourceSetB, documentation.keys.single(), "Expected only one entry from sourceSetB")
+ assertEquals("This is package sample.b", documentation.texts.single())
+ }
+}
diff --git a/dokka-subprojects/plugin-base/src/test/kotlin/transformers/ContextModuleAndPackageDocumentationReaderTest3.kt b/dokka-subprojects/plugin-base/src/test/kotlin/transformers/ContextModuleAndPackageDocumentationReaderTest3.kt
new file mode 100644
index 00000000..ebd5b7eb
--- /dev/null
+++ b/dokka-subprojects/plugin-base/src/test/kotlin/transformers/ContextModuleAndPackageDocumentationReaderTest3.kt
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
+ */
+
+package transformers
+
+import org.jetbrains.dokka.analysis.kotlin.internal.InternalKotlinAnalysisPlugin
+import org.jetbrains.dokka.links.DRI
+import org.jetbrains.dokka.plugability.DokkaContext
+import org.jetbrains.dokka.plugability.plugin
+import org.jetbrains.dokka.plugability.querySingle
+import org.jetbrains.dokka.utilities.DokkaConsoleLogger
+import org.jetbrains.dokka.utilities.LoggingLevel
+import testApi.testRunner.TestDokkaConfigurationBuilder
+import testApi.testRunner.dPackage
+import kotlin.test.BeforeTest
+import kotlin.test.Test
+import kotlin.test.assertEquals
+
+class ContextModuleAndPackageDocumentationReaderTest3 : AbstractContextModuleAndPackageDocumentationReaderTest() {
+
+ private val include by lazy { temporaryDirectory.resolve("include.md").toFile() }
+
+ @BeforeTest
+ fun materializeInclude() {
+ include.writeText(
+ """
+ # Package
+ This is the root package
+
+ # Package [root]
+ This is also the root package
+ """.trimIndent()
+ )
+ }
+
+ private val configurationBuilder = TestDokkaConfigurationBuilder()
+
+ private val sourceSet by configurationBuilder.sourceSet {
+ includes = listOf(include.canonicalPath)
+ }
+
+ private val context by lazy {
+ DokkaContext.create(
+ configuration = configurationBuilder.build(),
+ logger = DokkaConsoleLogger(LoggingLevel.DEBUG),
+ pluginOverrides = emptyList()
+ )
+ }
+
+ private val reader by lazy { context.plugin<InternalKotlinAnalysisPlugin>().querySingle { moduleAndPackageDocumentationReader } }
+
+
+ @Test
+ fun `root package is matched by empty string and the root keyword`() {
+ val documentation = reader.read(dPackage(DRI(""), sourceSets = setOf(sourceSet)))
+ assertEquals(
+ listOf("This is the root package", "This is also the root package"), documentation.texts
+ )
+ }
+}
diff --git a/dokka-subprojects/plugin-base/src/test/kotlin/transformers/DivisionSwitchTest.kt b/dokka-subprojects/plugin-base/src/test/kotlin/transformers/DivisionSwitchTest.kt
new file mode 100644
index 00000000..fec5fc47
--- /dev/null
+++ b/dokka-subprojects/plugin-base/src/test/kotlin/transformers/DivisionSwitchTest.kt
@@ -0,0 +1,126 @@
+/*
+ * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
+ */
+
+package transformers
+
+import org.jetbrains.dokka.DokkaConfiguration
+import org.jetbrains.dokka.PluginConfigurationImpl
+import org.jetbrains.dokka.base.DokkaBase
+import org.jetbrains.dokka.base.testApi.testRunner.BaseAbstractTest
+import org.jetbrains.dokka.model.dfs
+import org.jetbrains.dokka.pages.ClasslikePageNode
+import org.jetbrains.dokka.pages.ContentHeader
+import org.jetbrains.dokka.pages.ContentNode
+import org.jetbrains.dokka.pages.ContentText
+import kotlin.test.Test
+import kotlin.test.assertEquals
+import kotlin.test.assertNotNull
+
+class DivisionSwitchTest : BaseAbstractTest() {
+
+ private val query = """
+ |/src/source0.kt
+ package package0
+ /**
+ * Documentation for ClassA
+ */
+ class ClassA {
+ val A: String = "A"
+ fun a() {}
+ fun b() {}
+ }
+
+ /src/source1.kt
+ package package0
+ /**
+ * Documentation for ClassB
+ */
+ class ClassB : ClassA() {
+ val B: String = "B"
+ fun d() {}
+ fun e() {}
+ }
+ """.trimMargin()
+
+ private fun configuration(switchOn: Boolean) = dokkaConfiguration {