From 8e5c63d035ef44a269b8c43430f43f5c8eebfb63 Mon Sep 17 00:00:00 2001 From: Ignat Beresnev Date: Fri, 10 Nov 2023 11:46:54 +0100 Subject: 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 --- .../kotlin/translators/AccessorMethodNamingTest.kt | 123 --- .../base/src/test/kotlin/translators/Bug1341.kt | 48 - ...efaultDescriptorToDocumentableTranslatorTest.kt | 1107 -------------------- .../DefaultPsiToDocumentableTranslatorTest.kt | 1027 ------------------ .../translators/ExternalDocumentablesTest.kt | 144 --- .../kotlin/translators/JavadocInheritDocsTest.kt | 312 ------ .../translators/JavadocInheritedDocTagsTest.kt | 252 ----- .../test/kotlin/translators/JavadocParserTest.kt | 208 ---- plugins/base/src/test/kotlin/translators/utils.kt | 43 - 9 files changed, 3264 deletions(-) delete mode 100644 plugins/base/src/test/kotlin/translators/AccessorMethodNamingTest.kt delete mode 100644 plugins/base/src/test/kotlin/translators/Bug1341.kt delete mode 100644 plugins/base/src/test/kotlin/translators/DefaultDescriptorToDocumentableTranslatorTest.kt delete mode 100644 plugins/base/src/test/kotlin/translators/DefaultPsiToDocumentableTranslatorTest.kt delete mode 100644 plugins/base/src/test/kotlin/translators/ExternalDocumentablesTest.kt delete mode 100644 plugins/base/src/test/kotlin/translators/JavadocInheritDocsTest.kt delete mode 100644 plugins/base/src/test/kotlin/translators/JavadocInheritedDocTagsTest.kt delete mode 100644 plugins/base/src/test/kotlin/translators/JavadocParserTest.kt delete mode 100644 plugins/base/src/test/kotlin/translators/utils.kt (limited to 'plugins/base/src/test/kotlin/translators') diff --git a/plugins/base/src/test/kotlin/translators/AccessorMethodNamingTest.kt b/plugins/base/src/test/kotlin/translators/AccessorMethodNamingTest.kt deleted file mode 100644 index ff36337a..00000000 --- a/plugins/base/src/test/kotlin/translators/AccessorMethodNamingTest.kt +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package translators - -import org.jetbrains.dokka.base.testApi.testRunner.BaseAbstractTest -import org.jetbrains.dokka.model.DProperty -import kotlin.test.Test -import kotlin.test.assertEquals -import kotlin.test.assertTrue - -/** - * https://kotlinlang.org/docs/java-to-kotlin-interop.html#properties - * https://kotlinlang.org/docs/java-interop.html#getters-and-setters - */ -class AccessorMethodNamingTest : BaseAbstractTest() { - - @Test - fun `standard property`() { - testAccessors("data class TestCase(var standardString: String, var standardBoolean: Boolean)") { - doTest("standardString", "getStandardString", "setStandardString") - doTest("standardBoolean", "getStandardBoolean", "setStandardBoolean") - } - } - - @Test - fun `properties that start with the word 'is' use the special is rules`() { - testAccessors("data class TestCase(var isFoo: String, var isBar: Boolean)") { - doTest("isFoo", "isFoo", "setFoo") - doTest("isBar", "isBar", "setBar") - } - } - - @Test - fun `properties that start with a word that starts with 'is' use get and set`() { - testAccessors("data class TestCase(var issuesFetched: Int, var issuesWereDisplayed: Boolean)") { - doTest("issuesFetched", "getIssuesFetched", "setIssuesFetched") - doTest("issuesWereDisplayed", "getIssuesWereDisplayed", "setIssuesWereDisplayed") - } - } - - @Test - fun `properties that start with the word 'is' followed by underscore use the special is rules`() { - testAccessors("data class TestCase(var is_foo: String, var is_bar: Boolean)") { - doTest("is_foo", "is_foo", "set_foo") - doTest("is_bar", "is_bar", "set_bar") - } - } - - @Test - fun `properties that start with the word 'is' followed by a number use the special is rules`() { - testAccessors("data class TestCase(var is1of: String, var is2of: Boolean)") { - doTest("is1of", "is1of", "set1of") - doTest("is2of", "is2of", "set2of") - } - } - - @Test - fun `sanity check short names`() { - testAccessors( - """ - data class TestCase( - var i: Boolean, - var `is`: Boolean, - var isz: Boolean, - var isA: Int, - var isB: Boolean, - ) - """.trimIndent() - ) { - doTest("i", "getI", "setI") - doTest("is", "getIs", "setIs") - doTest("isz", "getIsz", "setIsz") - doTest("isA", "isA", "setA") - doTest("isB", "isB", "setB") - } - } - - private fun testAccessors(code: String, block: PropertyTestCase.() -> Unit) { - val configuration = dokkaConfiguration { - suppressObviousFunctions = false - sourceSets { - sourceSet { - sourceRoots = listOf("src/main/kotlin") - } - } - } - - testInline(""" - /src/main/kotlin/sample/TestCase.kt - package sample - - $code - """.trimIndent(), - configuration) { - documentablesMergingStage = { module -> - val properties = module.packages.single().classlikes.first().properties - PropertyTestCase(properties).apply { - block() - finish() - } - } - } - } - - private class PropertyTestCase(private val properties: List) { - private var testsDone: Int = 0 - - fun doTest(kotlinName: String, getter: String? = null, setter: String? = null) { - properties.first { it.name == kotlinName }.let { - assertEquals(getter, it.getter?.name) - assertEquals(setter, it.setter?.name) - } - testsDone += 1 - } - - fun finish() { - assertTrue(testsDone > 0, "No tests in TestCase") - assertEquals(testsDone, properties.size) - } - } -} diff --git a/plugins/base/src/test/kotlin/translators/Bug1341.kt b/plugins/base/src/test/kotlin/translators/Bug1341.kt deleted file mode 100644 index 6a7bfc97..00000000 --- a/plugins/base/src/test/kotlin/translators/Bug1341.kt +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package translators - -import org.jetbrains.dokka.base.testApi.testRunner.BaseAbstractTest -import org.jetbrains.dokka.links.DRI -import kotlin.test.Test -import kotlin.test.assertEquals - -class Bug1341 : BaseAbstractTest() { - @Test - fun `reproduce bug #1341`() { - val configuration = dokkaConfiguration { - sourceSets { - sourceSet { - sourceRoots = listOf("src") - analysisPlatform = "jvm" - } - } - } - - testInline( - """ - /src/com/sample/OtherClass.kt - package com.sample - class OtherClass internal constructor() { - internal annotation class CustomAnnotation - } - - /src/com/sample/ClassUsingAnnotation.java - package com.sample - public class ClassUsingAnnotation { - @OtherClass.CustomAnnotation - public int doSomething() { - return 1; - } - } - """.trimIndent(), - configuration - ) { - this.documentablesMergingStage = { module -> - assertEquals(DRI("com.sample"), module.packages.single().dri) - } - } - } -} diff --git a/plugins/base/src/test/kotlin/translators/DefaultDescriptorToDocumentableTranslatorTest.kt b/plugins/base/src/test/kotlin/translators/DefaultDescriptorToDocumentableTranslatorTest.kt deleted file mode 100644 index 6812f0b4..00000000 --- a/plugins/base/src/test/kotlin/translators/DefaultDescriptorToDocumentableTranslatorTest.kt +++ /dev/null @@ -1,1107 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package translators - -import org.jetbrains.dokka.DokkaConfiguration -import org.jetbrains.dokka.base.signatures.KotlinSignatureUtils.modifiers -import org.jetbrains.dokka.base.testApi.testRunner.BaseAbstractTest -import org.jetbrains.dokka.links.DRI -import org.jetbrains.dokka.links.PointingToDeclaration -import org.jetbrains.dokka.model.* -import org.jetbrains.dokka.model.doc.* -import utils.text -import kotlin.test.* -import utils.OnlyDescriptors - -class DefaultDescriptorToDocumentableTranslatorTest : BaseAbstractTest() { - val configuration = dokkaConfiguration { - suppressObviousFunctions = false - sourceSets { - sourceSet { - sourceRoots = listOf("src/main/kotlin") - classpath = listOf(commonStdlibPath!!, jvmStdlibPath!!) - } - } - } - - @Suppress("DEPRECATION") // for includeNonPublic - val javaConfiguration = dokkaConfiguration { - sourceSets { - sourceSet { - sourceRoots = listOf("src/main/java") - includeNonPublic = true - } - } - } - - @Test - fun `data class kdocs over generated methods`() { - testInline( - """ - |/src/main/kotlin/sample/XD.kt - |package sample - |/** - | * But the fat Hobbit, he knows. Eyes always watching. - | */ - |data class XD(val xd: String) { - | /** - | * But the fat Hobbit, he knows. Eyes always watching. - | */ - | fun custom(): String = "" - | - | /** - | * Memory is not what the heart desires. That is only a mirror. - | */ - | override fun equals(other: Any?): Boolean = true - |} - """.trimIndent(), - configuration - ) { - documentablesMergingStage = { module -> - assertEquals("", module.documentationOf("XD", "copy")) - assertEquals( - "Memory is not what the heart desires. That is only a mirror.", - module.documentationOf( - "XD", - "equals" - ) - ) - assertEquals("", module.documentationOf("XD", "hashCode")) - assertEquals("", module.documentationOf("XD", "toString")) - assertEquals("But the fat Hobbit, he knows. Eyes always watching.", module.documentationOf("XD", "custom")) - } - } - } - - @Test - fun `simple class kdocs`() { - testInline( - """ - |/src/main/kotlin/sample/XD.kt - |package sample - |/** - | * But the fat Hobbit, he knows. Eyes always watching. - | */ - |class XD(val xd: String) { - | /** - | * But the fat Hobbit, he knows. Eyes always watching. - | */ - | fun custom(): String = "" - | - | /** - | * Memory is not what the heart desires. That is only a mirror. - | */ - | override fun equals(other: Any?): Boolean = true - |} - """.trimIndent(), - configuration - ) { - documentablesMergingStage = { module -> - assertEquals("But the fat Hobbit, he knows. Eyes always watching.", module.documentationOf("XD", "custom")) - assertEquals( - "Memory is not what the heart desires. That is only a mirror.", - module.documentationOf( - "XD", - "equals" - ) - ) - } - } - } - - @Test - fun `kdocs with code block`() { - testInline( - """ - |/src/main/kotlin/sample/TestForCodeInDocs.kt - |package sample - |/** - | * Utility for building a String that represents an XML document. - | * The XmlBlob object is immutable and the passed values are copied where it makes sense. - | * - | * Note the XML Declaration is not output as part of the XmlBlob - | * - | * - | * val soapAttrs = attrs("soap-env" to "http://www.w3.org/2001/12/soap-envelope", - | * "soap-env:encodingStyle" to "http://www.w3.org/2001/12/soap-encoding") - | * val soapXml = node("soap-env:Envelope", soapAttrs, - | * node("soap-env:Body", attrs("xmlns:m" to "http://example"), - | * node("m:GetExample", - | * node("m:GetExampleName", "BasePair") - | * ) - | * ) - | * ) - | * - | * - | */ - |class TestForCodeInDocs { - |} - """.trimIndent(), configuration - ) { - documentablesMergingStage = { module -> - val description = module.descriptionOf("TestForCodeInDocs") - val expected = listOf( - P( - children = listOf(Text("Utility for building a String that represents an XML document. The XmlBlob object is immutable and the passed values are copied where it makes sense.")) - ), - P( - children = listOf(Text("Note the XML Declaration is not output as part of the XmlBlob")) - ), - CodeBlock( - children = listOf( - Text( - """val soapAttrs = attrs("soap-env" to "http://www.w3.org/2001/12/soap-envelope", - "soap-env:encodingStyle" to "http://www.w3.org/2001/12/soap-encoding") -val soapXml = node("soap-env:Envelope", soapAttrs, - node("soap-env:Body", attrs("xmlns:m" to "http://example"), - node("m:GetExample", - node("m:GetExampleName", "BasePair") - ) - ) -)""" - ) - ) - ) - ) - assertEquals(expected, description?.root?.children) - } - } - } - - private fun runTestSuitesAgainstGivenClasses(classlikes: List, testSuites: List>) { - classlikes.zip(testSuites).forEach { (classlike, testSuites) -> - testSuites.forEach { testSuite -> - when (testSuite) { - is TestSuite.PropertyDoesntExist -> assertEquals( - null, - classlike.properties.firstOrNull { it.name == testSuite.propertyName }, - "Test for class ${classlike.name} failed" - ) - is TestSuite.PropertyExists -> classlike.properties.single { it.name == testSuite.propertyName } - .run { - assertEquals( - testSuite.modifier, - modifier.values.single(), - "Test for class ${classlike.name} with property $name failed" - ) - assertEquals( - testSuite.visibility, - visibility.values.single(), - "Test for class ${classlike.name} with property $name failed" - ) - assertEquals( - testSuite.additionalModifiers, - extra[AdditionalModifiers]?.content?.values?.single() ?: emptySet(), - "Test for class ${classlike.name} with property $name failed" - ) - } - is TestSuite.FunctionDoesntExist -> assertEquals( - null, - classlike.functions.firstOrNull { it.name == testSuite.propertyName }, - "Test for class ${classlike.name} failed" - ) - is TestSuite.FunctionExists -> classlike.functions.single { it.name == testSuite.propertyName } - .run { - assertEquals( - testSuite.modifier, - modifier.values.single(), - "Test for class ${classlike.name} with function $name failed" - ) - assertEquals( - testSuite.visibility, - visibility.values.single(), - "Test for class ${classlike.name} with function $name failed" - ) - assertEquals( - testSuite.additionalModifiers, - extra[AdditionalModifiers]?.content?.values?.single() ?: emptySet(), - "Test for class ${classlike.name} with function $name failed" - ) - } - } - } - } - } - - @Test - fun `derived properties with non-public code included`() { - - val configuration = dokkaConfiguration { - sourceSets { - sourceSet { - sourceRoots = listOf("src/main/kotlin") - documentedVisibilities = setOf( - DokkaConfiguration.Visibility.PUBLIC, - DokkaConfiguration.Visibility.PRIVATE, - DokkaConfiguration.Visibility.PROTECTED, - DokkaConfiguration.Visibility.INTERNAL, - ) - } - } - } - - testInline( - """ - |/src/main/kotlin/sample/XD.kt - |package sample - | - |open class A { - | private val privateProperty: Int = 1 - | protected val protectedProperty: Int = 2 - | internal val internalProperty: Int = 3 - | val publicProperty: Int = 4 - | open val propertyToOverride: Int = 5 - | - | private fun privateFun(): Int = 6 - | protected fun protectedFun(): Int = 7 - | internal fun internalFun(): Int = 8 - | fun publicFun(): Int = 9 - | open fun funToOverride(): Int = 10 - |} - | - |open class B : A() { - | override val propertyToOverride: Int = 11 - | - | override fun funToOverride(): Int = 12 - |} - |class C : B() - """.trimIndent(), - configuration - ) { - - documentablesMergingStage = { module -> - val classes = module.packages.single().classlikes.sortedBy { it.name } - - val testSuites: List> = listOf( - listOf( - TestSuite.PropertyExists( - "privateProperty", - KotlinModifier.Final, - KotlinVisibility.Private, - emptySet() - ), - TestSuite.PropertyExists( - "protectedProperty", - KotlinModifier.Final, - KotlinVisibility.Protected, - emptySet() - ), - TestSuite.PropertyExists( - "internalProperty", - KotlinModifier.Final, - KotlinVisibility.Internal, - emptySet() - ), - TestSuite.PropertyExists( - "publicProperty", - KotlinModifier.Final, - KotlinVisibility.Public, - emptySet() - ), - TestSuite.PropertyExists( - "propertyToOverride", - KotlinModifier.Open, - KotlinVisibility.Public, - emptySet() - ), - TestSuite.FunctionExists( - "privateFun", - KotlinModifier.Final, - KotlinVisibility.Private, - emptySet() - ), - TestSuite.FunctionExists( - "protectedFun", - KotlinModifier.Final, - KotlinVisibility.Protected, - emptySet() - ), - TestSuite.FunctionExists( - "internalFun", - KotlinModifier.Final, - KotlinVisibility.Internal, - emptySet() - ), - TestSuite.FunctionExists( - "publicFun", - KotlinModifier.Final, - KotlinVisibility.Public, - emptySet() - ), - TestSuite.FunctionExists( - "funToOverride", - KotlinModifier.Open, - KotlinVisibility.Public, - emptySet() - ) - ), - listOf( - TestSuite.PropertyExists( - "privateProperty", - KotlinModifier.Final, - KotlinVisibility.Private, - emptySet() - ), - TestSuite.PropertyExists( - "protectedProperty", - KotlinModifier.Final, - KotlinVisibility.Protected, - emptySet() - ), - TestSuite.PropertyExists( - "internalProperty", - KotlinModifier.Final, - KotlinVisibility.Internal, - emptySet() - ), - TestSuite.PropertyExists( - "publicProperty", - KotlinModifier.Final, - KotlinVisibility.Public, - emptySet() - ), - TestSuite.PropertyExists( - "propertyToOverride", - KotlinModifier.Open, - KotlinVisibility.Public, - setOf(ExtraModifiers.KotlinOnlyModifiers.Override) - ), - TestSuite.FunctionExists( - "privateFun", - KotlinModifier.Final, - KotlinVisibility.Private, - emptySet() - ), - TestSuite.FunctionExists( - "protectedFun", - KotlinModifier.Final, - KotlinVisibility.Protected, - emptySet() - ), - TestSuite.FunctionExists( - "internalFun", - KotlinModifier.Final, - KotlinVisibility.Internal, - emptySet() - ), - TestSuite.FunctionExists( - "publicFun", - KotlinModifier.Final, - KotlinVisibility.Public, - emptySet() - ), - TestSuite.FunctionExists( - "funToOverride", - KotlinModifier.Open, - KotlinVisibility.Public, - setOf(ExtraModifiers.KotlinOnlyModifiers.Override) - ) - ), - listOf( - TestSuite.PropertyExists( - "privateProperty", - KotlinModifier.Final, - KotlinVisibility.Private, - emptySet() - ), - TestSuite.PropertyExists( - "protectedProperty", - KotlinModifier.Final, - KotlinVisibility.Protected, - emptySet() - ), - TestSuite.PropertyExists( - "internalProperty", - KotlinModifier.Final, - KotlinVisibility.Internal, - emptySet() - ), - TestSuite.PropertyExists( - "publicProperty", - KotlinModifier.Final, - KotlinVisibility.Public, - emptySet() - ), - TestSuite.PropertyExists( - "propertyToOverride", - KotlinModifier.Open, - KotlinVisibility.Public, - setOf(ExtraModifiers.KotlinOnlyModifiers.Override) - ), - TestSuite.FunctionExists( - "privateFun", - KotlinModifier.Final, - KotlinVisibility.Private, - emptySet() - ), - TestSuite.FunctionExists( - "protectedFun", - KotlinModifier.Final, - KotlinVisibility.Protected, - emptySet() - ), - TestSuite.FunctionExists( - "internalFun", - KotlinModifier.Final, - KotlinVisibility.Internal, - emptySet() - ), - TestSuite.FunctionExists( - "publicFun", - KotlinModifier.Final, - KotlinVisibility.Public, - emptySet() - ), - TestSuite.FunctionExists( - "funToOverride", - KotlinModifier.Open, - KotlinVisibility.Public, - setOf(ExtraModifiers.KotlinOnlyModifiers.Override) - ) - ) - ) - - runTestSuitesAgainstGivenClasses(classes, testSuites) - } - } - } - - - @Test - fun `derived properties with only public code`() { - - @Suppress("DEPRECATION") // for includeNonPublic - val configuration = dokkaConfiguration { - sourceSets { - sourceSet { - sourceRoots = listOf("src/main/kotlin") - includeNonPublic = false - } - } - } - - testInline( - """ - |/src/main/kotlin/sample/XD.kt - |package sample - | - |open class A { - | private val privateProperty: Int = 1 - | protected val protectedProperty: Int = 2 - | internal val internalProperty: Int = 3 - | val publicProperty: Int = 4 - | open val propertyToOverride: Int = 5 - | open val propertyToOverrideButCloseMeanwhile: Int = 6 - | - | private fun privateFun(): Int = 7 - | protected fun protectedFun(): Int = 8 - | internal fun internalFun(): Int = 9 - | fun publicFun(): Int = 10 - | open fun funToOverride(): Int = 11 - | open fun funToOverrideButCloseMeanwhile(): Int = 12 - |} - | - |open class B : A() { - | override val propertyToOverride: Int = 13 - | final override val propertyToOverrideButCloseMeanwhile: Int = 14 - | - | override fun funToOverride(): Int = 15 - | final override fun funToOverrideButCloseMeanwhile(): Int = 16 - |} - |class C : B() - """.trimIndent(), - configuration - ) { - - documentablesMergingStage = { module -> - val classes = module.packages.single().classlikes.sortedBy { it.name } - - val testSuites: List> = listOf( - listOf( - TestSuite.PropertyDoesntExist("privateProperty"), - TestSuite.PropertyDoesntExist("protectedProperty"), - TestSuite.PropertyDoesntExist("internalProperty"), - TestSuite.PropertyExists( - "publicProperty", - KotlinModifier.Final, - KotlinVisibility.Public, - emptySet() - ), - TestSuite.PropertyExists( - "propertyToOverride", - KotlinModifier.Open, - KotlinVisibility.Public, - emptySet() - ), - TestSuite.PropertyExists( - "propertyToOverrideButCloseMeanwhile", - KotlinModifier.Open, - KotlinVisibility.Public, - emptySet() - ), - TestSuite.FunctionDoesntExist("privateFun"), - TestSuite.FunctionDoesntExist("protectedFun"), - TestSuite.FunctionDoesntExist("internalFun"), - TestSuite.FunctionExists( - "publicFun", - KotlinModifier.Final, - KotlinVisibility.Public, - emptySet() - ), - TestSuite.FunctionExists( - "funToOverride", - KotlinModifier.Open, - KotlinVisibility.Public, - emptySet() - ), - TestSuite.FunctionExists( - "funToOverrideButCloseMeanwhile", - KotlinModifier.Open, - KotlinVisibility.Public, - emptySet() - ) - ), - listOf( - TestSuite.PropertyDoesntExist("privateProperty"), - TestSuite.PropertyDoesntExist("protectedProperty"), - TestSuite.PropertyDoesntExist("internalProperty"), - TestSuite.PropertyExists( - "publicProperty", - KotlinModifier.Final, - KotlinVisibility.Public, - emptySet() - ), - TestSuite.PropertyExists( - "propertyToOverride", - KotlinModifier.Open, - KotlinVisibility.Public, - setOf(ExtraModifiers.KotlinOnlyModifiers.Override) - ), - TestSuite.PropertyExists( - "propertyToOverrideButCloseMeanwhile", - KotlinModifier.Final, - KotlinVisibility.Public, - setOf(ExtraModifiers.KotlinOnlyModifiers.Override) - ), - TestSuite.FunctionDoesntExist("privateFun"), - TestSuite.FunctionDoesntExist("protectedFun"), - TestSuite.FunctionDoesntExist("internalFun"), - TestSuite.FunctionExists( - "publicFun", - KotlinModifier.Final, - KotlinVisibility.Public, - emptySet() - ), - TestSuite.FunctionExists( - "funToOverride", - KotlinModifier.Open, - KotlinVisibility.Public, - setOf(ExtraModifiers.KotlinOnlyModifiers.Override) - ), - TestSuite.FunctionExists( - "funToOverrideButCloseMeanwhile", - KotlinModifier.Final, - KotlinVisibility.Public, - setOf(ExtraModifiers.KotlinOnlyModifiers.Override) - ) - ), - listOf( - TestSuite.PropertyDoesntExist("privateProperty"), - TestSuite.PropertyDoesntExist("protectedProperty"), - TestSuite.PropertyDoesntExist("internalProperty"), - TestSuite.PropertyExists( - "publicProperty", - KotlinModifier.Final, - KotlinVisibility.Public, - emptySet() - ), - TestSuite.PropertyExists( - "propertyToOverride", - KotlinModifier.Open, - KotlinVisibility.Public, - setOf(ExtraModifiers.KotlinOnlyModifiers.Override) - ), - TestSuite.PropertyExists( - "propertyToOverrideButCloseMeanwhile", - KotlinModifier.Final, - KotlinVisibility.Public, - setOf(ExtraModifiers.KotlinOnlyModifiers.Override) - ), - TestSuite.FunctionDoesntExist("privateFun"), - TestSuite.FunctionDoesntExist("protectedFun"), - TestSuite.FunctionDoesntExist("internalFun"), - TestSuite.FunctionExists( - "publicFun", - KotlinModifier.Final, - KotlinVisibility.Public, - emptySet() - ), - TestSuite.FunctionExists( - "funToOverride", - KotlinModifier.Open, - KotlinVisibility.Public, - setOf(ExtraModifiers.KotlinOnlyModifiers.Override) - ), - TestSuite.FunctionExists( - "funToOverrideButCloseMeanwhile", - KotlinModifier.Final, - KotlinVisibility.Public, - setOf(ExtraModifiers.KotlinOnlyModifiers.Override) - ) - ) - ) - - runTestSuitesAgainstGivenClasses(classes, testSuites) - } - } - } - - @Ignore // The compiler throws away annotations on unresolved types upstream - @Test - fun `Can annotate unresolved type`() { - testInline( - """ - |/src/main/java/sample/FooLibrary.kt - |package sample; - |@MustBeDocumented - |@Target(AnnotationTarget.TYPE) - |annotation class Hello() - |fun bar(): @Hello() TypeThatDoesntResolve - """.trimMargin(), - javaConfiguration - ) { - documentablesMergingStage = { module -> - val type = module.packages.single().functions.single().type as GenericTypeConstructor - assertEquals( - Annotations.Annotation(DRI("sample", "Hello"), emptyMap()), - type.extra[Annotations]?.directAnnotations?.values?.single()?.single() - ) - } - } - } - - /** - * Kotlin Int becomes java int. Java int cannot be annotated in source, but Kotlin Int can be. - * This is paired with KotlinAsJavaPluginTest.`Java primitive annotations work`() - */ - @Test - fun `Java primitive annotations work`() { - testInline( - """ - |/src/main/java/sample/FooLibrary.kt - |package sample; - |@MustBeDocumented - |@Target(AnnotationTarget.TYPE) - |annotation class Hello() - |fun bar(): @Hello() Int - """.trimMargin(), - javaConfiguration - ) { - documentablesMergingStage = { module -> - val type = module.packages.single().functions.single().type as GenericTypeConstructor - assertEquals( - Annotations.Annotation(DRI("sample", "Hello"), emptyMap()), - type.extra[Annotations]?.directAnnotations?.values?.single()?.single() - ) - assertEquals("kotlin/Int///PointingToDeclaration/", type.dri.toString()) - } - } - } - - @Test - fun `should preserve regular functions that look like accessors, but are not accessors`() { - testInline( - """ - |/src/main/kotlin/A.kt - |package test - |class A { - | private var v: Int = 0 - | - | // not accessors because declared separately, just functions - | fun setV(new: Int) { v = new } - | fun getV(): Int = v - |} - """.trimIndent(), - configuration - ) { - documentablesMergingStage = { module -> - val testClass = module.packages.single().classlikes.single { it.name == "A" } - val setterLookalike = testClass.functions.firstOrNull { it.name == "setV" } - assertNotNull(setterLookalike) { - "Expected regular function not found, wrongly categorized as setter?" - } - - val getterLookalike = testClass.functions.firstOrNull { it.name == "getV" } - assertNotNull(getterLookalike) { - "Expected regular function not found, wrongly categorized as getter?" - } - } - } - } - - @Test - fun `should correctly add IsVar extra for properties`() { - testInline( - """ - |/src/main/kotlin/A.kt - |package test - |class A { - | public var mutable: Int = 0 - | public val immutable: Int = 0 - |} - """.trimIndent(), - configuration - ) { - documentablesMergingStage = { module -> - val testClass = module.packages.single().classlikes.single { it.name == "A" } - assertEquals(2, testClass.properties.size) - - val mutable = testClass.properties[0] - assertEquals("mutable", mutable.name) - assertNotNull(mutable.extra[IsVar]) - - val immutable = testClass.properties[1] - assertEquals("immutable", immutable.name) - assertNull(immutable.extra[IsVar]) - } - } - } - - @Test - fun `should correctly parse multiple see tags with static function and property links`() { - testInline( - """ - |/src/main/kotlin/com/example/package/CollectionExtensions.kt - |package com.example.util - | - |object CollectionExtensions { - | val property = "Hi" - | - | fun emptyList() {} - | fun emptyMap() {} - | fun emptySet() {} - |} - | - |/src/main/kotlin/com/example/foo.kt - |package com.example - | - |import com.example.util.CollectionExtensions.emptyMap - |import com.example.util.CollectionExtensions.emptyList - |import com.example.util.CollectionExtensions.emptySet - |import com.example.util.CollectionExtensions.property - | - |/** - | * @see [List] stdlib list - | * @see [Map] stdlib map - | * @see [emptyMap] static emptyMap - | * @see [emptyList] static emptyList - | * @see [emptySet] static emptySet - | * @see [property] static property - | */ - |fun foo() {} - """.trimIndent(), - configuration - ) { - fun assertSeeTag(tag: TagWrapper, expectedName: String, expectedDescription: String) { - assertTrue(tag is See) - assertEquals(expectedName, tag.name) - val description = tag.children.joinToString { it.text().trim() } - assertEquals(expectedDescription, description) - } - - documentablesMergingStage = { module -> - val testFunction = module.packages.find { it.name == "com.example" } - ?.functions - ?.single { it.name == "foo" } - assertNotNull(testFunction) - - val documentationTags = testFunction.documentation.values.single().children - assertEquals(7, documentationTags.size) - - val descriptionTag = documentationTags[0] - assertTrue(descriptionTag is Description, "Expected first tag to be empty description") - assertTrue(descriptionTag.children.isEmpty(), "Expected first tag to be empty description") - - assertSeeTag( - tag = documentationTags[1], - expectedName = "kotlin.collections.List", - expectedDescription = "stdlib list" - ) - assertSeeTag( - tag = documentationTags[2], - expectedName = "kotlin.collections.Map", - expectedDescription = "stdlib map" - ) - assertSeeTag( - tag = documentationTags[3], - expectedName = "com.example.util.CollectionExtensions.emptyMap", - expectedDescription = "static emptyMap" - ) - assertSeeTag( - tag = documentationTags[4], - expectedName = "com.example.util.CollectionExtensions.emptyList", - expectedDescription = "static emptyList" - ) - assertSeeTag( - tag = documentationTags[5], - expectedName = "com.example.util.CollectionExtensions.emptySet", - expectedDescription = "static emptySet" - ) - assertSeeTag( - tag = documentationTags[6], - expectedName = "com.example.util.CollectionExtensions.property", - expectedDescription = "static property" - ) - } - } - } - - @Test - fun `should have documentation for synthetic Enum values functions`() { - testInline( - """ - |/src/main/kotlin/test/KotlinEnum.kt - |package test - | - |enum class KotlinEnum { - | FOO, BAR; - |} - """.trimIndent(), - configuration - ) { - documentablesMergingStage = { module -> - val kotlinEnum = module.packages.find { it.name == "test" } - ?.classlikes - ?.single { it.name == "KotlinEnum" } - assertNotNull(kotlinEnum) - val valuesFunction = kotlinEnum.functions.single { it.name == "values" } - - val expectedValuesType = GenericTypeConstructor( - dri = DRI( - packageName = "kotlin", - classNames = "Array" - ), - projections = listOf( - Invariance( - GenericTypeConstructor( - dri = DRI( - packageName = "test", - classNames = "KotlinEnum" - ), - projections = emptyList() - ) - ) - ) - ) - assertEquals(expectedValuesType, valuesFunction.type) - - val expectedDocumentation = DocumentationNode(listOf( - Description( - CustomDocTag( - children = listOf( - P(listOf( - Text( - "Returns an array containing the constants of this enum type, in the order " + - "they're declared." - ), - )), - P(listOf( - Text("This method may be used to iterate over the constants.") - )) - ), - name = "MARKDOWN_FILE" - ) - ) - )) - assertEquals(expectedDocumentation, valuesFunction.documentation.values.single()) - } - } - } - - @Test - fun `should have documentation for synthetic Enum entries property`() { - testInline( - """ - |/src/main/kotlin/test/KotlinEnum.kt - |package test - | - |enum class KotlinEnum { - | FOO, BAR; - |} - """.trimIndent(), - configuration - ) { - documentablesMergingStage = { module -> - val kotlinEnum = module.packages.find { it.name == "test" } - ?.classlikes - ?.single { it.name == "KotlinEnum" } - - assertNotNull(kotlinEnum) - - val entriesProperty = kotlinEnum.properties.single { it.name == "entries" } - val expectedEntriesType = GenericTypeConstructor( - dri = DRI( - packageName = "kotlin.enums", - classNames = "EnumEntries" - ), - projections = listOf( - Invariance( - GenericTypeConstructor( - dri = DRI( - packageName = "test", - classNames = "KotlinEnum" - ), - projections = emptyList() - ) - ) - ) - ) - assertEquals(expectedEntriesType, entriesProperty.type) - - val expectedDocumentation = DocumentationNode(listOf( - Description( - CustomDocTag( - children = listOf( - P(listOf( - Text( - "Returns a representation of an immutable list of all enum entries, " + - "in the order they're declared." - ), - )), - P(listOf( - Text("This method may be used to iterate over the enum entries.") - )) - ), - name = "MARKDOWN_FILE" - ) - ) - )) - assertEquals(expectedDocumentation, entriesProperty.documentation.values.single()) - } - } - } - - @OnlyDescriptors("Fix kdoc link") // TODO - @Test - fun `should have documentation for synthetic Enum valueOf functions`() { - testInline( - """ - |/src/main/kotlin/test/KotlinEnum.kt - |package test - | - |enum class KotlinEnum { - | FOO, BAR; - |} - """.trimIndent(), - configuration - ) { - documentablesMergingStage = { module -> - val kotlinEnum = module.packages.find { it.name == "test" } - ?.classlikes - ?.single { it.name == "KotlinEnum" } - assertNotNull(kotlinEnum) - - val expectedValueOfType = GenericTypeConstructor( - dri = DRI( - packageName = "test", - classNames = "KotlinEnum" - ), - projections = emptyList() - ) - - val expectedDocumentation = DocumentationNode(listOf( - Description( - CustomDocTag( - children = listOf( - P(listOf( - Text( - "Returns the enum constant of this type with the specified name. " + - "The string must match exactly an identifier used to declare an enum " + - "constant in this type. (Extraneous whitespace characters are not permitted.)" - ) - )) - ), - name = "MARKDOWN_FILE" - ) - ), - Throws( - root = CustomDocTag( - children = listOf( - P(listOf( - Text("if this enum type has no constant with the specified name") - )) - ), - name = "MARKDOWN_FILE" - ), - name = "kotlin.IllegalArgumentException", - exceptionAddress = DRI( - packageName = "kotlin", - classNames = "IllegalArgumentException", - target = PointingToDeclaration - ), - ) - )) - - val valueOfFunction = kotlinEnum.functions.single { it.name == "valueOf" } - assertEquals(expectedDocumentation, valueOfFunction.documentation.values.single()) - assertEquals(expectedValueOfType, valueOfFunction.type) - - val valueOfParamDRI = (valueOfFunction.parameters.single().type as GenericTypeConstructor).dri - assertEquals(DRI(packageName = "kotlin", classNames = "String"), valueOfParamDRI) - } - } - } - - @Test - fun `should add data modifier to data objects`() { - testInline( - """ - |/src/main/kotlin/test/KotlinDataObject.kt - |package test - | - |data object KotlinDataObject {} - """.trimIndent(), - configuration - ) { - documentablesMergingStage = { module -> - val pckg = module.packages.single { it.name == "test" } - - val dataObject = pckg.classlikes.single { it.name == "KotlinDataObject" } - assertTrue(dataObject is DObject) - - val modifiers = dataObject.modifiers().values.flatten() - assertEquals(1, modifiers.size) - assertEquals(ExtraModifiers.KotlinOnlyModifiers.Data, modifiers[0]) - } - } - } -} - -private sealed class TestSuite { - abstract val propertyName: String - - data class PropertyDoesntExist( - override val propertyName: String - ) : TestSuite() - - - data class PropertyExists( - override val propertyName: String, - val modifier: KotlinModifier, - val visibility: KotlinVisibility, - val additionalModifiers: Set - ) : TestSuite() - - data class FunctionDoesntExist( - override val propertyName: String, - ) : TestSuite() - - data class FunctionExists( - override val propertyName: String, - val modifier: KotlinModifier, - val visibility: KotlinVisibility, - val additionalModifiers: Set - ) : TestSuite() -} diff --git a/plugins/base/src/test/kotlin/translators/DefaultPsiToDocumentableTranslatorTest.kt b/plugins/base/src/test/kotlin/translators/DefaultPsiToDocumentableTranslatorTest.kt deleted file mode 100644 index 7e9bff1e..00000000 --- a/plugins/base/src/test/kotlin/translators/DefaultPsiToDocumentableTranslatorTest.kt +++ /dev/null @@ -1,1027 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package translators - -import org.jetbrains.dokka.DokkaConfiguration -import org.jetbrains.dokka.DokkaConfiguration.Visibility -import org.jetbrains.dokka.base.testApi.testRunner.BaseAbstractTest -import org.jetbrains.dokka.links.DRI -import org.jetbrains.dokka.links.PointingToDeclaration -import org.jetbrains.dokka.model.* -import org.jetbrains.dokka.model.doc.* -import kotlin.test.* - -class DefaultPsiToDocumentableTranslatorTest : BaseAbstractTest() { - val configuration = dokkaConfiguration { - sourceSets { - sourceSet { - sourceRoots = listOf("src/main/java") - } - } - } - - @Test - fun `method overriding two documented classes picks closest class documentation`() { - testInline( - """ - |/src/main/java/sample/BaseClass1.java - |package sample; - |public class BaseClass1 { - | /** B1 */ - | public void x() { } - |} - | - |/src/main/java/sample/BaseClass2.java - |package sample; - |public class BaseClass2 extends BaseClass1 { - | /** B2 */ - | public void x() { } - |} - | - |/src/main/java/sample/X.java - |package sample; - |public class X extends BaseClass2 { - | public void x() { } - |} - """.trimIndent(), - configuration - ) { - documentablesMergingStage = { module -> - val documentationOfFunctionX = module.documentationOf("X", "x") - assertTrue( - "B2" in documentationOfFunctionX, - "Expected nearest super method documentation to be parsed as documentation. " + - "Documentation: $documentationOfFunctionX" - ) - } - } - } - - @Test - fun `method overriding class and interface picks class documentation`() { - testInline( - """ - |/src/main/java/sample/BaseClass1.java - |package sample; - |public class BaseClass1 { - | /** B1 */ - | public void x() { } - |} - | - |/src/main/java/sample/Interface1.java - |package sample; - |public interface Interface1 { - | /** I1 */ - | public void x() {} - |} - | - |/src/main/java/sample/X.java - |package sample; - |public class X extends BaseClass1 implements Interface1 { - | public void x() { } - |} - """.trimMargin(), - configuration - ) { - documentablesMergingStage = { module -> - val documentationOfFunctionX = module.documentationOf("X", "x") - assertTrue( - "B1" in documentationOfFunctionX, - "Expected documentation of superclass being prioritized over interface " + - "Documentation: $documentationOfFunctionX" - ) - } - } - } - - @Test - fun `method overriding two classes picks closest documented class documentation`() { - testInline( - """ - |/src/main/java/sample/BaseClass1.java - |package sample; - |public class BaseClass1 { - | /** B1 */ - | public void x() { } - |} - | - |/src/main/java/sample/BaseClass2.java - |package sample; - |public class BaseClass2 extends BaseClass1 { - | public void x() {} - |} - | - |/src/main/java/sample/X.java - |package sample; - |public class X extends BaseClass2 { - | public void x() { } - |} - """.trimMargin(), - configuration - ) { - documentablesMergingStage = { module -> - val documentationOfFunctionX = module.documentationOf("X", "x") - assertTrue( - "B1" in documentationOfFunctionX, - "Expected Documentation \"B1\", found: \"$documentationOfFunctionX\"" - ) - } - } - } - - @Test - fun `java package-info package description`() { - testInline( - """ - |/src/main/java/sample/BaseClass1.java - |package sample; - |public class BaseClass1 { - | /** B1 */ - | void x() { } - |} - | - |/src/main/java/sample/BaseClass2.java - |package sample; - |public class BaseClass2 extends BaseClass1 { - | void x() {} - |} - | - |/src/main/java/sample/X.java - |package sample; - |public class X extends BaseClass2 { - | void x() { } - |} - | - |/src/main/java/sample/package-info.java - |/** - | * Here comes description from package-info - | */ - |package sample; - """.trimMargin(), - configuration - ) { - documentablesMergingStage = { module -> - val documentationOfPackage = module.packages.single().documentation.values.single().children.single() - .firstMemberOfType().body - assertEquals( - "Here comes description from package-info", documentationOfPackage - ) - } - } - } - - @Test - fun `java package-info package annotations`() { - testInline( - """ - |/src/main/java/sample/PackageAnnotation.java - |package sample; - |@java.lang.annotation.Target(java.lang.annotation.ElementType.PACKAGE) - |public @interface PackageAnnotation { - |} - | - |/src/main/java/sample/package-info.java - |@PackageAnnotation - |package sample; - """.trimMargin(), - configuration - ) { - documentablesMergingStage = { module -> - assertEquals( - Annotations.Annotation(DRI("sample", "PackageAnnotation"), emptyMap()), - module.packages.single().extra[Annotations]?.directAnnotations?.values?.single()?.single() - ) - } - } - } - - @Test - fun `should add default value to constant properties`() { - testInline( - """ - |/src/main/java/test/JavaConstants.java - |package test; - | - |public class JavaConstants { - | public static final byte BYTE = 1; - | public static final short SHORT = 2; - | public static final int INT = 3; - | public static final long LONG = 4L; - | public static final float FLOAT = 5.0f; - | public static final double DOUBLE = 6.0d; - | public static final String STRING = "Seven"; - | public static final char CHAR = 'E'; - | public static final boolean BOOLEAN = true; - |} - """.trimIndent(), - configuration - ) { - documentablesMergingStage = { module -> - val testedClass = module.packages.single().classlikes.single { it.name == "JavaConstants" } - - val constants = testedClass.properties - assertEquals(9, constants.size) - - val constantsByName = constants.associateBy { it.name } - fun getConstantExpression(name: String): Expression? { - return constantsByName.getValue(name).extra[DefaultValue]?.expression?.values?.first() - } - - assertEquals(IntegerConstant(1), getConstantExpression("BYTE")) - assertEquals(IntegerConstant(2), getConstantExpression("SHORT")) - assertEquals(IntegerConstant(3), getConstantExpression("INT")) - assertEquals(IntegerConstant(4), getConstantExpression("LONG")) - assertEquals(FloatConstant(5.0f), getConstantExpression("FLOAT")) - assertEquals(DoubleConstant(6.0), getConstantExpression("DOUBLE")) - assertEquals(StringConstant("Seven"), getConstantExpression("STRING")) - assertEquals(StringConstant("E"), getConstantExpression("CHAR")) - assertEquals(BooleanConstant(true), getConstantExpression("BOOLEAN")) - } - } - } - - @Test - fun `should resolve static imports used as annotation param values as literal values`() { - testInline( - """ - |/src/main/java/test/JavaClassUsingAnnotation.java - |package test; - | - |import static test.JavaConstants.STRING; - |import static test.JavaConstants.INTEGER; - |import static test.JavaConstants.LONG; - |import static test.JavaConstants.BOOLEAN; - |import static test.JavaConstants.DOUBLE; - |import static test.JavaConstants.FLOAT; - |import static test.JavaConstan