From 855718815ff58660a965b29247137355e67160c9 Mon Sep 17 00:00:00 2001
From: "sebastian.sellmair" <sebastian.sellmair@jetbrains.com>
Date: Wed, 26 Aug 2020 14:49:31 +0200
Subject: WIP

---
 .../parseModuleAndPackageDocumentationFragments.kt |  14 +-
 ...seModuleAndPackageDocumentationFragmentsTest.kt |  31 +--
 ...ackageDocumentationTransformerFunctionalTest.kt |  96 ++++++++
 ...ModuleAndPackageDocumentationTransformerTest.kt | 241 ---------------------
 ...leAndPackageDocumentationTransformerUnitTest.kt | 241 +++++++++++++++++++++
 5 files changed, 362 insertions(+), 261 deletions(-)
 create mode 100644 plugins/base/src/test/kotlin/transformers/ModuleAndPackageDocumentationTransformerFunctionalTest.kt
 delete mode 100644 plugins/base/src/test/kotlin/transformers/ModuleAndPackageDocumentationTransformerTest.kt
 create mode 100644 plugins/base/src/test/kotlin/transformers/ModuleAndPackageDocumentationTransformerUnitTest.kt

(limited to 'plugins/base/src')

diff --git a/plugins/base/src/main/kotlin/parsers/moduleAndPackage/parseModuleAndPackageDocumentationFragments.kt b/plugins/base/src/main/kotlin/parsers/moduleAndPackage/parseModuleAndPackageDocumentationFragments.kt
index 2667681c..6155af52 100644
--- a/plugins/base/src/main/kotlin/parsers/moduleAndPackage/parseModuleAndPackageDocumentationFragments.kt
+++ b/plugins/base/src/main/kotlin/parsers/moduleAndPackage/parseModuleAndPackageDocumentationFragments.kt
@@ -1,5 +1,6 @@
 package org.jetbrains.dokka.base.parsers.moduleAndPackage
 
+import org.jetbrains.dokka.base.parsers.moduleAndPackage.ModuleAndPackageDocumentation.Classifier.*
 import java.io.File
 
 
@@ -24,17 +25,18 @@ private fun parseModuleAndPackageDocFragment(
     val firstLine = firstLineAndDocumentation[0]
 
     val classifierAndName = firstLine.split(Regex("\\s+"), limit = 2)
-    if (classifierAndName.size != 2) {
-        throw IllegalModuleAndPackageDocumentation(source, "Missing ${classifierAndName.first()} name")
-    }
 
     val classifier = when (classifierAndName[0].trim()) {
-        "Module" -> ModuleAndPackageDocumentation.Classifier.Module
-        "Package" -> ModuleAndPackageDocumentation.Classifier.Package
+        "Module" -> Module
+        "Package" -> Package
         else -> throw IllegalStateException("Unexpected classifier ${classifierAndName[0]}")
     }
 
-    val name = classifierAndName[1].trim()
+    if (classifierAndName.size != 2 && classifier == Module) {
+        throw IllegalModuleAndPackageDocumentation(source, "Missing Module name")
+    }
+
+    val name = classifierAndName.getOrNull(1)?.trim().orEmpty()
     if (name.contains(Regex("\\s"))) {
         throw IllegalModuleAndPackageDocumentation(
             source, "Module/Package name cannot contain whitespace in '$firstLine'"
diff --git a/plugins/base/src/test/kotlin/parsers/ParseModuleAndPackageDocumentationFragmentsTest.kt b/plugins/base/src/test/kotlin/parsers/ParseModuleAndPackageDocumentationFragmentsTest.kt
index 5c0a0646..17f9631a 100644
--- a/plugins/base/src/test/kotlin/parsers/ParseModuleAndPackageDocumentationFragmentsTest.kt
+++ b/plugins/base/src/test/kotlin/parsers/ParseModuleAndPackageDocumentationFragmentsTest.kt
@@ -76,21 +76,24 @@ class ParseModuleAndPackageDocumentationFragmentsTest {
     }
 
     @Test
-    fun `no package name specified fails`() {
-        val exception = assertThrows<IllegalModuleAndPackageDocumentation> {
-            parseModuleAndPackageDocumentationFragments(
-                source(
-                    """
-                    # Package
-                    No package name given
-                    """.trimIndent()
-                )
-            )
-        }
+    fun `no package name specified does not fail`() {
+        val source = source(
+            """
+            # Package
+            This is a root package
+            """.trimIndent()
+        )
+        val fragments = parseModuleAndPackageDocumentationFragments(source)
+        assertEquals(1, fragments.size, "Expected a single package fragment")
 
-        assertTrue(
-            "Missing Package name" in exception.message.orEmpty(),
-            "Expected 'Missing Package name' in error message"
+        assertEquals(
+            ModuleAndPackageDocumentationFragment(
+                name = "",
+                classifier = Package,
+                documentation = "This is a root package",
+                source = source
+            ),
+            fragments.single()
         )
     }
 
diff --git a/plugins/base/src/test/kotlin/transformers/ModuleAndPackageDocumentationTransformerFunctionalTest.kt b/plugins/base/src/test/kotlin/transformers/ModuleAndPackageDocumentationTransformerFunctionalTest.kt
new file mode 100644
index 00000000..e622e79d
--- /dev/null
+++ b/plugins/base/src/test/kotlin/transformers/ModuleAndPackageDocumentationTransformerFunctionalTest.kt
@@ -0,0 +1,96 @@
+package transformers
+
+import org.jetbrains.dokka.DokkaSourceSetID
+import org.jetbrains.dokka.testApi.testRunner.AbstractCoreTest
+import org.junit.jupiter.api.Test
+import org.junit.jupiter.api.io.TempDir
+import java.nio.file.Path
+import kotlin.test.assertEquals
+
+class ModuleAndPackageDocumentationTransformerFunctionalTest : AbstractCoreTest() {
+
+    @Test
+    fun `multiplatform project`(@TempDir tempDir: Path) {
+        val include = tempDir.resolve("include.md").toFile()
+        include.writeText(
+            """
+            # Module moduleA
+            This is moduleA
+            
+            # Package
+            This is the root package
+            
+            # Package common
+            This is the common package
+            
+            # Package jvm 
+            This is the jvm package
+            
+            # Package js
+            This is the js package
+            """.trimIndent()
+        )
+        val configuration = dokkaConfiguration {
+            sourceSets {
+                sourceSet {
+                    moduleName = "moduleA"
+                    name = "commonMain"
+                    displayName = "common"
+                    analysisPlatform = "common"
+                    sourceRoots = listOf("src/commonMain/kotlin")
+                    includes = listOf(include.canonicalPath)
+                }
+                sourceSet {
+                    moduleName = "moduleA"
+                    name = "jsMain"
+                    displayName = "js"
+                    analysisPlatform = "js"
+                    sourceRoots = listOf("src/jsMain/kotlin")
+                    dependentSourceSets = setOf(DokkaSourceSetID("moduleA", "commonMain"))
+                }
+                sourceSet {
+                    moduleName = "moduleA"
+                    name = "jvmMain"
+                    displayName = "jvm"
+                    analysisPlatform = "jvm"
+                    sourceRoots = listOf("src/jvmMain/kotlin")
+                    dependentSourceSets = setOf(DokkaSourceSetID("moduleA", "commonMain"))
+                }
+            }
+        }
+
+        testInline(
+            """
+            /src/commonMain/kotlin/common/CommonApi.kt
+            package common
+            val commonApi = "common"
+            
+            /src/jsMain/kotlin/js/JsApi.kt
+            package js
+            val jsApi = "js"
+            
+            /src/jvmMain/kotlin/jvm/JvmApi.kt
+            package jvm
+            val jvmApi = "jvm"
+            
+            /src/commonMain/kotlin/CommonRoot.kt
+            val commonRoot = "commonRoot"
+            
+            /src/jsMain/kotlin/JsRoot.kt
+            val jsRoot = "jsRoot"
+            
+            /src/jvmMain/kotlin/JvmRoot.kt
+            val jvmRoot = "jvmRoot"
+            """.trimIndent(),
+            configuration
+        ) {
+            this.documentablesMergingStage = { module ->
+                val packageNames = module.packages.map { it.dri.packageName ?: "NULL" }
+                assertEquals(
+                    listOf("", "common", "js", "jvm").sorted(), packageNames.sorted(),
+                    "Expected all packages to be present"
+                )
+            }
+        }
+    }
+}
diff --git a/plugins/base/src/test/kotlin/transformers/ModuleAndPackageDocumentationTransformerTest.kt b/plugins/base/src/test/kotlin/transformers/ModuleAndPackageDocumentationTransformerTest.kt
deleted file mode 100644
index d2b41273..00000000
--- a/plugins/base/src/test/kotlin/transformers/ModuleAndPackageDocumentationTransformerTest.kt
+++ /dev/null
@@ -1,241 +0,0 @@
-package transformers
-
-import org.jetbrains.dokka.base.transformers.documentables.ModuleAndPackageDocumentationReader
-import org.jetbrains.dokka.base.transformers.documentables.ModuleAndPackageDocumentationTransformer
-import org.jetbrains.dokka.links.DRI
-import org.jetbrains.dokka.model.DModule
-import org.jetbrains.dokka.model.DPackage
-import org.jetbrains.dokka.model.SourceSetDependent
-import org.jetbrains.dokka.model.doc.DocumentationNode
-import org.junit.jupiter.api.Assertions.assertEquals
-import org.junit.jupiter.api.Test
-import testApi.testRunner.documentationNode
-import testApi.testRunner.sourceSet
-
-
-class ModuleAndPackageDocumentationTransformerTest {
-
-    @Test
-    fun `empty list of modules`() {
-        val transformer = ModuleAndPackageDocumentationTransformer(
-            object : ModuleAndPackageDocumentationReader {
-                override fun get(module: DModule): SourceSetDependent<DocumentationNode> = throw NotImplementedError()
-                override fun get(pkg: DPackage): SourceSetDependent<DocumentationNode> = throw NotImplementedError()
-            }
-        )
-
-        assertEquals(
-            emptyList<DModule>(), transformer(emptyList()),
-        )
-    }
-
-    @Test
-    fun `single module documentation`() {
-        val transformer = ModuleAndPackageDocumentationTransformer(
-            object : ModuleAndPackageDocumentationReader {
-                override fun get(pkg: DPackage): SourceSetDependent<DocumentationNode> = throw NotImplementedError()
-                override fun get(module: DModule): SourceSetDependent<DocumentationNode> {
-                    return module.sourceSets.associateWith { sourceSet ->
-                        documentationNode("doc" + sourceSet.displayName)
-                    }
-                }
-
-            }
-        )
-
-        val result = transformer(
-            listOf(
-                DModule(
-                    "ModuleName",
-                    documentation = emptyMap(),
-                    packages = emptyList(),
-                    sourceSets = setOf(
-                        sourceSet("A"),
-                        sourceSet("B")
-                    )
-                )
-            )
-        )
-
-        assertEquals(
-            DModule(
-                "ModuleName",
-                documentation = mapOf(
-                    sourceSet("A") to documentationNode("docA"),
-                    sourceSet("B") to documentationNode("docB")
-                ),
-                sourceSets = setOf(sourceSet("A"), sourceSet("B")),
-                packages = emptyList()
-            ),
-            result.single()
-        )
-
-    }
-
-    @Test
-    fun `merges with already existing module documentation`() {
-        val transformer = ModuleAndPackageDocumentationTransformer(
-            object : ModuleAndPackageDocumentationReader {
-                override fun get(pkg: DPackage): SourceSetDependent<DocumentationNode> = throw NotImplementedError()
-                override fun get(module: DModule): SourceSetDependent<DocumentationNode> {
-                    /* Only add documentation for first source set */
-                    return module.sourceSets.take(1).associateWith { sourceSet ->
-                        documentationNode("doc" + sourceSet.displayName)
-                    }
-                }
-            }
-        )
-
-        val result = transformer(
-            listOf(
-                DModule(
-                    "MyModule",
-                    documentation = mapOf(
-                        sourceSet("A") to documentationNode("pre-existing:A"),
-                        sourceSet("B") to documentationNode("pre-existing:B")
-                    ),
-                    sourceSets = setOf(sourceSet("A"), sourceSet("B")),
-                    packages = emptyList()
-                )
-            )
-        )
-
-        assertEquals(
-            DModule(
-                "MyModule",
-                documentation = mapOf(
-                    /* Expect previous documentation and newly attached one */
-                    sourceSet("A") to documentationNode("pre-existing:A", "docA"),
-                    /* Only first source set will get documentation attached */
-                    sourceSet("B") to documentationNode("pre-existing:B")
-                ),
-                sourceSets = setOf(sourceSet("A"), sourceSet("B")),
-                packages = emptyList()
-            ),
-            result.single()
-        )
-    }
-
-    @Test
-    fun `package documentation`() {
-        val transformer = ModuleAndPackageDocumentationTransformer(
-            object : ModuleAndPackageDocumentationReader {
-                override fun get(module: DModule): SourceSetDependent<DocumentationNode> = emptyMap()
-                override fun get(pkg: DPackage): SourceSetDependent<DocumentationNode> {
-                    /* Only attach documentation to packages with 'attach' */
-                    if ("attach" !in pkg.dri.packageName.orEmpty()) return emptyMap()
-                    /* Only attach documentation to two source sets */
-                    return pkg.sourceSets.take(2).associateWith { sourceSet ->
-                        documentationNode("doc:${sourceSet.displayName}:${pkg.dri.packageName}")
-                    }
-                }
-            }
-        )
-
-        val result = transformer(
-            listOf(
-                DModule(
-                    "MyModule",
-                    documentation = emptyMap(),
-                    sourceSets = emptySet(),
-                    packages = listOf(
-                        DPackage(
-                            dri = DRI("com.sample"),
-                            documentation = mapOf(
-                                sourceSet("A") to documentationNode("pre-existing:A:com.sample")
-                            ),
-                            sourceSets = setOf(sourceSet("A"), sourceSet("B"), sourceSet("C")),
-                        ),
-                        DPackage(
-                            dri = DRI("com.attach"),
-                            documentation = mapOf(
-                                sourceSet("A") to documentationNode("pre-existing:A:com.attach")
-                            ),
-                            sourceSets = setOf(sourceSet("A"), sourceSet("B"), sourceSet("C"))
-                        ),
-                        DPackage(
-                            dri = DRI("com.attach.sub"),
-                            documentation = mapOf(
-                                sourceSet("A") to documentationNode("pre-existing:A:com.attach.sub"),
-                                sourceSet("B") to documentationNode("pre-existing:B:com.attach.sub"),
-                                sourceSet("C") to documentationNode("pre-existing:C:com.attach.sub")
-                            ),
-                            sourceSets = setOf(sourceSet("A"), sourceSet("B"), sourceSet("C")),
-                        )
-                    )
-                )
-            )
-        )
-
-        result.single().packages.forEach { pkg ->
-            assertEquals(
-                setOf(sourceSet("A"), sourceSet("B"), sourceSet("C")), pkg.sourceSets,
-                "Expected source sets A, B, C for package ${pkg.dri.packageName}"
-            )
-        }
-
-        val comSample = result.single().packages.single { it.dri.packageName == "com.sample" }
-        assertEquals(
-            mapOf(sourceSet("A") to documentationNode("pre-existing:A:com.sample")),
-            comSample.documentation,
-            "Expected no documentation added to package 'com.sample' because of wrong package"
-        )
-
-        val comAttach = result.single().packages.single { it.dri.packageName == "com.attach" }
-        assertEquals(
-            mapOf(
-                sourceSet("A") to documentationNode("pre-existing:A:com.attach", "doc:A:com.attach"),
-                sourceSet("B") to documentationNode("doc:B:com.attach")
-            ),
-            comAttach.documentation,
-            "Expected documentation added to source sets A and B"
-        )
-
-        assertEquals(
-            DModule(
-                "MyModule",
-                documentation = emptyMap(),
-                sourceSets = emptySet(),
-                packages = listOf(
-                    DPackage(
-                        dri = DRI("com.sample"),
-                        documentation = mapOf(
-                            /* No documentation added, since in wrong package */
-                            sourceSet("A") to documentationNode("pre-existing:A:com.sample")
-                        ),
-                        sourceSets = setOf(sourceSet("A"), sourceSet("B"), sourceSet("C")),
-
-                        ),
-                    DPackage(
-                        dri = DRI("com.attach"),
-                        documentation = mapOf(
-                            /* Documentation added */
-                            sourceSet("A") to documentationNode("pre-existing:A:com.attach", "doc:A:com.attach"),
-                            sourceSet("B") to documentationNode("doc:B:com.attach")
-                        ),
-                        sourceSets = setOf(sourceSet("A"), sourceSet("B"), sourceSet("C")),
-                    ),
-                    DPackage(
-                        dri = DRI("com.attach.sub"),
-                        documentation = mapOf(
-                            /* Documentation added */
-                            sourceSet("A") to documentationNode(
-                                "pre-existing:A:com.attach.sub",
-                                "doc:A:com.attach.sub"
-                            ),
-                            /* Documentation added */
-                            sourceSet("B") to documentationNode(
-                                "pre-existing:B:com.attach.sub",
-                                "doc:B:com.attach.sub"
-                            ),
-                            /* No documentation added, since in wrong source set */
-                            sourceSet("C") to documentationNode("pre-existing:C:com.attach.sub")
-                        ),
-                        sourceSets = setOf(sourceSet("A"), sourceSet("B"), sourceSet("C")),
-                    )
-                )
-            ), result.single()
-        )
-    }
-
-}
diff --git a/plugins/base/src/test/kotlin/transformers/ModuleAndPackageDocumentationTransformerUnitTest.kt b/plugins/base/src/test/kotlin/transformers/ModuleAndPackageDocumentationTransformerUnitTest.kt
new file mode 100644
index 00000000..b75f8e5b
--- /dev/null
+++ b/plugins/base/src/test/kotlin/transformers/ModuleAndPackageDocumentationTransformerUnitTest.kt
@@ -0,0 +1,241 @@
+package transformers
+
+import org.jetbrains.dokka.base.transformers.documentables.ModuleAndPackageDocumentationReader
+import org.jetbrains.dokka.base.transformers.documentables.ModuleAndPackageDocumentationTransformer
+import org.jetbrains.dokka.links.DRI
+import org.jetbrains.dokka.model.DModule
+import org.jetbrains.dokka.model.DPackage
+import org.jetbrains.dokka.model.SourceSetDependent
+import org.jetbrains.dokka.model.doc.DocumentationNode
+import org.junit.jupiter.api.Assertions.assertEquals
+import org.junit.jupiter.api.Test
+import testApi.testRunner.documentationNode
+import testApi.testRunner.sourceSet
+
+
+class ModuleAndPackageDocumentationTransformerUnitTest {
+
+    @Test
+    fun `empty list of modules`() {
+        val transformer = ModuleAndPackageDocumentationTransformer(
+            object : ModuleAndPackageDocumentationReader {
+                override fun get(module: DModule): SourceSetDependent<DocumentationNode> = throw NotImplementedError()
+                override fun get(pkg: DPackage): SourceSetDependent<DocumentationNode> = throw NotImplementedError()
+            }
+        )
+
+        assertEquals(
+            emptyList<DModule>(), transformer(emptyList()),
+        )
+    }
+
+    @Test
+    fun `single module documentation`() {
+        val transformer = ModuleAndPackageDocumentationTransformer(
+            object : ModuleAndPackageDocumentationReader {
+                override fun get(pkg: DPackage): SourceSetDependent<DocumentationNode> = throw NotImplementedError()
+                override fun get(module: DModule): SourceSetDependent<DocumentationNode> {
+                    return module.sourceSets.associateWith { sourceSet ->
+                        documentationNode("doc" + sourceSet.displayName)
+                    }
+                }
+
+            }
+        )
+
+        val result = transformer(
+            listOf(
+                DModule(
+                    "ModuleName",
+                    documentation = emptyMap(),
+                    packages = emptyList(),
+                    sourceSets = setOf(
+                        sourceSet("A"),
+                        sourceSet("B")
+                    )
+                )
+            )
+        )
+
+        assertEquals(
+            DModule(
+                "ModuleName",
+                documentation = mapOf(
+                    sourceSet("A") to documentationNode("docA"),
+                    sourceSet("B") to documentationNode("docB")
+                ),
+                sourceSets = setOf(sourceSet("A"), sourceSet("B")),
+                packages = emptyList()
+            ),
+            result.single()
+        )
+
+    }
+
+    @Test
+    fun `merges with already existing module documentation`() {
+        val transformer = ModuleAndPackageDocumentationTransformer(
+            object : ModuleAndPackageDocumentationReader {
+                override fun get(pkg: DPackage): SourceSetDependent<DocumentationNode> = throw NotImplementedError()
+                override fun get(module: DModule): SourceSetDependent<DocumentationNode> {
+                    /* Only add documentation for first source set */
+                    return module.sourceSets.take(1).associateWith { sourceSet ->
+                        documentationNode("doc" + sourceSet.displayName)
+                    }
+                }
+            }
+        )
+
+        val result = transformer(
+            listOf(
+                DModule(
+                    "MyModule",
+                    documentation = mapOf(
+                        sourceSet("A") to documentationNode("pre-existing:A"),
+                        sourceSet("B") to documentationNode("pre-existing:B")
+                    ),
+                    sourceSets = setOf(sourceSet("A"), sourceSet("B")),
+                    packages = emptyList()
+                )
+            )
+        )
+
+        assertEquals(
+            DModule(
+                "MyModule",
+                documentation = mapOf(
+                    /* Expect previous documentation and newly attached one */
+                    sourceSet("A") to documentationNode("pre-existing:A", "docA"),
+                    /* Only first source set will get documentation attached */
+                    sourceSet("B") to documentationNode("pre-existing:B")
+                ),
+                sourceSets = setOf(sourceSet("A"), sourceSet("B")),
+                packages = emptyList()
+            ),
+            result.single()
+        )
+    }
+
+    @Test
+    fun `package documentation`() {
+        val transformer = ModuleAndPackageDocumentationTransformer(
+            object : ModuleAndPackageDocumentationReader {
+                override fun get(module: DModule): SourceSetDependent<DocumentationNode> = emptyMap()
+                override fun get(pkg: DPackage): SourceSetDependent<DocumentationNode> {
+                    /* Only attach documentation to packages with 'attach' */
+                    if ("attach" !in pkg.dri.packageName.orEmpty()) return emptyMap()
+                    /* Only attach documentation to two source sets */
+                    return pkg.sourceSets.take(2).associateWith { sourceSet ->
+                        documentationNode("doc:${sourceSet.displayName}:${pkg.dri.packageName}")
+                    }
+                }
+            }
+        )
+
+        val result = transformer(
+            listOf(
+                DModule(
+                    "MyModule",
+                    documentation = emptyMap(),
+                    sourceSets = emptySet(),
+                    packages = listOf(
+                        DPackage(
+                            dri = DRI("com.sample"),
+                            documentation = mapOf(
+                                sourceSet("A") to documentationNode("pre-existing:A:com.sample")
+                            ),
+                            sourceSets = setOf(sourceSet("A"), sourceSet("B"), sourceSet("C")),
+                        ),
+                        DPackage(
+                            dri = DRI("com.attach"),
+                            documentation = mapOf(
+                                sourceSet("A") to documentationNode("pre-existing:A:com.attach")
+                            ),
+                            sourceSets = setOf(sourceSet("A"), sourceSet("B"), sourceSet("C"))
+                        ),
+                        DPackage(
+                            dri = DRI("com.attach.sub"),
+                            documentation = mapOf(
+                                sourceSet("A") to documentationNode("pre-existing:A:com.attach.sub"),
+                                sourceSet("B") to documentationNode("pre-existing:B:com.attach.sub"),
+                                sourceSet("C") to documentationNode("pre-existing:C:com.attach.sub")
+                            ),
+                            sourceSets = setOf(sourceSet("A"), sourceSet("B"), sourceSet("C")),
+                        )
+                    )
+                )
+            )
+        )
+
+        result.single().packages.forEach { pkg ->
+            assertEquals(
+                setOf(sourceSet("A"), sourceSet("B"), sourceSet("C")), pkg.sourceSets,
+                "Expected source sets A, B, C for package ${pkg.dri.packageName}"
+            )
+        }
+
+        val comSample = result.single().packages.single { it.dri.packageName == "com.sample" }
+        assertEquals(
+            mapOf(sourceSet("A") to documentationNode("pre-existing:A:com.sample")),
+            comSample.documentation,
+            "Expected no documentation added to package 'com.sample' because of wrong package"
+        )
+
+        val comAttach = result.single().packages.single { it.dri.packageName == "com.attach" }
+        assertEquals(
+            mapOf(
+                sourceSet("A") to documentationNode("pre-existing:A:com.attach", "doc:A:com.attach"),
+                sourceSet("B") to documentationNode("doc:B:com.attach")
+            ),
+            comAttach.documentation,
+            "Expected documentation added to source sets A and B"
+        )
+
+        assertEquals(
+            DModule(
+                "MyModule",
+                documentation = emptyMap(),
+                sourceSets = emptySet(),
+                packages = listOf(
+                    DPackage(
+                        dri = DRI("com.sample"),
+                        documentation = mapOf(
+                            /* No documentation added, since in wrong package */
+                            sourceSet("A") to documentationNode("pre-existing:A:com.sample")
+                        ),
+                        sourceSets = setOf(sourceSet("A"), sourceSet("B"), sourceSet("C")),
+
+                        ),
+                    DPackage(
+                        dri = DRI("com.attach"),
+                        documentation = mapOf(
+                            /* Documentation added */
+                            sourceSet("A") to documentationNode("pre-existing:A:com.attach", "doc:A:com.attach"),
+                            sourceSet("B") to documentationNode("doc:B:com.attach")
+                        ),
+                        sourceSets = setOf(sourceSet("A"), sourceSet("B"), sourceSet("C")),
+                    ),
+                    DPackage(
+                        dri = DRI("com.attach.sub"),
+                        documentation = mapOf(
+                            /* Documentation added */
+                            sourceSet("A") to documentationNode(
+                                "pre-existing:A:com.attach.sub",
+                                "doc:A:com.attach.sub"
+                            ),
+                            /* Documentation added */
+                            sourceSet("B") to documentationNode(
+                                "pre-existing:B:com.attach.sub",
+                                "doc:B:com.attach.sub"
+                            ),
+                            /* No documentation added, since in wrong source set */
+                            sourceSet("C") to documentationNode("pre-existing:C:com.attach.sub")
+                        ),
+                        sourceSets = setOf(sourceSet("A"), sourceSet("B"), sourceSet("C")),
+                    )
+                )
+            ), result.single()
+        )
+    }
+
+}
-- 
cgit