aboutsummaryrefslogtreecommitdiff
path: root/core/src/test/kotlin
diff options
context:
space:
mode:
authorSzymon Świstun <sswistun@virtuslab.com>2020-01-14 10:34:36 +0100
committerPaweł Marks <Kordyjan@users.noreply.github.com>2020-01-15 18:47:35 +0100
commitb13ff5993eb6a24adea0d17d989a594ae2e1e062 (patch)
treeca967a48886aaea4b2fcff6af6435573a608a304 /core/src/test/kotlin
parent0db075c17417884b6414b84e618a29f234286c4d (diff)
downloaddokka-b13ff5993eb6a24adea0d17d989a594ae2e1e062.tar.gz
dokka-b13ff5993eb6a24adea0d17d989a594ae2e1e062.tar.bz2
dokka-b13ff5993eb6a24adea0d17d989a594ae2e1e062.zip
Add testing utils and examples
Diffstat (limited to 'core/src/test/kotlin')
-rw-r--r--core/src/test/kotlin/generator/DokkaTestGenerator.kt78
-rw-r--r--core/src/test/kotlin/generator/TestRunner.kt157
-rw-r--r--core/src/test/kotlin/generator/test/GeneratorTest.kt62
-rw-r--r--core/src/test/kotlin/generator/test/MultiplatformTest.kt52
-rw-r--r--core/src/test/kotlin/utils/Builders.kt78
5 files changed, 427 insertions, 0 deletions
diff --git a/core/src/test/kotlin/generator/DokkaTestGenerator.kt b/core/src/test/kotlin/generator/DokkaTestGenerator.kt
new file mode 100644
index 00000000..9ceeeadf
--- /dev/null
+++ b/core/src/test/kotlin/generator/DokkaTestGenerator.kt
@@ -0,0 +1,78 @@
+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
new file mode 100644
index 00000000..305996f8
--- /dev/null
+++ b/core/src/test/kotlin/generator/TestRunner.kt
@@ -0,0 +1,157 @@
+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
new file mode 100644
index 00000000..97eb8b92
--- /dev/null
+++ b/core/src/test/kotlin/generator/test/GeneratorTest.kt
@@ -0,0 +1,62 @@
+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
new file mode 100644
index 00000000..2e28797d
--- /dev/null
+++ b/core/src/test/kotlin/generator/test/MultiplatformTest.kt
@@ -0,0 +1,52 @@
+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/utils/Builders.kt b/core/src/test/kotlin/utils/Builders.kt
new file mode 100644
index 00000000..e881082f
--- /dev/null
+++ b/core/src/test/kotlin/utils/Builders.kt
@@ -0,0 +1,78 @@
+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