diff options
author | Ignat Beresnev <ignat.beresnev@jetbrains.com> | 2023-11-10 11:46:54 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-11-10 11:46:54 +0100 |
commit | 8e5c63d035ef44a269b8c43430f43f5c8eebfb63 (patch) | |
tree | 1b915207b2b9f61951ddbf0ff2e687efd053d555 /dokka-subprojects/plugin-base-test-utils | |
parent | a44efd4ba0c2e4ab921ff75e0f53fc9335aa79db (diff) | |
download | dokka-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-test-utils')
9 files changed, 599 insertions, 0 deletions
diff --git a/dokka-subprojects/plugin-base-test-utils/api/plugin-base-test-utils.api b/dokka-subprojects/plugin-base-test-utils/api/plugin-base-test-utils.api new file mode 100644 index 00000000..a6bdc192 --- /dev/null +++ b/dokka-subprojects/plugin-base-test-utils/api/plugin-base-test-utils.api @@ -0,0 +1,199 @@ +public abstract class org/jetbrains/dokka/base/testApi/testRunner/BaseAbstractTest : org/jetbrains/dokka/testApi/testRunner/AbstractTest { + public fun <init> ()V + public fun <init> (Lorg/jetbrains/dokka/testApi/logger/TestLogger;)V + public synthetic fun <init> (Lorg/jetbrains/dokka/testApi/logger/TestLogger;ILkotlin/jvm/internal/DefaultConstructorMarker;)V +} + +public final class org/jetbrains/dokka/base/testApi/testRunner/BaseDokkaTestGenerator : org/jetbrains/dokka/testApi/testRunner/DokkaTestGenerator { + public fun <init> (Lorg/jetbrains/dokka/DokkaConfiguration;Lorg/jetbrains/dokka/utilities/DokkaLogger;Lorg/jetbrains/dokka/base/testApi/testRunner/BaseTestMethods;Ljava/util/List;)V + public synthetic fun <init> (Lorg/jetbrains/dokka/DokkaConfiguration;Lorg/jetbrains/dokka/utilities/DokkaLogger;Lorg/jetbrains/dokka/base/testApi/testRunner/BaseTestMethods;Ljava/util/List;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public fun generate ()V +} + +public final class org/jetbrains/dokka/base/testApi/testRunner/BaseTestBuilder : org/jetbrains/dokka/testApi/testRunner/TestBuilder { + public fun <init> ()V + public fun build ()Lorg/jetbrains/dokka/base/testApi/testRunner/BaseTestMethods; + public synthetic fun build ()Lorg/jetbrains/dokka/testApi/testRunner/TestMethods; + public final fun getDocumentablesCreationStage ()Lkotlin/jvm/functions/Function1; + public final fun getDocumentablesMergingStage ()Lkotlin/jvm/functions/Function1; + public final fun getDocumentablesTransformationStage ()Lkotlin/jvm/functions/Function1; + public final fun getPagesGenerationStage ()Lkotlin/jvm/functions/Function1; + public final fun getPagesTransformationStage ()Lkotlin/jvm/functions/Function1; + public final fun getPluginsSetupStage ()Lkotlin/jvm/functions/Function1; + public final fun getPreMergeDocumentablesTransformationStage ()Lkotlin/jvm/functions/Function1; + public final fun getRenderingStage ()Lkotlin/jvm/functions/Function2; + public final fun getVerificationStage ()Lkotlin/jvm/functions/Function1; + public final fun setDocumentablesCreationStage (Lkotlin/jvm/functions/Function1;)V + public final fun setDocumentablesMergingStage (Lkotlin/jvm/functions/Function1;)V + public final fun setDocumentablesTransformationStage (Lkotlin/jvm/functions/Function1;)V + public final fun setPagesGenerationStage (Lkotlin/jvm/functions/Function1;)V + public final fun setPagesTransformationStage (Lkotlin/jvm/functions/Function1;)V + public final fun setPluginsSetupStage (Lkotlin/jvm/functions/Function1;)V + public final fun setPreMergeDocumentablesTransformationStage (Lkotlin/jvm/functions/Function1;)V + public final fun setRenderingStage (Lkotlin/jvm/functions/Function2;)V + public final fun setVerificationStage (Lkotlin/jvm/functions/Function1;)V +} + +public final class org/jetbrains/dokka/base/testApi/testRunner/BaseTestMethods : org/jetbrains/dokka/testApi/testRunner/CoreTestMethods { + public fun <init> (Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function2;)V + public final fun component1 ()Lkotlin/jvm/functions/Function1; + public final fun component2 ()Lkotlin/jvm/functions/Function1; + public final fun component3 ()Lkotlin/jvm/functions/Function1; + public final fun component4 ()Lkotlin/jvm/functions/Function1; + public final fun component5 ()Lkotlin/jvm/functions/Function1; + public final fun component6 ()Lkotlin/jvm/functions/Function1; + public final fun component7 ()Lkotlin/jvm/functions/Function1; + public final fun component8 ()Lkotlin/jvm/functions/Function1; + public final fun component9 ()Lkotlin/jvm/functions/Function2; + public final fun copy (Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function2;)Lorg/jetbrains/dokka/base/testApi/testRunner/BaseTestMethods; + public static synthetic fun copy$default (Lorg/jetbrains/dokka/base/testApi/testRunner/BaseTestMethods;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lorg/jetbrains/dokka/base/testApi/testRunner/BaseTestMethods; + public fun equals (Ljava/lang/Object;)Z + public fun getDocumentablesCreationStage ()Lkotlin/jvm/functions/Function1; + public final fun getDocumentablesFirstTransformationStep ()Lkotlin/jvm/functions/Function1; + public fun getDocumentablesMergingStage ()Lkotlin/jvm/functions/Function1; + public fun getDocumentablesTransformationStage ()Lkotlin/jvm/functions/Function1; + public fun getPagesGenerationStage ()Lkotlin/jvm/functions/Function1; + public fun getPagesTransformationStage ()Lkotlin/jvm/functions/Function1; + public fun getPluginsSetupStage ()Lkotlin/jvm/functions/Function1; + public fun getRenderingStage ()Lkotlin/jvm/functions/Function2; + public fun getVerificationStage ()Lkotlin/jvm/functions/Function1; + public fun hashCode ()I + public fun toString ()Ljava/lang/String; +} + +public final class renderers/RawTestPage : org/jetbrains/dokka/pages/RootPageNode, org/jetbrains/dokka/pages/ContentPage { + public fun <init> (Lorg/jetbrains/dokka/pages/ContentNode;Ljava/lang/String;Ljava/util/Set;Ljava/util/List;Ljava/util/List;)V + public synthetic fun <init> (Lorg/jetbrains/dokka/pages/ContentNode;Ljava/lang/String;Ljava/util/Set;Ljava/util/List;Ljava/util/List;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public fun getChildren ()Ljava/util/List; + public fun getContent ()Lorg/jetbrains/dokka/pages/ContentNode; + public fun getDocumentable ()Lorg/jetbrains/dokka/model/Documentable; + public fun getDri ()Ljava/util/Set; + public fun getEmbeddedResources ()Ljava/util/List; + public fun getName ()Ljava/lang/String; + public synthetic fun modified (Ljava/lang/String;Ljava/util/List;)Lorg/jetbrains/dokka/pages/PageNode; + public fun modified (Ljava/lang/String;Ljava/util/List;)Lorg/jetbrains/dokka/pages/RootPageNode; + public fun modified (Ljava/lang/String;Lorg/jetbrains/dokka/pages/ContentNode;Ljava/util/Set;Ljava/util/List;Ljava/util/List;)Lorg/jetbrains/dokka/pages/ContentPage; +} + +public abstract class renderers/RenderingOnlyTestBase { + public fun <init> ()V + public abstract fun getContext ()Lorg/jetbrains/dokka/testApi/context/MockContext; + public abstract fun getRenderedContent ()Ljava/lang/Object; +} + +public final class renderers/TestPageKt { + public static final fun testPage (Lkotlin/jvm/functions/Function1;)Lrenderers/RawTestPage; +} + +public final class signatures/Parameter : utils/Tag { + public fun <init> ([Ljava/lang/Object;)V +} + +public final class signatures/Parameters : utils/Tag { + public fun <init> ([Ljava/lang/Object;)V +} + +public final class signatures/SignatureUtilsKt { + public static final fun firstSignature (Lorg/jsoup/nodes/Element;)Lorg/jsoup/nodes/Element; + public static final fun lastSignature (Lorg/jsoup/nodes/Element;)Lorg/jsoup/nodes/Element; + public static final fun renderedContent (Lutils/TestOutputWriter;Ljava/lang/String;)Lorg/jsoup/nodes/Element; + public static synthetic fun renderedContent$default (Lutils/TestOutputWriter;Ljava/lang/String;ILjava/lang/Object;)Lorg/jsoup/nodes/Element; + public static final fun signature (Lorg/jsoup/nodes/Element;)Lorg/jsoup/select/Elements; + public static final fun tab (Lorg/jsoup/nodes/Element;Ljava/lang/String;)Lorg/jsoup/select/Elements; +} + +public final class utils/A : utils/Tag { + public fun <init> ([Ljava/lang/Object;)V +} + +public final class utils/AssertHtmlEqualsIgnoringWhitespaceKt { + public static final fun assertHtmlEqualsIgnoringWhitespace (Ljava/lang/String;Ljava/lang/String;)V +} + +public final class utils/B : utils/Tag { + public fun <init> ([Ljava/lang/Object;)V +} + +public final class utils/BlockQuote : utils/Tag { + public fun <init> ([Ljava/lang/Object;)V +} + +public final class utils/Br : utils/Tag { + public static final field INSTANCE Lutils/Br; +} + +public final class utils/Dd : utils/Tag { + public fun <init> ([Ljava/lang/Object;)V +} + +public final class utils/Div : utils/Tag { + public fun <init> ([Ljava/lang/Object;)V +} + +public final class utils/Dl : utils/Tag { + public fun <init> ([Ljava/lang/Object;)V +} + +public final class utils/Dt : utils/Tag { + public fun <init> ([Ljava/lang/Object;)V +} + +public final class utils/I : utils/Tag { + public fun <init> ([Ljava/lang/Object;)V +} + +public final class utils/JsoupUtilsKt { + public static final fun match (Lorg/jsoup/nodes/Element;[Ljava/lang/Object;Z)V + public static synthetic fun match$default (Lorg/jsoup/nodes/Element;[Ljava/lang/Object;ZILjava/lang/Object;)V + public static final fun withClasses (Lutils/Tag;[Ljava/lang/String;)Lutils/Tag; +} + +public final class utils/P : utils/Tag { + public fun <init> ([Ljava/lang/Object;)V +} + +public final class utils/STRIKE : utils/Tag { + public fun <init> ([Ljava/lang/Object;)V +} + +public final class utils/Span : utils/Tag { + public fun <init> ([Ljava/lang/Object;)V +} + +public class utils/Tag { + public fun <init> (Ljava/lang/String;[Ljava/lang/Object;Ljava/util/List;)V + public synthetic fun <init> (Ljava/lang/String;[Ljava/lang/Object;Ljava/util/List;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public final fun getExpectedClasses ()Ljava/util/List; + public final fun getMatchers ()[Ljava/lang/Object; + public final fun getName ()Ljava/lang/String; +} + +public final class utils/TestOutputWriter : org/jetbrains/dokka/base/renderers/OutputWriter { + public fun <init> ()V + public fun <init> (Z)V + public synthetic fun <init> (ZILkotlin/jvm/internal/DefaultConstructorMarker;)V + public final fun getContents ()Ljava/util/Map; + public fun write (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; + public fun writeResources (Ljava/lang/String;Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; +} + +public final class utils/TestOutputWriterPlugin : org/jetbrains/dokka/plugability/DokkaPlugin { + public fun <init> ()V + public fun <init> (Z)V + public synthetic fun <init> (ZILkotlin/jvm/internal/DefaultConstructorMarker;)V + public final fun getTestWriter ()Lorg/jetbrains/dokka/plugability/Extension; + public final fun getWriter ()Lutils/TestOutputWriter; +} + +public final class utils/U : utils/Tag { + public fun <init> ([Ljava/lang/Object;)V +} + +public final class utils/Var : utils/Tag { + public fun <init> ([Ljava/lang/Object;)V +} + +public final class utils/Wbr : utils/Tag { + public static final field INSTANCE Lutils/Wbr; +} + diff --git a/dokka-subprojects/plugin-base-test-utils/build.gradle.kts b/dokka-subprojects/plugin-base-test-utils/build.gradle.kts new file mode 100644 index 00000000..d137b728 --- /dev/null +++ b/dokka-subprojects/plugin-base-test-utils/build.gradle.kts @@ -0,0 +1,32 @@ +/* + * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. + */ + +import dokkabuild.overridePublicationArtifactId + +plugins { + id("dokkabuild.kotlin-jvm") + id("dokkabuild.publish-jvm") +} + +overridePublicationArtifactId("dokka-base-test-utils") + +dependencies { + compileOnly(projects.dokkaSubprojects.dokkaCore) + compileOnly(projects.dokkaSubprojects.pluginBase) + + api(projects.dokkaSubprojects.analysisKotlinApi) + + // TODO [beresnev] analysis switcher + //runtimeOnly(project(path = ":subprojects:analysis-kotlin-symbols", configuration = "shadow")) + runtimeOnly(project(path = ":dokka-subprojects:analysis-kotlin-descriptors", configuration = "shadow")) + + implementation(kotlin("reflect")) + implementation(libs.jsoup) + + implementation(kotlin("test")) + implementation(projects.dokkaSubprojects.coreTestApi) + + testImplementation(kotlin("test")) + testImplementation(projects.dokkaSubprojects.coreTestApi) +} diff --git a/dokka-subprojects/plugin-base-test-utils/src/main/kotlin/org/jetbrains/dokka/base/testApi/renderers/RenderingOnlyTestBase.kt b/dokka-subprojects/plugin-base-test-utils/src/main/kotlin/org/jetbrains/dokka/base/testApi/renderers/RenderingOnlyTestBase.kt new file mode 100644 index 00000000..d2ff3ad4 --- /dev/null +++ b/dokka-subprojects/plugin-base-test-utils/src/main/kotlin/org/jetbrains/dokka/base/testApi/renderers/RenderingOnlyTestBase.kt @@ -0,0 +1,12 @@ +/* + * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. + */ + +package renderers + +import org.jetbrains.dokka.testApi.context.MockContext + +public abstract class RenderingOnlyTestBase<T> { + public abstract val context: MockContext + public abstract val renderedContent: T +} diff --git a/dokka-subprojects/plugin-base-test-utils/src/main/kotlin/org/jetbrains/dokka/base/testApi/renderers/TestPage.kt b/dokka-subprojects/plugin-base-test-utils/src/main/kotlin/org/jetbrains/dokka/base/testApi/renderers/TestPage.kt new file mode 100644 index 00000000..6fb484bf --- /dev/null +++ b/dokka-subprojects/plugin-base-test-utils/src/main/kotlin/org/jetbrains/dokka/base/testApi/renderers/TestPage.kt @@ -0,0 +1,59 @@ +/* + * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. + */ + +package renderers + +import org.jetbrains.dokka.DokkaConfiguration +import org.jetbrains.dokka.base.signatures.KotlinSignatureProvider +import org.jetbrains.dokka.base.transformers.pages.comments.CommentsToContentConverter +import org.jetbrains.dokka.base.translators.documentables.PageContentBuilder +import org.jetbrains.dokka.links.DRI +import org.jetbrains.dokka.model.doc.DocTag +import org.jetbrains.dokka.model.properties.PropertyContainer +import org.jetbrains.dokka.pages.* +import org.jetbrains.dokka.utilities.DokkaConsoleLogger +import org.jetbrains.dokka.utilities.LoggingLevel + +public fun testPage(callback: PageContentBuilder.DocumentableContentBuilder.() -> Unit): RawTestPage { + val content = PageContentBuilder( + EmptyCommentConverter, + KotlinSignatureProvider(EmptyCommentConverter, DokkaConsoleLogger(LoggingLevel.DEBUG)), + DokkaConsoleLogger(LoggingLevel.DEBUG) + ).contentFor( + DRI.topLevel, + emptySet(), + block = callback + ) + + return RawTestPage(content) +} + +public class RawTestPage( + override val content: ContentNode, + override val name: String = "testPage", + override val dri: Set<DRI> = setOf(DRI.topLevel), + override val embeddedResources: List<String> = emptyList(), + override val children: List<PageNode> = emptyList(), +): RootPageNode(), ContentPage { + override fun modified( + name: String, + content: ContentNode, + dri: Set<DRI>, + embeddedResources: List<String>, + children: List<PageNode> + ): ContentPage = this + + override fun modified(name: String, children: List<PageNode>): RootPageNode = this + +} + +internal object EmptyCommentConverter : CommentsToContentConverter { + override fun buildContent( + docTag: DocTag, + dci: DCI, + sourceSets: Set<DokkaConfiguration.DokkaSourceSet>, + styles: Set<Style>, + extras: PropertyContainer<ContentNode> + ): List<ContentNode> = emptyList() +} diff --git a/dokka-subprojects/plugin-base-test-utils/src/main/kotlin/org/jetbrains/dokka/base/testApi/signatures/SignatureUtils.kt b/dokka-subprojects/plugin-base-test-utils/src/main/kotlin/org/jetbrains/dokka/base/testApi/signatures/SignatureUtils.kt new file mode 100644 index 00000000..ecbe809b --- /dev/null +++ b/dokka-subprojects/plugin-base-test-utils/src/main/kotlin/org/jetbrains/dokka/base/testApi/signatures/SignatureUtils.kt @@ -0,0 +1,23 @@ +/* + * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. + */ + +package signatures + +import org.jsoup.Jsoup +import org.jsoup.nodes.Element +import org.jsoup.select.Elements +import utils.Tag +import utils.TestOutputWriter + +public fun TestOutputWriter.renderedContent(path: String = "root/example.html"): Element = + contents.getValue(path).let { Jsoup.parse(it) }.select("#content") + .single() + +public fun Element.signature(): Elements = select("div.symbol.monospace") +public fun Element.tab(tabName: String): Elements = select("div[data-togglable=\"$tabName\"]") +public fun Element.firstSignature(): Element = signature().first() ?: throw NoSuchElementException("No signature found") +public fun Element.lastSignature(): Element = signature().last() ?: throw NoSuchElementException("No signature found") + +public class Parameters(vararg matchers: Any) : Tag("span", *matchers, expectedClasses = listOf("parameters")) +public class Parameter(vararg matchers: Any) : Tag("span", *matchers, expectedClasses = listOf("parameter")) diff --git a/dokka-subprojects/plugin-base-test-utils/src/main/kotlin/org/jetbrains/dokka/base/testApi/testRunner/baseTestApi.kt b/dokka-subprojects/plugin-base-test-utils/src/main/kotlin/org/jetbrains/dokka/base/testApi/testRunner/baseTestApi.kt new file mode 100644 index 00000000..3dc0e54b --- /dev/null +++ b/dokka-subprojects/plugin-base-test-utils/src/main/kotlin/org/jetbrains/dokka/base/testApi/testRunner/baseTestApi.kt @@ -0,0 +1,124 @@ +/* + * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. + */ + +package org.jetbrains.dokka.base.testApi.testRunner + +import org.jetbrains.dokka.CoreExtensions +import org.jetbrains.dokka.DokkaConfiguration +import org.jetbrains.dokka.DokkaGenerator +import org.jetbrains.dokka.base.generation.SingleModuleGeneration +import org.jetbrains.dokka.model.DModule +import org.jetbrains.dokka.pages.RootPageNode +import org.jetbrains.dokka.plugability.DokkaContext +import org.jetbrains.dokka.plugability.DokkaPlugin +import org.jetbrains.dokka.testApi.logger.TestLogger +import org.jetbrains.dokka.testApi.testRunner.AbstractTest +import org.jetbrains.dokka.testApi.testRunner.CoreTestMethods +import org.jetbrains.dokka.testApi.testRunner.DokkaTestGenerator +import org.jetbrains.dokka.testApi.testRunner.TestBuilder +import org.jetbrains.dokka.utilities.DokkaConsoleLogger +import org.jetbrains.dokka.utilities.DokkaLogger +import org.jetbrains.dokka.utilities.LoggingLevel + +public class BaseDokkaTestGenerator( + configuration: DokkaConfiguration, + logger: DokkaLogger, + testMethods: BaseTestMethods, + additionalPlugins: List<DokkaPlugin> = emptyList() +) : DokkaTestGenerator<BaseTestMethods>(configuration, logger, testMethods, additionalPlugins) { + + override fun generate() { + with(testMethods) { + val dokkaGenerator = DokkaGenerator(configuration, logger) + + val context = + dokkaGenerator.initializePlugins(configuration, logger, additionalPlugins) + pluginsSetupStage(context) + + val singleModuleGeneration = context.single(CoreExtensions.generation) as SingleModuleGeneration + + val modulesFromPlatforms = singleModuleGeneration.createDocumentationModels() + documentablesCreationStage(modulesFromPlatforms) + + verificationStage { singleModuleGeneration.validityCheck(context) } + + val filteredModules = singleModuleGeneration.transformDocumentationModelBeforeMerge(modulesFromPlatforms) + documentablesFirstTransformationStep(filteredModules) + + val documentationModel = singleModuleGeneration.mergeDocumentationModels(filteredModules) + documentablesMergingStage(documentationModel!!) + + val transformedDocumentation = singleModuleGeneration.transformDocumentationModelAfterMerge(documentationModel) + documentablesTransformationStage(transformedDocumentation) + + val pages = singleModuleGeneration.createPages(transformedDocumentation) + pagesGenerationStage(pages) + + val transformedPages = singleModuleGeneration.transformPages(pages) + pagesTransformationStage(transformedPages) + + singleModuleGeneration.render(transformedPages) + renderingStage(transformedPages, context) + + singleModuleGeneration.runPostActions() + + singleModuleGeneration.reportAfterRendering() + } + } +} + +public data class BaseTestMethods( + override val pluginsSetupStage: (DokkaContext) -> Unit, + override val verificationStage: (() -> Unit) -> Unit, + override val documentablesCreationStage: (List<DModule>) -> Unit, + val documentablesFirstTransformationStep: (List<DModule>) -> Unit, + override val documentablesMergingStage: (DModule) -> Unit, + override val documentablesTransformationStage: (DModule) -> Unit, + override val pagesGenerationStage: (RootPageNode) -> Unit, + override val pagesTransformationStage: (RootPageNode) -> Unit, + override val renderingStage: (RootPageNode, DokkaContext) -> Unit +) : CoreTestMethods( + pluginsSetupStage, + verificationStage, + documentablesCreationStage, + documentablesMergingStage, + documentablesTransformationStage, + pagesGenerationStage, + pagesTransformationStage, + renderingStage, +) + +public class BaseTestBuilder : TestBuilder<BaseTestMethods>() { + public var pluginsSetupStage: (DokkaContext) -> Unit = {} + public var verificationStage: (() -> Unit) -> Unit = {} + public var documentablesCreationStage: (List<DModule>) -> Unit = {} + public var preMergeDocumentablesTransformationStage: (List<DModule>) -> Unit = {} + public var documentablesMergingStage: (DModule) -> Unit = {} + public var documentablesTransformationStage: (DModule) -> Unit = {} + public var pagesGenerationStage: (RootPageNode) -> Unit = {} + public var pagesTransformationStage: (RootPageNode) -> Unit = {} + public var renderingStage: (RootPageNode, DokkaContext) -> Unit = { _, _ -> } + + override fun build(): BaseTestMethods { + return BaseTestMethods( + pluginsSetupStage, + verificationStage, + documentablesCreationStage, + preMergeDocumentablesTransformationStage, + documentablesMergingStage, + documentablesTransformationStage, + pagesGenerationStage, + pagesTransformationStage, + renderingStage + ) + } +} + +public abstract class BaseAbstractTest( + logger: TestLogger = TestLogger(DokkaConsoleLogger(LoggingLevel.DEBUG)) +) : AbstractTest<BaseTestMethods, BaseTestBuilder, BaseDokkaTestGenerator>( + ::BaseTestBuilder, + ::BaseDokkaTestGenerator, + logger, +) diff --git a/dokka-subprojects/plugin-base-test-utils/src/main/kotlin/org/jetbrains/dokka/base/testApi/utils/JsoupUtils.kt b/dokka-subprojects/plugin-base-test-utils/src/main/kotlin/org/jetbrains/dokka/base/testApi/utils/JsoupUtils.kt new file mode 100644 index 00000000..fcd73ff0 --- /dev/null +++ b/dokka-subprojects/plugin-base-test-utils/src/main/kotlin/org/jetbrains/dokka/base/testApi/utils/JsoupUtils.kt @@ -0,0 +1,79 @@ +/* + * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. + */ + +package utils + +import org.jsoup.nodes.Element +import org.jsoup.nodes.Node +import org.jsoup.nodes.TextNode + +public fun Element.match(vararg matchers: Any, ignoreSpanWithTokenStyle:Boolean = false): Unit = + childNodes() + .let { list -> + if(ignoreSpanWithTokenStyle) { + list + .filterNot { it is Element && it.tagName() == "span" && it.attr("class").startsWith("token ") && it.childNodeSize() == 0} + .map { if(it is Element && it.tagName() == "span" + && it.attr("class").startsWith("token ") + && it.childNodeSize() == 1) it.childNode(0) else it } + .uniteConsecutiveTextNodes() + } else list + } + .filter { (it !is TextNode || it.text().isNotBlank())} + .let { it.drop(it.size - matchers.size) } + .zip(matchers) + .forEach { (n, m) -> m.accepts(n, ignoreSpan = ignoreSpanWithTokenStyle) } + +public open class Tag( + public val name: String, + public vararg val matchers: Any, + public val expectedClasses: List<String> = emptyList() +) +public class Div(vararg matchers: Any) : Tag("div", *matchers) +public class P(vararg matchers: Any) : Tag("p", *matchers) +public class Span(vararg matchers: Any) : Tag("span", *matchers) +public class A(vararg matchers: Any) : Tag("a", *matchers) +public class B(vararg matchers: Any) : Tag("b", *matchers) +public class I(vararg matchers: Any) : Tag("i", *matchers) +public class STRIKE(vararg matchers: Any) : Tag("strike", *matchers) +public class BlockQuote(vararg matchers: Any) : Tag("blockquote", *matchers) +public class Dl(vararg matchers: Any) : Tag("dl", *matchers) +public class Dt(vararg matchers: Any) : Tag("dt", *matchers) +public class Dd(vararg matchers: Any) : Tag("dd", *matchers) +public class Var(vararg matchers: Any) : Tag("var", *matchers) +public class U(vararg matchers: Any) : Tag("u", *matchers) +public object Wbr : Tag("wbr") +public object Br : Tag("br") + +public fun Tag.withClasses(vararg classes: String): Tag = Tag(name, *matchers, expectedClasses = classes.toList()) + +private fun Any.accepts(n: Node, ignoreSpan:Boolean = true) { + when (this) { + is String -> assert(n is TextNode && n.text().trim() == this.trim()) { "\"$this\" expected but found: $n" } + is Tag -> { + check(n is Element) { "Expected node to be Element: $n" } + assert(n.tagName() == name) { "Tag \"$name\" expected but found: \"$n\"" } + expectedClasses.forEach { + assert(n.hasClass(it)) { "Expected to find class \"$it\" for tag \"$name\", found: ${n.classNames()}" } + } + if (matchers.isNotEmpty()) n.match(*matchers, ignoreSpanWithTokenStyle = ignoreSpan) + } + else -> throw IllegalArgumentException("$this is not proper matcher") + } +} + +private fun List<Node>.uniteConsecutiveTextNodes(): MutableList<Node> { + val resList = mutableListOf<Node>() + var acc = StringBuilder() + forEachIndexed { index, item -> + if (item is TextNode) { + acc.append(item.text()) + if (!(index + 1 < size && this[index + 1] is TextNode)) { + resList.add(TextNode(acc.toString())) + acc = StringBuilder() + } + } else resList.add(item) + } + return resList + } diff --git a/dokka-subprojects/plugin-base-test-utils/src/main/kotlin/org/jetbrains/dokka/base/testApi/utils/TestOutputWriter.kt b/dokka-subprojects/plugin-base-test-utils/src/main/kotlin/org/jetbrains/dokka/base/testApi/utils/TestOutputWriter.kt new file mode 100644 index 00000000..089a94ca --- /dev/null +++ b/dokka-subprojects/plugin-base-test-utils/src/main/kotlin/org/jetbrains/dokka/base/testApi/utils/TestOutputWriter.kt @@ -0,0 +1,47 @@ +/* + * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. + */ + +package utils + +import org.jetbrains.dokka.base.DokkaBase +import org.jetbrains.dokka.base.renderers.OutputWriter +import org.jetbrains.dokka.plugability.DokkaPlugin +import org.jetbrains.dokka.plugability.DokkaPluginApiPreview +import org.jetbrains.dokka.plugability.Extension +import org.jetbrains.dokka.plugability.PluginApiPreviewAcknowledgement +import java.util.* + +public class TestOutputWriterPlugin(failOnOverwrite: Boolean = true) : DokkaPlugin() { + public val writer: TestOutputWriter = TestOutputWriter(failOnOverwrite) + + private val dokkaBase by lazy { plugin<DokkaBase>() } + + public val testWriter: Extension<OutputWriter, *, *> by extending { + (dokkaBase.outputWriter + with writer + override dokkaBase.fileWriter) + } + + @OptIn(DokkaPluginApiPreview::class) + override fun pluginApiPreviewAcknowledgement(): PluginApiPreviewAcknowledgement = + PluginApiPreviewAcknowledgement +} + +public class TestOutputWriter( + private val failOnOverwrite: Boolean = true +) : OutputWriter { + public val contents: Map<String, String> get() = _contents + private val _contents = Collections.synchronizedMap(mutableMapOf<String, String>()) + + override suspend fun write(path: String, text: String, ext: String) { + val fullPath = "$path$ext" + _contents.putIfAbsent(fullPath, text)?.also { + if (failOnOverwrite) throw AssertionError("File $fullPath is being overwritten.") + } + } + + override suspend fun writeResources(pathFrom: String, pathTo: String) { + write(pathTo, "*** content of $pathFrom ***", "") + } +} diff --git a/dokka-subprojects/plugin-base-test-utils/src/main/kotlin/org/jetbrains/dokka/base/testApi/utils/assertHtmlEqualsIgnoringWhitespace.kt b/dokka-subprojects/plugin-base-test-utils/src/main/kotlin/org/jetbrains/dokka/base/testApi/utils/assertHtmlEqualsIgnoringWhitespace.kt new file mode 100644 index 00000000..207ebb8a --- /dev/null +++ b/dokka-subprojects/plugin-base-test-utils/src/main/kotlin/org/jetbrains/dokka/base/testApi/utils/assertHtmlEqualsIgnoringWhitespace.kt @@ -0,0 +1,24 @@ +/* + * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. + */ + +package utils + +import org.jsoup.Jsoup +import org.jsoup.nodes.Document +import kotlin.test.assertEquals + +/** + * Parses it using JSOUP, trims whitespace at the end of the line and asserts if they are equal + * parsing is required to unify the formatting + */ +public fun assertHtmlEqualsIgnoringWhitespace(expected: String, actual: String) { + val ignoreFormattingSettings = Document.OutputSettings().indentAmount(0).outline(true) + assertEquals( + Jsoup.parse(expected).outputSettings(ignoreFormattingSettings).outerHtml().trimSpacesAtTheEndOfLine(), + Jsoup.parse(actual).outputSettings(ignoreFormattingSettings).outerHtml().trimSpacesAtTheEndOfLine() + ) +} + +private fun String.trimSpacesAtTheEndOfLine(): String = + replace(" \n", "\n") |