diff options
20 files changed, 371 insertions, 572 deletions
diff --git a/core/src/main/kotlin/DokkaBootstrapImpl.kt b/core/src/main/kotlin/DokkaBootstrapImpl.kt index d11f1623..ccd87363 100644 --- a/core/src/main/kotlin/DokkaBootstrapImpl.kt +++ b/core/src/main/kotlin/DokkaBootstrapImpl.kt @@ -47,7 +47,7 @@ class DokkaBootstrapImpl : DokkaBootstrap { } } - lateinit var generator: DokkaGenerator + private lateinit var generator: DokkaGenerator val gson = Gson() fun configure(logger: DokkaLogger, configuration: DokkaConfigurationImpl) = with(configuration) { diff --git a/core/src/main/kotlin/DokkaGenerator.kt b/core/src/main/kotlin/DokkaGenerator.kt index 845ad53f..0812dd5b 100644 --- a/core/src/main/kotlin/DokkaGenerator.kt +++ b/core/src/main/kotlin/DokkaGenerator.kt @@ -3,6 +3,7 @@ package org.jetbrains.dokka import org.jetbrains.dokka.analysis.AnalysisEnvironment import org.jetbrains.dokka.analysis.DokkaResolutionFacade import org.jetbrains.dokka.model.Module +import org.jetbrains.dokka.pages.ModulePageNode import org.jetbrains.dokka.pages.PlatformData import org.jetbrains.dokka.plugability.DokkaContext import org.jetbrains.dokka.plugability.single @@ -16,40 +17,81 @@ import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment import org.jetbrains.kotlin.utils.PathUtil import java.io.File -open class DokkaGenerator( +/** + * DokkaGenerator is the main entry point for generating documentation + * [generate] method has been split into submethods for test reasons + */ +class DokkaGenerator( private val configuration: DokkaConfiguration, private val logger: DokkaLogger ) { + fun generate() { + logger.progress("Setting up analysis environments") + val platforms: Map<PlatformData, EnvironmentAndFacade> = setUpAnalysis(configuration) - open fun generate() { - logger.debug("Setting up analysis environments") - val platforms: Map<PlatformData, EnvironmentAndFacade> = configuration.passesConfigurations.map { - PlatformData(it.moduleName, it.analysisPlatform, it.targets) to createEnvironmentAndFacade(it) - }.toMap() + logger.progress("Initializing plugins") + val context = initializePlugins(configuration.pluginsClasspath, logger, platforms) + + logger.progress("Creating documentation models") + val modulesFromPlatforms = createDocumentationModels(platforms, context) - logger.debug("Initializing plugins") - val context = DokkaContext.create(configuration.pluginsClasspath, logger, platforms) + logger.progress("Merging documentation models") + val documentationModel = mergeDocumentationModels(modulesFromPlatforms, context) - logger.debug("Creating documentation models") - val modulesFromPlatforms = platforms.map { (pdata, _) -> translateDescriptors(pdata, context) } + logger.progress("Transforming documentation model") + val transformedDocumentation = transformDocumentationModel(documentationModel, context) - logger.debug("Merging documentation models") - val documentationModel = context.single(CoreExtensions.documentationMerger) - .invoke(modulesFromPlatforms, context) + logger.progress("Creating pages") + val pages = createPages(transformedDocumentation, context) - logger.debug("Transforming documentation model") - val transformedDocumentation = context[CoreExtensions.documentationTransformer] - .fold(documentationModel) { acc, t -> t(acc, context) } + logger.progress("Transforming pages") + val transformedPages = transformPages(pages, context) - logger.debug("Creating pages") - val pages = context.single(CoreExtensions.documentationToPageTranslator) - .invoke(transformedDocumentation, context) + logger.progress("Rendering") + render(transformedPages, configuration, context) + } - logger.debug("Transforming pages") - val transformedPages = context[CoreExtensions.pageTransformer] - .fold(pages) { acc, t -> t(acc, context) } + internal fun setUpAnalysis(configuration: DokkaConfiguration): Map<PlatformData, EnvironmentAndFacade> = + configuration.passesConfigurations.map { + PlatformData(it.moduleName, it.analysisPlatform, it.targets) to createEnvironmentAndFacade(it) + }.toMap() - logger.debug("Rendering") + internal fun initializePlugins( + pluginsClasspath: List<File>, + logger: DokkaLogger, + platforms: Map<PlatformData, EnvironmentAndFacade> + ) = DokkaContext.create(pluginsClasspath, logger, platforms) + + internal fun createDocumentationModels( + platforms: Map<PlatformData, EnvironmentAndFacade>, + context: DokkaContext + ) = platforms.map { (pdata, _) -> translateDescriptors(pdata, context) } + + internal fun mergeDocumentationModels( + modulesFromPlatforms: List<Module>, + context: DokkaContext + ) = context.single(CoreExtensions.documentationMerger).invoke(modulesFromPlatforms, context) + + internal fun transformDocumentationModel( + documentationModel: Module, + context: DokkaContext + ) = context[CoreExtensions.documentationTransformer].fold(documentationModel) { acc, t -> t(acc, context) } + + internal fun createPages( + transformedDocumentation: Module, + context: DokkaContext + ) = context.single(CoreExtensions.documentationToPageTranslator).invoke(transformedDocumentation, context) + + internal fun transformPages( + pages: ModulePageNode, + context: DokkaContext + ) = context[CoreExtensions.pageTransformer].fold(pages) { acc, t -> t(acc, context) } + + internal fun render( + transformedPages: ModulePageNode, + configuration: DokkaConfiguration, + context: DokkaContext + ) { val fileWriter = FileWriter(configuration.outputDir, "") val locationProvider = context.single(CoreExtensions.locationProviderFactory) .invoke(transformedPages, configuration, context) @@ -59,7 +101,7 @@ open class DokkaGenerator( renderer.render(transformedPages) } - protected fun createEnvironmentAndFacade(pass: DokkaConfiguration.PassConfiguration): EnvironmentAndFacade = + private fun createEnvironmentAndFacade(pass: DokkaConfiguration.PassConfiguration): EnvironmentAndFacade = AnalysisEnvironment(DokkaMessageCollector(logger), pass.analysisPlatform).run { if (analysisPlatform == Platform.jvm) { addClasspath(PathUtil.getJdkClassesRootsFromCurrentJre()) @@ -75,7 +117,7 @@ open class DokkaGenerator( EnvironmentAndFacade(environment, facade) } - protected fun translateDescriptors(platformData: PlatformData, context: DokkaContext): Module { + private fun translateDescriptors(platformData: PlatformData, context: DokkaContext): Module { val (environment, facade) = context.platforms.getValue(platformData) val packageFragments = environment.getSourceFiles().asSequence() @@ -88,7 +130,7 @@ open class DokkaGenerator( .invoke(platformData.name, packageFragments, platformData, context) } - protected class DokkaMessageCollector(private val logger: DokkaLogger) : MessageCollector { + private class DokkaMessageCollector(private val logger: DokkaLogger) : MessageCollector { override fun clear() { seenErrors = false } diff --git a/core/src/test/kotlin/externalLocationProviders/ExternalLocationProviderTest.kt b/core/src/test/kotlin/externalLocationProviders/ExternalLocationProviderTest.kt deleted file mode 100644 index 5a1822a6..00000000 --- a/core/src/test/kotlin/externalLocationProviders/ExternalLocationProviderTest.kt +++ /dev/null @@ -1,25 +0,0 @@ -package org.jetbrains.dokka.tests.externalLocationProviders - -import junit.framework.Assert.assertEquals -import org.jetbrains.dokka.DokkaConfiguration -import org.jetbrains.dokka.links.DRI -import org.jetbrains.dokka.resolvers.ExternalLocationProvider -import org.junit.Test - - -class ExternalLocationProviderTest { - val stdlibLink = DokkaConfiguration.ExternalDocumentationLink.Builder("https://kotlinlang.org/api/latest/jvm/stdlib/").build() -// @Test fun kotlinString() { -// val dri = DRI("kotlin", "String") -// val link = ExternalLocationProvider.getLocation(dri, listOf(stdlibLink.packageListUrl)) -// assertEquals("kotlin/-string/index.html", link) -// } -// -// @Test fun kotlinCompareTo() { -// val dri = DRI("kotlin", "String", "compareTo", "#Int#String") -// val link = ExternalLocationProvider.getLocation(dri, listOf(stdlibLink.packageListUrl)) -// assertEquals("kotlin/-string/compare-to.html", link) -// } - -} - diff --git a/core/src/test/kotlin/generator/DokkaTestGenerator.kt b/core/src/test/kotlin/generator/DokkaTestGenerator.kt deleted file mode 100644 index 9ceeeadf..00000000 --- a/core/src/test/kotlin/generator/DokkaTestGenerator.kt +++ /dev/null @@ -1,78 +0,0 @@ -package org.jetbrains.dokka - -import org.jetbrains.dokka.model.Module -import org.jetbrains.dokka.pages.ModulePageNode -import org.jetbrains.dokka.pages.PlatformData -import org.jetbrains.dokka.plugability.DokkaContext -import org.jetbrains.dokka.plugability.single -import org.jetbrains.dokka.renderers.FileWriter -import org.jetbrains.dokka.utilities.DokkaLogger - -class DokkaTestGenerator( - private val configuration: DokkaConfiguration, - private val logger: DokkaLogger, - private val setupTest: (Map<PlatformData, EnvironmentAndFacade>) -> Unit?, - private val pluginInitTest: (DokkaContext) -> Unit?, - private val documentablesCreationTest: (List<Module>) -> Unit?, - private val documentablesMergingTest: (Module) -> Unit?, - private val documentablesTransformationTest: (Module) -> Unit?, - private val pagesCreationTest: (ModulePageNode) -> Unit?, - private val pagesTransformationTest: (ModulePageNode) -> Unit?, - private val finalTest: (DokkaConfiguration) -> Unit? -) : DokkaGenerator(configuration, logger) { - - override fun generate() { - logger.debug("Setting up analysis environments") - val platforms = configuration.passesConfigurations.map { - PlatformData(it.moduleName, it.analysisPlatform, it.targets) to createEnvironmentAndFacade(it) - }.toMap() - - setupTest(platforms) - - logger.debug("Initializing plugins") - val context = DokkaContext.create(configuration.pluginsClasspath, logger, platforms) - - pluginInitTest(context) - - logger.debug("Creating documentation models") - val modulesFromPlatforms = platforms.map { (pdata, _) -> translateDescriptors(pdata, context) } - - documentablesCreationTest(modulesFromPlatforms) - - logger.debug("Merging documentation models") - val documentationModel = context.single(CoreExtensions.documentationMerger) - .invoke(modulesFromPlatforms, context) - - documentablesMergingTest(documentationModel) - - logger.debug("Transforming documentation model") - val transformedDocumentation = context[CoreExtensions.documentationTransformer] - .fold(documentationModel) { acc, t -> t(acc, context) } - - documentablesTransformationTest(transformedDocumentation) - - logger.debug("Creating pages") - val pages = context.single(CoreExtensions.documentationToPageTranslator) - .invoke(transformedDocumentation, context) - - pagesCreationTest(pages) - - logger.debug("Transforming pages") - val transformedPages = context[CoreExtensions.pageTransformer] - .fold(pages) { acc, t -> t(acc, context) } - - pagesTransformationTest(transformedPages) - - logger.debug("Rendering") - val fileWriter = FileWriter(configuration.outputDir, "") - val locationProvider = context.single(CoreExtensions.locationProviderFactory) - .invoke(transformedPages, configuration, context) - val renderer = context.single(CoreExtensions.rendererFactory) - .invoke(fileWriter, locationProvider, context) - - renderer.render(transformedPages) - - finalTest(configuration) - } - -}
\ No newline at end of file diff --git a/core/src/test/kotlin/generator/TestRunner.kt b/core/src/test/kotlin/generator/TestRunner.kt deleted file mode 100644 index 305996f8..00000000 --- a/core/src/test/kotlin/generator/TestRunner.kt +++ /dev/null @@ -1,157 +0,0 @@ -package generator - -import com.intellij.util.io.createDirectories -import com.intellij.util.io.exists -import org.jetbrains.dokka.DokkaConfiguration -import org.jetbrains.dokka.DokkaTestGenerator -import org.jetbrains.dokka.EnvironmentAndFacade -import org.jetbrains.dokka.SourceRootImpl -import org.jetbrains.dokka.model.Module -import org.jetbrains.dokka.pages.ModulePageNode -import org.jetbrains.dokka.pages.PlatformData -import org.jetbrains.dokka.plugability.DokkaContext -import org.jetbrains.dokka.utilities.DokkaConsoleLogger -import org.jetbrains.dokka.utilities.DokkaLogger -import utils.Builders -import java.io.File -import java.nio.charset.Charset -import java.nio.file.Files -import java.nio.file.Path -import java.nio.file.Paths - -data class ConfigParams(val name: String, val root: Path, val out: Path) - -object TestRunner { - - private val createdDirs: MutableList<File> = mutableListOf() - - fun cleanup() { - createdDirs.forEach { f -> f.takeIf { it.exists() }?.deleteRecursively() } - createdDirs.clear() - } - - fun srcSetFromName(name: String) = - ClassLoader.getSystemResource("sourceSets/$name").takeIf { it != null } - ?.let { Paths.get(it.toURI()).toString() } - - fun testFromSourceSets( - name: String, - configBuilder: Builders.ConfigBuilder, - setupTest: (Map<PlatformData, EnvironmentAndFacade>) -> Unit? = {}, - pluginInitTest: (DokkaContext) -> Unit? = {}, - documentablesCreationTest: (List<Module>) -> Unit? = {}, - documentablesMergingTest: (Module) -> Unit? = {}, - documentablesTransformationTest: (Module) -> Unit? = {}, - pagesCreationTest: (ModulePageNode) -> Unit? = {}, - pagesTransformationTest: (ModulePageNode) -> Unit? = {}, - finalTest: (DokkaConfiguration) -> Unit? = {}, - logger: DokkaLogger = DokkaConsoleLogger - ) { - val (out, _) = getTestDirs(name) - DokkaTestGenerator( - configBuilder(out.toString()), - logger, - setupTest, - pluginInitTest, - documentablesCreationTest, - documentablesMergingTest, - documentablesTransformationTest, - pagesCreationTest, - pagesTransformationTest, - finalTest - ).generate() - } - - fun testInline( - name: String, - query: String, - config: (ConfigParams) -> DokkaConfiguration, - setupTest: (Map<PlatformData, EnvironmentAndFacade>) -> Unit? = {}, - pluginInitTest: (DokkaContext) -> Unit? = {}, - documentablesCreationTest: (List<Module>) -> Unit? = {}, - documentablesMergingTest: (Module) -> Unit? = {}, - documentablesTransformationTest: (Module) -> Unit? = {}, - pagesCreationTest: (ModulePageNode) -> Unit? = {}, - pagesTransformationTest: (ModulePageNode) -> Unit? = {}, - finalTest: (DokkaConfiguration) -> Unit? = {}, - logger: DokkaLogger = DokkaConsoleLogger - ) { - - val (root, out) = getTestDirs(name) - query.toFileMap().materializeFiles(root) - DokkaTestGenerator( - config(ConfigParams(name, root, out)), - logger, - setupTest, - pluginInitTest, - documentablesCreationTest, - documentablesMergingTest, - documentablesTransformationTest, - pagesCreationTest, - pagesTransformationTest, - finalTest - ).generate() - } - - fun generatePassesForPlatforms( - testName: String, - platforms: List<String>, - passBuilder: Builders.PassBuilder - ): List<Builders.PassBuilder> { - fun File.nameLower() = this.name.toLowerCase() - fun File.isCommon() = this.nameLower().contains("common") - fun File.getPlatforms(platforms: List<String>) = - platforms.filter { this.nameLower().contains(it.toLowerCase()) } - - - val testSrcDirs = - srcSetFromName(testName)?.let { fName -> - File(fName).listFiles()?.filter { it.isDirectory } - } ?: emptyList() - - val dirs = - platforms.associateWith { platform -> - testSrcDirs.filter { file -> - platform == "common" && file.isCommon() && file.getPlatforms(platforms).size == 1 || - platform != "common" && file.nameLower().contains(platform.toLowerCase()) - }.map { it.path } - }.filter { (_, value) -> value.isNotEmpty() } - - return dirs.map { (platform, srcs) -> - passBuilder.copy(moduleName = "$testName-$platform", analysisPlatform = platform, sourceRoots = srcs) - } - } - - fun getTestDirs(name: String) = - Files.createTempDirectory(name).also { it.takeIf { it.exists() }?.deleteContents() } - .let { it to it.resolve("out").also { it.createDirectories() } } - .also { createdDirs += it.first.toFile() } - - fun String.toFileMap(): Map<String, String> = this.replace("\r\n", "\n") - .split("\n/") - .map {fileString -> - fileString.split("\n", limit = 2) - .let { - it.first().trim().removePrefix("/") to it.last().trim() - } - } - .toMap() - - fun Map<String, String>.materializeFiles( - root: Path = Paths.get("."), - charset: Charset = Charset.forName("utf-8") - ) = this.map { (path, content) -> - val file = root.resolve(path) - Files.createDirectories(file.parent) - Files.write(file, content.toByteArray(charset)) - } - - fun File.deleteContents() { - this.listFiles()?.forEach { it.deleteRecursively() } - } - - fun Path.deleteContents() { - this.toFile().deleteContents() - } - -}
\ No newline at end of file diff --git a/core/src/test/kotlin/generator/test/GeneratorTest.kt b/core/src/test/kotlin/generator/test/GeneratorTest.kt deleted file mode 100644 index 97eb8b92..00000000 --- a/core/src/test/kotlin/generator/test/GeneratorTest.kt +++ /dev/null @@ -1,62 +0,0 @@ -package generator.test - -import generator.ConfigParams -import generator.TestRunner -import org.jetbrains.dokka.* -import org.jetbrains.dokka.utilities.DokkaConsoleLogger -import org.junit.AfterClass -import org.junit.Rule -import org.junit.Test -import org.junit.rules.TestName -import utils.Builders - -class GeneratorTest { - - companion object { - @AfterClass @JvmStatic - fun cleanup() = TestRunner.cleanup() - } - - val builder = Builders.ConfigBuilder( - format = "html", - generateIndexPages = true - ) - - val name: TestName = TestName() - @Rule - fun name(): TestName = name - - val logger = DokkaConsoleLogger - fun config(): (ConfigParams) -> DokkaConfiguration = { (name, root, out) -> - builder.copy( - passesConfigurations = listOf( - Builders.PassBuilder( - moduleName = name, - sourceRoots = listOf(root.toString()), - analysisPlatform = "jvm", - targets = listOf("jvm") - ) - ) - )(out.toString()) - } - - @Test - fun test1() { - TestRunner.testInline( - name = name.methodName, - query = """ - |/src/main/kotlin/test/Test.kt - |package test - | - |object Test { - | fun test2(str: String): Unit {println(str)} - |} - """.trimMargin(), - pagesCreationTest = { pages -> - val test = pages.parentMap.size == 7 - if (!test) println(pages.parentMap.size) - assert(test) - }, config = config(), logger = logger - ) - } -}
\ No newline at end of file diff --git a/core/src/test/kotlin/generator/test/MultiplatformTest.kt b/core/src/test/kotlin/generator/test/MultiplatformTest.kt deleted file mode 100644 index 2e28797d..00000000 --- a/core/src/test/kotlin/generator/test/MultiplatformTest.kt +++ /dev/null @@ -1,52 +0,0 @@ -package generator.test - -import generator.TestRunner -import org.jetbrains.dokka.Platform -import org.jetbrains.dokka.utilities.DokkaConsoleLogger -import org.junit.AfterClass -import org.junit.Rule -import org.junit.Test -import org.junit.rules.TestName -import utils.Builders - -class MultiplatformTest { - - companion object { - @AfterClass @JvmStatic - fun cleanup() = - TestRunner.cleanup() - } - - val platforms = Platform.values().map { it.name } - - val configBuilder = Builders.ConfigBuilder( - format = "html", - generateIndexPages = true - ) - val passBuilder = Builders.PassBuilder(targets = platforms) - - val name: TestName = TestName() - @Rule - fun name(): TestName = name - - val logger = DokkaConsoleLogger - - @Test - fun example() { - val testName = name.methodName - - val passBuilders = - TestRunner.generatePassesForPlatforms(testName, platforms, passBuilder) - - TestRunner.testFromSourceSets( - name = testName, - configBuilder = configBuilder.copy(passesConfigurations = passBuilders), - pagesTransformationTest = { assert(it.children.size == 2) }, - finalTest = { - assert(it.passesConfigurations.size == 3) - }, - logger = logger - ) - } - -}
\ No newline at end of file diff --git a/core/src/test/kotlin/linkResolvers/LinkResolverTest.kt b/core/src/test/kotlin/linkResolvers/LinkResolverTest.kt deleted file mode 100644 index b2cccce2..00000000 --- a/core/src/test/kotlin/linkResolvers/LinkResolverTest.kt +++ /dev/null @@ -1,92 +0,0 @@ -package org.jetbrains.dokka.tests.linkResolvers -// -//import junit.framework.Assert.assertEquals -//import org.jetbrains.dokka.testApi.DokkaConfigurationImpl -//import org.jetbrains.dokka.Platform -//import org.jetbrains.dokka.links.DRI -//import org.jetbrains.dokka.pages.* -//import org.jetbrains.dokka.renderers.FileWriter -//import org.jetbrains.dokka.renderers.NewHtmlRenderer -//import org.jetbrains.dokka.resolvers.DefaultLocationProvider -//import org.junit.Test -// -// -//class LinkResolverTest { -// -// fun createModel(): ModulePageNode { -// val platform = listOf(PlatformData("jvm", Platform.jvm)) -// -// val moduleSymbol = ContentSymbol( -// listOf(ContentText("moduleName", platform)), -// platform) -// -// val packageDRI = DRI("packageName") -// -// val module = ModulePageNode("", -// listOf(moduleSymbol, ContentBlock( -// "packages", -// listOf(ContentGroup(listOf(ContentLink("packageName", packageDRI, platform)), platform)), -// platform) -// ), -// null) -// -// val packageSymbol = ContentSymbol( -// listOf(ContentText("package moduleName.packageName", platform)), -// platform) -// -// val packageNode = PackagePageNode("packageName", listOf(packageSymbol), module, DRI("packageName")) -// -// val classSymbol = ContentSymbol( -// listOf(ContentText("class ClassName()", platform)), -// platform) -// -// val classNode = ClassPageNode("className", listOf(classSymbol), packageNode, DRI("packageName", "className")) -// -// val memberSymbol = ContentSymbol( -// listOf(ContentText("fun funName(): String", platform)), -// platform) -// -// val memberText = ContentText("This is some docs for funName", platform) -// -// val memberNode = MemberPageNode("funName", -// listOf(memberSymbol, ContentComment(listOf(memberText), platform)), -// classNode, -// DRI("packageName", "className", "funName", "...")) -// -// module.appendChild(packageNode) -// packageNode.appendChild(classNode) -// classNode.appendChild(memberNode) -// return module -// } -// -// @Test fun memberLink() { -// val model = createModel() -// val linkResolver = DefaultLocationProvider(model, DokkaConfigurationImpl()) -// val link = linkResolver.resolve(model.children.first().children.first().children.first()) -// assertEquals("/--root--/package-name/class-name/fun-name", link) -// } -// -// @Test fun classLink() { -// val model = createModel() -// val linkResolver = DefaultLocationProvider(model, DokkaConfigurationImpl()) -// val link = linkResolver.resolve(model.children.first().children.first()) -// assertEquals("/--root--/package-name/class-name/index", link) -// } -// -// @Test fun moduleLink() { -// val model = createModel() -// val linkResolver = DefaultLocationProvider(model, DokkaConfigurationImpl()) -// val link = linkResolver.resolve(model) -// assertEquals("/--root--/index", link) -// } -// -// @Test fun writeToFile() { -// val model = createModel() -// val linkResolver = DefaultLocationProvider(model, DokkaConfigurationImpl()) -// val fileWriter = FileWriter("/Users/kamildoleglo/IdeaProjects/dokka/build/dokka", ".html") -// val renderer = NewHtmlRenderer("/Users/kamildoleglo/IdeaProjects/dokka/build/dokka", fileWriter, linkResolver) -// renderer.render(model) -// } -// -//} -// diff --git a/core/src/test/kotlin/multiplatform/BasicMultiplatformTest.kt b/core/src/test/kotlin/multiplatform/BasicMultiplatformTest.kt new file mode 100644 index 00000000..da5103c2 --- /dev/null +++ b/core/src/test/kotlin/multiplatform/BasicMultiplatformTest.kt @@ -0,0 +1,55 @@ +package multiplatform + +import org.junit.Test +import testRunner.AbstractCoreTest +import kotlin.test.assertEquals + +class BasicMultiplatformTest : AbstractCoreTest() { + + @Test + fun dataTestExample() { + val testDataDir = getTestDataDir("multiplatform/basicMultiplatformTest").toAbsolutePath() + + val configuration = dokkaConfiguration { + passes { + pass { + sourceRoots = listOf("$testDataDir/jvmMain/") + } + } + } + + testFromData(configuration) { + pagesTransformationStage = { + assertEquals(6, it.children.firstOrNull()?.children?.count() ?: 0) + } + } + } + + @Test + fun inlineTestExample() { + val configuration = dokkaConfiguration { + passes { + pass { + sourceRoots = listOf("src/main/kotlin/multiplatform/Test.kt") + } + } + } + + testInline( + """ + |/src/main/kotlin/multiplatform/Test.kt + |package multiplatform + | + |object Test { + | fun test2(str: String): Unit {println(str)} + |} + """.trimMargin(), + configuration + ) { + pagesGenerationStage = { + println(it.dri) + assertEquals(7, it.parentMap.size) + } + } + } +}
\ No newline at end of file diff --git a/core/src/test/kotlin/testRunner/DokkaTestGenerator.kt b/core/src/test/kotlin/testRunner/DokkaTestGenerator.kt new file mode 100644 index 00000000..e6f6edee --- /dev/null +++ b/core/src/test/kotlin/testRunner/DokkaTestGenerator.kt @@ -0,0 +1,41 @@ +package testRunner + +import org.jetbrains.dokka.DokkaConfiguration +import org.jetbrains.dokka.DokkaGenerator +import org.jetbrains.dokka.EnvironmentAndFacade +import org.jetbrains.dokka.pages.PlatformData +import org.jetbrains.dokka.utilities.DokkaLogger + +internal class DokkaTestGenerator( + private val configuration: DokkaConfiguration, + private val logger: DokkaLogger, + private val testMethods: TestMethods +) { + + fun generate() = with(testMethods) { + val dokkaGenerator = DokkaGenerator(configuration, logger) + + val platforms: Map<PlatformData, EnvironmentAndFacade> = dokkaGenerator.setUpAnalysis(configuration) + analysisSetupStage(platforms) + + val context = dokkaGenerator.initializePlugins(configuration.pluginsClasspath, logger, platforms) + pluginsSetupStage(context) + + val modulesFromPlatforms = dokkaGenerator.createDocumentationModels(platforms, context) + documentablesCreationStage(modulesFromPlatforms) + + val documentationModel = dokkaGenerator.mergeDocumentationModels(modulesFromPlatforms, context) + documentablesMergingStage(documentationModel) + + val transformedDocumentation = dokkaGenerator.transformDocumentationModel(documentationModel, context) + documentablesTransformationStage(transformedDocumentation) + + val pages = dokkaGenerator.createPages(transformedDocumentation, context) + pagesGenerationStage(pages) + + val transformedPages = dokkaGenerator.transformPages(pages, context) + pagesTransformationStage(transformedPages) + + dokkaGenerator.render(transformedPages, configuration, context) + } +}
\ No newline at end of file diff --git a/core/src/test/kotlin/testRunner/TestRunner.kt b/core/src/test/kotlin/testRunner/TestRunner.kt new file mode 100644 index 00000000..a2b0f96c --- /dev/null +++ b/core/src/test/kotlin/testRunner/TestRunner.kt @@ -0,0 +1,206 @@ +package testRunner + +import org.jetbrains.dokka.* +import org.jetbrains.dokka.model.Module +import org.jetbrains.dokka.pages.ModulePageNode +import org.jetbrains.dokka.pages.PlatformData +import org.jetbrains.dokka.plugability.DokkaContext +import org.jetbrains.dokka.utilities.DokkaConsoleLogger +import org.junit.rules.TemporaryFolder +import java.io.File +import java.nio.charset.Charset +import java.nio.file.Files +import java.nio.file.InvalidPathException +import java.nio.file.Path +import java.nio.file.Paths + +// TODO: take dokka configuration from file +abstract class AbstractCoreTest { + protected val logger = DokkaConsoleLogger + + protected fun getTestDataDir(name: String) = + File("src/test/resources/$name").takeIf { it.exists() }?.toPath() + ?: throw InvalidPathException(name, "Cannot be found") + + protected fun testFromData( + configuration: DokkaConfigurationImpl, + cleanupOutput: Boolean = true, + block: TestBuilder.() -> Unit + ) { + val testMethods = TestBuilder().apply(block).build() + val tempDir = getTempDir(cleanupOutput) + if (!cleanupOutput) + logger.info("Output generated under: ${tempDir.root.absolutePath}") + val newConfiguration = + configuration.copy( + outputDir = tempDir.root.toPath().toAbsolutePath().toString() + ) + DokkaTestGenerator(newConfiguration, logger, testMethods).generate() + } + + protected fun testInline( + query: String, + configuration: DokkaConfigurationImpl, + cleanupOutput: Boolean = true, + block: TestBuilder.() -> Unit + ) { + val testMethods = TestBuilder().apply(block).build() + val testDirPath = getTempDir(cleanupOutput).root.toPath() + val fileMap = query.toFileMap() + fileMap.materializeFiles(testDirPath.toAbsolutePath()) + if (!cleanupOutput) + logger.info("Output generated under: ${testDirPath.toAbsolutePath()}") + val newConfiguration = + configuration.copy( + outputDir = testDirPath.toAbsolutePath().toString(), + passesConfigurations = configuration.passesConfigurations + .map { it.copy(sourceRoots = it.sourceRoots.map { it.copy(path = "${testDirPath.toAbsolutePath()}/${it.path}") }) } + ) + DokkaTestGenerator(newConfiguration, logger, testMethods).generate() + } + + private fun String.toFileMap(): Map<String, String> = this.replace("\r\n", "\n") + .split("\n/") + .map { fileString -> + fileString.split("\n", limit = 2) + .let { + it.first().trim().removePrefix("/") to it.last().trim() + } + }.toMap() + + private fun Map<String, String>.materializeFiles( + root: Path = Paths.get("."), + charset: Charset = Charset.forName("utf-8") + ) = this.map { (path, content) -> + val file = root.resolve(path) + Files.createDirectories(file.parent) + Files.write(file, content.toByteArray(charset)) + } + + private fun getTempDir(cleanupOutput: Boolean) = if (cleanupOutput) { + TemporaryFolder().apply { create() } + } else { + object : TemporaryFolder() { + override fun after() {} + }.apply { create() } + } + + protected class TestBuilder { + var analysisSetupStage: (Map<PlatformData, EnvironmentAndFacade>) -> Unit = {} + var pluginsSetupStage: (DokkaContext) -> Unit = {} + var documentablesCreationStage: (List<Module>) -> Unit = {} + var documentablesMergingStage: (Module) -> Unit = {} + var documentablesTransformationStage: (Module) -> Unit = {} + var pagesGenerationStage: (ModulePageNode) -> Unit = {} + var pagesTransformationStage: (ModulePageNode) -> Unit = {} + + fun build() = TestMethods( + analysisSetupStage, + pluginsSetupStage, + documentablesCreationStage, + documentablesMergingStage, + documentablesTransformationStage, + pagesGenerationStage, + pagesTransformationStage + ) + } + + protected fun dokkaConfiguration(block: DokkaConfigurationBuilder.() -> Unit): DokkaConfigurationImpl = + DokkaConfigurationBuilder().apply(block).build() + + @DslMarker + protected annotation class DokkaConfigurationDsl + + @DokkaConfigurationDsl + protected class DokkaConfigurationBuilder { + var outputDir: String = "out" + var format: String = "html" + var generateIndexPages: Boolean = true + var cacheRoot: String? = null + var pluginsClasspath: List<File> = emptyList() + private val passesConfigurations = mutableListOf<PassConfigurationImpl>() + + fun build() = DokkaConfigurationImpl( + outputDir = outputDir, + format = format, + generateIndexPages = generateIndexPages, + cacheRoot = cacheRoot, + impliedPlatforms = emptyList(), + passesConfigurations = passesConfigurations, + pluginsClasspath = pluginsClasspath + ) + + fun passes(block: Passes.() -> Unit) { + passesConfigurations.addAll(Passes().apply(block)) + } + } + + @DokkaConfigurationDsl + protected class Passes : ArrayList<PassConfigurationImpl>() { + fun pass(block: DokkaPassConfigurationBuilder.() -> Unit) = + add(DokkaPassConfigurationBuilder().apply(block).build()) + } + + @DokkaConfigurationDsl + protected class DokkaPassConfigurationBuilder( + var moduleName: String = "root", + var classpath: List<String> = emptyList(), + var sourceRoots: List<String> = emptyList(), + var samples: List<String> = emptyList(), + var includes: List<String> = emptyList(), + var includeNonPublic: Boolean = true, + var includeRootPackage: Boolean = true, + var reportUndocumented: Boolean = false, + var skipEmptyPackages: Boolean = false, + var skipDeprecated: Boolean = false, + var jdkVersion: Int = 6, + var languageVersion: String? = null, + var apiVersion: String? = null, + var noStdlibLink: Boolean = false, + var noJdkLink: Boolean = false, + var suppressedFiles: List<String> = emptyList(), + var collectInheritedExtensionsFromLibraries: Boolean = true, + var analysisPlatform: String = "jvm", + var targets: List<String> = listOf("jvm"), + var sinceKotlin: String? = null, + var perPackageOptions: List<PackageOptionsImpl> = emptyList(), + var externalDocumentationLinks: List<ExternalDocumentationLinkImpl> = emptyList(), + var sourceLinks: List<SourceLinkDefinitionImpl> = emptyList() + ) { + fun build() = PassConfigurationImpl( + moduleName = moduleName, + classpath = classpath, + sourceRoots = sourceRoots.map { SourceRootImpl(it) }, + samples = samples, + includes = includes, + includeNonPublic = includeNonPublic, + includeRootPackage = includeRootPackage, + reportUndocumented = reportUndocumented, + skipEmptyPackages = skipEmptyPackages, + skipDeprecated = skipDeprecated, + jdkVersion = jdkVersion, + languageVersion = languageVersion, + apiVersion = apiVersion, + noStdlibLink = noStdlibLink, + noJdkLink = noJdkLink, + suppressedFiles = suppressedFiles, + collectInheritedExtensionsFromLibraries = collectInheritedExtensionsFromLibraries, + analysisPlatform = Platform.fromString(analysisPlatform), + targets = targets, + sinceKotlin = sinceKotlin, + perPackageOptions = perPackageOptions, + externalDocumentationLinks = externalDocumentationLinks, + sourceLinks = sourceLinks + ) + } +} + +data class TestMethods( + val analysisSetupStage: (Map<PlatformData, EnvironmentAndFacade>) -> Unit, + val pluginsSetupStage: (DokkaContext) -> Unit, + val documentablesCreationStage: (List<Module>) -> Unit, + val documentablesMergingStage: (Module) -> Unit, + val documentablesTransformationStage: (Module) -> Unit, + val pagesGenerationStage: (ModulePageNode) -> Unit, + val pagesTransformationStage: (ModulePageNode) -> Unit +)
\ No newline at end of file diff --git a/core/src/test/kotlin/utils/Builders.kt b/core/src/test/kotlin/utils/Builders.kt deleted file mode 100644 index e881082f..00000000 --- a/core/src/test/kotlin/utils/Builders.kt +++ /dev/null @@ -1,78 +0,0 @@ -package utils - -import org.jetbrains.dokka.DokkaConfigurationImpl -import org.jetbrains.dokka.PassConfigurationImpl -import org.jetbrains.dokka.Platform -import org.jetbrains.dokka.SourceRootImpl -import java.io.File - -object Builders { - data class ConfigBuilder( - val format: String = "html", - val generateIndexPages: Boolean = true, - val cacheRoot: String? = null, - val impliedPlatforms: List<String> = emptyList(), - val passesConfigurations: List<PassBuilder> = emptyList(), - var pluginsClasspath: List<String> = emptyList() - ) { - operator fun invoke(out: String) = - DokkaConfigurationImpl( - outputDir = out, - format = format, - generateIndexPages = generateIndexPages, - cacheRoot = cacheRoot, - impliedPlatforms = impliedPlatforms, - passesConfigurations = passesConfigurations.map { it() }, - pluginsClasspath = pluginsClasspath.map { File(it) } - ) - } - - data class PassBuilder( - val moduleName: String = "", - val classpath: List<String> = emptyList(), - val sourceRoots: List<String> = emptyList(), - val samples: List<String> = emptyList(), - val includes: List<String> = emptyList(), - val includeNonPublic: Boolean = true, - val includeRootPackage: Boolean = true, - val reportUndocumented: Boolean = false, - val skipEmptyPackages: Boolean = false, - val skipDeprecated: Boolean = false, - val jdkVersion: Int = 6, - val languageVersion: String? = null, - val apiVersion: String? = null, - val noStdlibLink: Boolean = false, - val noJdkLink: Boolean = false, - val suppressedFiles: List<String> = emptyList(), - val collectInheritedExtensionsFromLibraries: Boolean = true, - val analysisPlatform: String = "", - val targets: List<String> = emptyList(), - val sinceKotlin: String? = null - ) { - operator fun invoke() = - PassConfigurationImpl( - moduleName = moduleName, - classpath = classpath, - sourceRoots = sourceRoots.map{ SourceRootImpl(it) }, - samples = samples, - includes = includes, - includeNonPublic = includeNonPublic, - includeRootPackage = includeRootPackage, - reportUndocumented = reportUndocumented, - skipEmptyPackages = skipEmptyPackages, - skipDeprecated = skipDeprecated, - jdkVersion = jdkVersion, - languageVersion = languageVersion, - apiVersion = apiVersion, - noStdlibLink = noStdlibLink, - noJdkLink = noJdkLink, - suppressedFiles = suppressedFiles, - collectInheritedExtensionsFromLibraries = collectInheritedExtensionsFromLibraries, - analysisPlatform = Platform.fromString(analysisPlatform), - targets = targets, - sinceKotlin = sinceKotlin - ) - } - - -}
\ No newline at end of file diff --git a/core/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker b/core/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker deleted file mode 100644 index ca6ee9ce..00000000 --- a/core/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker +++ /dev/null @@ -1 +0,0 @@ -mock-maker-inline
\ No newline at end of file diff --git a/core/src/test/resources/sourceSets/example/commonMain/kotlin/Clock.kt b/core/src/test/resources/multiplatform/basicMultiplatformTest/commonMain/kotlin/Clock.kt index 4753cb32..4753cb32 100644 --- a/core/src/test/resources/sourceSets/example/commonMain/kotlin/Clock.kt +++ b/core/src/test/resources/multiplatform/basicMultiplatformTest/commonMain/kotlin/Clock.kt diff --git a/core/src/test/resources/sourceSets/example/commonMain/kotlin/House.kt b/core/src/test/resources/multiplatform/basicMultiplatformTest/commonMain/kotlin/House.kt index c879dee7..c879dee7 100644 --- a/core/src/test/resources/sourceSets/example/commonMain/kotlin/House.kt +++ b/core/src/test/resources/multiplatform/basicMultiplatformTest/commonMain/kotlin/House.kt diff --git a/core/src/test/resources/sourceSets/example/jsMain/kotlin/Clock.kt b/core/src/test/resources/multiplatform/basicMultiplatformTest/jsMain/kotlin/Clock.kt index 967cffcd..967cffcd 100644 --- a/core/src/test/resources/sourceSets/example/jsMain/kotlin/Clock.kt +++ b/core/src/test/resources/multiplatform/basicMultiplatformTest/jsMain/kotlin/Clock.kt diff --git a/core/src/test/resources/sourceSets/example/jvmAndJsSecondCommonMain/kotlin/Greeter.kt b/core/src/test/resources/multiplatform/basicMultiplatformTest/jvmAndJsSecondCommonMain/kotlin/Greeter.kt index 8a52e2f3..8a52e2f3 100644 --- a/core/src/test/resources/sourceSets/example/jvmAndJsSecondCommonMain/kotlin/Greeter.kt +++ b/core/src/test/resources/multiplatform/basicMultiplatformTest/jvmAndJsSecondCommonMain/kotlin/Greeter.kt diff --git a/core/src/test/resources/sourceSets/example/jvmMain/kotlin/example/Clock.kt b/core/src/test/resources/multiplatform/basicMultiplatformTest/jvmMain/kotlin/example/Clock.kt index 9ec01fb6..9ec01fb6 100644 --- a/core/src/test/resources/sourceSets/example/jvmMain/kotlin/example/Clock.kt +++ b/core/src/test/resources/multiplatform/basicMultiplatformTest/jvmMain/kotlin/example/Clock.kt diff --git a/core/src/test/resources/sourceSets/example/jvmMain/kotlin/example/ClockDays.kt b/core/src/test/resources/multiplatform/basicMultiplatformTest/jvmMain/kotlin/example/ClockDays.kt index 136ae5c8..136ae5c8 100644 --- a/core/src/test/resources/sourceSets/example/jvmMain/kotlin/example/ClockDays.kt +++ b/core/src/test/resources/multiplatform/basicMultiplatformTest/jvmMain/kotlin/example/ClockDays.kt diff --git a/core/src/test/resources/sourceSets/example/jvmMain/kotlin/example/ParticularClock.kt b/core/src/test/resources/multiplatform/basicMultiplatformTest/jvmMain/kotlin/example/ParticularClock.kt index 40813b50..40813b50 100644 --- a/core/src/test/resources/sourceSets/example/jvmMain/kotlin/example/ParticularClock.kt +++ b/core/src/test/resources/multiplatform/basicMultiplatformTest/jvmMain/kotlin/example/ParticularClock.kt |