aboutsummaryrefslogtreecommitdiff
path: root/plugins/kotlin-as-java/src/test
diff options
context:
space:
mode:
authorAndrey Tyrin <andrei.tyrin@jetbrains.com>2022-10-31 13:50:29 +0100
committerGitHub <noreply@github.com>2022-10-31 13:50:29 +0100
commitfaca33f69872cfd3abe84e3b7e1d4a9e309d7abc (patch)
treed3bf5df9f4da8939995e980c5b0227dadf441807 /plugins/kotlin-as-java/src/test
parentc0aece910e9b012a45ef577136a3f986c52df23e (diff)
downloaddokka-faca33f69872cfd3abe84e3b7e1d4a9e309d7abc.tar.gz
dokka-faca33f69872cfd3abe84e3b7e1d4a9e309d7abc.tar.bz2
dokka-faca33f69872cfd3abe84e3b7e1d4a9e309d7abc.zip
Suppress useless companion for Kotlin-As-Java (#2681)
Diffstat (limited to 'plugins/kotlin-as-java/src/test')
-rw-r--r--plugins/kotlin-as-java/src/test/kotlin/CompanionAsJavaTest.kt548
-rw-r--r--plugins/kotlin-as-java/src/test/kotlin/JvmFieldTest.kt61
2 files changed, 609 insertions, 0 deletions
diff --git a/plugins/kotlin-as-java/src/test/kotlin/CompanionAsJavaTest.kt b/plugins/kotlin-as-java/src/test/kotlin/CompanionAsJavaTest.kt
new file mode 100644
index 00000000..3b2a8e89
--- /dev/null
+++ b/plugins/kotlin-as-java/src/test/kotlin/CompanionAsJavaTest.kt
@@ -0,0 +1,548 @@
+package kotlinAsJavaPlugin
+
+import org.jetbrains.dokka.base.testApi.testRunner.BaseAbstractTest
+import org.jetbrains.dokka.model.*
+import org.junit.jupiter.api.Test
+import kotlin.test.assertEquals
+import kotlin.test.assertNotNull
+import kotlin.test.assertNull
+import kotlin.test.assertTrue
+
+private const val COMPANION_NAME = "C"
+
+class CompanionAsJavaTest : BaseAbstractTest() {
+ private val configuration = dokkaConfiguration {
+ sourceSets {
+ sourceSet {
+ sourceRoots = listOf("src/")
+ classpath += jvmStdlibPath!!
+ }
+ }
+ }
+
+ @Test
+ fun `empty companion object should not be rendered`() {
+ testInline(
+ """
+ |/src/main/kotlin/kotlinAsJavaPlugin/sample.kt
+ |package kotlinAsJavaPlugin
+ |class MyClass {
+ | companion object $COMPANION_NAME {}
+ |}
+ """.trimMargin(),
+ configuration,
+ ) {
+ documentablesTransformationStage = { module ->
+ val parentClass = module.findClass("MyClass")
+
+ assertCompanionNotRendered(parentClass)
+ }
+ }
+ }
+
+ @Test
+ fun `companion object with only jvmField should not be rendered`() {
+ testInline(
+ """
+ |/src/main/kotlin/kotlinAsJavaPlugin/sample.kt
+ |package kotlinAsJavaPlugin
+ |class MyClass {
+ | companion object $COMPANION_NAME {
+ | @JvmField val jvmFieldProp: String = ""
+ | }
+ |}
+ """.trimMargin(),
+ configuration,
+ ) {
+ documentablesTransformationStage = { module ->
+ val parentClass = module.findClass("MyClass")
+
+ assertCompanionNotRendered(parentClass)
+ }
+ }
+ }
+
+ @Test
+ fun `companion property with jvmField should be static`() {
+ testInline(
+ """
+ |/src/main/kotlin/kotlinAsJavaPlugin/sample.kt
+ |package kotlinAsJavaPlugin
+ |class MyClass {
+ | companion object $COMPANION_NAME {
+ | @JvmField val jvmFieldProp: String = ""
+ | }
+ |}
+ """.trimMargin(),
+ configuration,
+ ) {
+ documentablesTransformationStage = { module ->
+ val parentClass = module.findClass("MyClass")
+
+ val parentClassProperty = parentClass.properties.firstOrNull { it.name == "jvmFieldProp" }
+ assertNotNull(parentClassProperty, "Parent class should contain the companion jvmField property")
+ assertIsStatic(parentClassProperty)
+ }
+ }
+ }
+
+ @Test
+ fun `companion object with only const should not be rendered`() {
+ testInline(
+ """
+ |/src/main/kotlin/kotlinAsJavaPlugin/sample.kt
+ |package kotlinAsJavaPlugin
+ |class MyClass {
+ | companion object $COMPANION_NAME {
+ | const val constProp: Int = 0
+ | }
+ |}
+ """.trimMargin(),
+ configuration,
+ ) {
+ documentablesTransformationStage = { module ->
+ val parentClass = module.findClass("MyClass")
+
+ assertCompanionNotRendered(parentClass)
+ }
+ }
+ }
+
+ @Test
+ fun `companion property with const should be static`() {
+ testInline(
+ """
+ |/src/main/kotlin/kotlinAsJavaPlugin/sample.kt
+ |package kotlinAsJavaPlugin
+ |class MyClass {
+ | companion object $COMPANION_NAME {
+ | const val constProp: Int = 0
+ | }
+ |}
+ """.trimMargin(),
+ configuration,
+ ) {
+ documentablesTransformationStage = { module ->
+ val parentClass = module.findClass("MyClass")
+
+ val parentClassProperty = parentClass.properties.firstOrNull { it.name == "constProp" }
+ assertNotNull(parentClassProperty, "Parent class should contain the companion const property")
+ assertIsStatic(parentClassProperty)
+ }
+ }
+ }
+
+ @Test
+ fun `companion object with only lateinit not rendered`() {
+ testInline(
+ """
+ |/src/main/kotlin/kotlinAsJavaPlugin/sample.kt
+ |package kotlinAsJavaPlugin
+ |class MyClass {
+ | companion object $COMPANION_NAME {
+ | lateinit var lateInitProp: String
+ | }
+ |}
+ """.trimMargin(),
+ configuration,
+ ) {
+ documentablesTransformationStage = { module ->
+ val parentClass = module.findClass("MyClass")
+
+ assertCompanionNotRendered(parentClass)
+ }
+ }
+ }
+
+ @Test
+ fun `companion property with lateinit should be static`() {
+ testInline(
+ """
+ |/src/main/kotlin/kotlinAsJavaPlugin/sample.kt
+ |package kotlinAsJavaPlugin
+ |class MyClass {
+ | companion object $COMPANION_NAME {
+ | lateinit var lateInitProp: String
+ | }
+ |}
+ """.trimMargin(),
+ configuration,
+ ) {
+ documentablesTransformationStage = { module ->
+ val parentClass = module.findClass("MyClass")
+
+ val parentClassProperty = parentClass.properties.firstOrNull { it.name == "lateInitProp" }
+ assertNotNull(parentClassProperty, "Parent class should contain the companion lateinit property")
+ assertIsStatic(parentClassProperty)
+ }
+ }
+ }
+
+ @Test
+ fun `companion object with only jvmStatic fun not rendered`() {
+ testInline(
+ """
+ |/src/main/kotlin/kotlinAsJavaPlugin/sample.kt
+ |package kotlinAsJavaPlugin
+ |class MyClass {
+ | companion object $COMPANION_NAME {
+ | @JvmStatic fun staticFun(): String = ""
+ | }
+ |}
+ """.trimMargin(),
+ configuration,
+ ) {
+ documentablesTransformationStage = { module ->
+ val parentClass = module.findClass("MyClass")
+
+ assertCompanionNotRendered(parentClass)
+ }
+ }
+ }
+
+ @Test
+ fun `companion function with JvmStatic should be static`() {
+ testInline(
+ """
+ |/src/main/kotlin/kotlinAsJavaPlugin/sample.kt
+ |package kotlinAsJavaPlugin
+ |class MyClass {
+ | companion object $COMPANION_NAME {
+ | @JvmStatic fun staticFun(): String = ""
+ | }
+ |}
+ """.trimMargin(),
+ configuration,
+ ) {
+ documentablesTransformationStage = { module ->
+ val parentClass = module.findClass("MyClass")
+
+ val parentClassFunction = parentClass.functions.firstOrNull { it.name == "staticFun" }
+ assertNotNull(parentClassFunction, "Parent class should contains the companion jvmStatic function")
+ assertIsStatic(parentClassFunction)
+ }
+ }
+ }
+
+ @Test
+ fun `companion object with nested classes is rendered`() {
+ testInline(
+ """
+ |/src/main/kotlin/kotlinAsJavaPlugin/sample.kt
+ |package kotlinAsJavaPlugin
+ |class MyClass {
+ | companion object $COMPANION_NAME {
+ | @JvmStatic
+ | fun staticFun1(): String = ""
+ |
+ | const val CONST_VAL: Int = 100
+ |
+ | class NestedClass
+ | object NestedObject
+ | }
+ |}
+ """.trimMargin(),
+ configuration,
+ ) {
+ documentablesTransformationStage = { module ->
+ val parentClass = module.findClass("MyClass")
+
+ assertCompanionRendered(parentClass)
+
+ val classLikes = parentClass.companion?.classlikes
+ assertNotNull(classLikes)
+ assertEquals(2, classLikes.size,
+ "Classlike list should contains nested class and object")
+ assertTrue(classLikes.any { it.name == "NestedClass" })
+ assertTrue(classLikes.any { it.name == "NestedObject" })
+
+ }
+ }
+ }
+
+ @Test
+ fun `companion object with supertype is rendered`() {
+ testInline(
+ """
+ |/src/main/kotlin/kotlinAsJavaPlugin/sample.kt
+ |package kotlinAsJavaPlugin
+ |
+ |class Parent
+ |interface IParent
+ |class MyClass {
+ | companion object $COMPANION_NAME : Parent(), IParent {
+ | }
+ |}
+ """.trimMargin(),
+ configuration,
+ ) {
+ documentablesTransformationStage = { module ->
+ val parentClass = module.findClass("MyClass")
+
+ assertCompanionRendered(parentClass)
+ }
+ }
+ }
+
+ @Test
+ fun `companion object rendered for own properties`() {
+ testInline(
+ """
+ |/src/main/kotlin/kotlinAsJavaPlugin/sample.kt
+ |package kotlinAsJavaPlugin
+ |class MyClass {
+ | companion object $COMPANION_NAME {
+ | @JvmField
+ | val jvmField: String = ""
+ | const val contVal: Int = 0
+ | lateinit var lateInit: String
+ |
+ | val rendered: Int = TODO()
+ | }
+ |}
+ """.trimMargin(),
+ configuration,
+ ) {
+ documentablesTransformationStage = { module ->
+ val parentClass = module.findClass("MyClass")
+
+ assertCompanionRendered(parentClass)
+
+ val properties = parentClass.companion?.properties
+
+ assertNotNull(properties)
+ assertEquals(2, properties.size) // including INSTANCE
+ assertTrue(properties.any { it.name == "rendered" })
+ assertTrue(properties.none { it.name == "jvmField1" })
+ assertTrue(properties.none { it.name == "contVal" })
+ assertTrue(properties.none { it.name == "lateInit" })
+ }
+ }
+ }
+
+ @Test
+ fun `companion object rendered for own functions`() {
+ testInline(
+ """
+ |/src/main/kotlin/kotlinAsJavaPlugin/sample.kt
+ |package kotlinAsJavaPlugin
+ |class MyClass {
+ | companion object $COMPANION_NAME {
+ | @JvmStatic
+ | fun staticFun(): String = ""
+ |
+ | fun renderedFun(): String = ""
+ | }
+ |}
+ """.trimMargin(),
+ configuration,
+ ) {
+ documentablesTransformationStage = { module ->
+ val parentClass = module.findClass("MyClass")
+
+ assertCompanionRendered(parentClass)
+
+ val functions = parentClass.companion?.functions
+
+ assertNotNull(functions)
+ assertEquals(1, functions.size)
+ assertTrue(functions.any { it.name == "renderedFun" })
+ assertTrue(functions.none { it.name == "staticFun" })
+ }
+ }
+ }
+
+ @Test
+ fun `companion const value should be rendered as public by default`() {
+ testInline(
+ """
+ |/src/main/kotlin/kotlinAsJavaPlugin/sample.kt
+ |package kotlinAsJavaPlugin
+ |class MyClass {
+ | companion object $COMPANION_NAME {
+ | const val constProp: String = ""
+ | }
+ |}
+ """.trimMargin(),
+ configuration,
+ ) {
+ documentablesTransformationStage = { module ->
+ val parentClass = module.findClass("MyClass")
+
+ assertEquals(
+ JavaVisibility.Public,
+ parentClass.properties.firstOrNull()?.visibility?.values?.first()
+ )
+ assertNull(parentClass.findFunction("constProp"), "There is no getter for the cont field")
+ }
+ }
+ }
+
+ @Test
+ fun `companion const value should preserve Java modifier`() {
+ testInline(
+ """
+ |/src/main/kotlin/kotlinAsJavaPlugin/sample.kt
+ |package kotlinAsJavaPlugin
+ |class MyClass {
+ | companion object $COMPANION_NAME {
+ | protected const val constProp: String = ""
+ | }
+ |}
+ """.trimMargin(),
+ dokkaConfiguration {
+ sourceSets {
+ sourceSet {
+ sourceRoots = listOf("src/")
+ classpath += jvmStdlibPath!!
+ documentedVisibilities = setOf(
+ org.jetbrains.dokka.DokkaConfiguration.Visibility.PUBLIC,
+ org.jetbrains.dokka.DokkaConfiguration.Visibility.PROTECTED
+ )
+ }
+ }
+ },
+ ) {
+ documentablesTransformationStage = { module ->
+ val parentClass = module.findClass("MyClass")
+
+ assertEquals(
+ JavaVisibility.Protected,
+ parentClass.properties.firstOrNull()?.visibility?.values?.first()
+ )
+ assertNull(parentClass.findFunction("constProp"), "There is no getter for the cont field")
+ }
+ }
+ }
+
+ @Test
+ fun `companion lateinit value should be rendered as public by default`() {
+ testInline(
+ """
+ |/src/main/kotlin/kotlinAsJavaPlugin/sample.kt
+ |package kotlinAsJavaPlugin
+ |class MyClass {
+ | companion object $COMPANION_NAME {
+ | lateinit var lateInitProp: String
+ | }
+ |}
+ """.trimMargin(),
+ configuration,
+ ) {
+ documentablesTransformationStage = { module ->
+ val parentClass = module.findClass("MyClass")
+
+ assertEquals(
+ JavaVisibility.Public,
+ parentClass.properties.firstOrNull()?.visibility?.values?.first()
+ )
+ assertNull(parentClass.findFunction("lateInitProp"), "There is no getter for the cont field")
+ }
+ }
+ }
+
+ @Test
+ fun `named companion instance property should be rendered if companion rendered`() {
+ testInline(
+ """
+ |/src/main/kotlin/kotlinAsJavaPlugin/sample.kt
+ |package kotlinAsJavaPlugin
+ |class MyClass {
+ | companion object $COMPANION_NAME {
+ | var property: String = ""
+ | }
+ |}
+ """.trimMargin(),
+ configuration,
+ ) {
+ documentablesTransformationStage = { module ->
+ val parentClass = module.findClass("MyClass")
+
+ assertNotNull(parentClass.properties.any { it.name == COMPANION_NAME })
+ }
+ }
+ }
+
+ @Test
+ fun `default named companion instance property should be rendered if companion rendered`() {
+ testInline(
+ """
+ |/src/main/kotlin/kotlinAsJavaPlugin/sample.kt
+ |package kotlinAsJavaPlugin
+ |class MyClass {
+ | companion object {
+ | var property: String = ""
+ | }
+ |}
+ """.trimMargin(),
+ configuration,
+ ) {
+ documentablesTransformationStage = { module ->
+ val parentClass = module.findClass("MyClass")
+
+ assertTrue(parentClass.properties.any { it.name == "Companion" })
+ }
+ }
+ }
+
+ @Test
+ fun `companion instance property should be hidden if companion not rendered`() {
+ testInline(
+ """
+ |/src/main/kotlin/kotlinAsJavaPlugin/sample.kt
+ |package kotlinAsJavaPlugin
+ |class MyClass {
+ | companion object $COMPANION_NAME {
+ | const val property: String = ""
+ | }
+ |}
+ """.trimMargin(),
+ configuration,
+ ) {
+ documentablesTransformationStage = { module ->
+ val parentClass = module.findClass("MyClass")
+
+ assertTrue(parentClass.properties.none { it.name == COMPANION_NAME })
+ }
+ }
+ }
+}
+
+private fun DModule.findClass(name: String) = packages.flatMap { it.classlikes }
+ .firstOrNull { it.name == name } as DClass
+
+private fun DClass.findFunction(name: String) = functions.firstOrNull { it.name.contains(name, ignoreCase = true) }
+
+private fun assertCompanionRendered(parentClass: DClass) {
+ assertNotNull(parentClass.companion, "Companion should not be null")
+ assertTrue(
+ parentClass.classlikes.any { it.name == COMPANION_NAME },
+ "Companion should be in classlikes list"
+ )
+}
+
+private fun assertCompanionNotRendered(parentClass: DClass) {
+ assertNull(parentClass.companion, "Companion should be null")
+ assertTrue(
+ parentClass.classlikes.none { it.name == COMPANION_NAME },
+ "Companion should not be in classlikes list"
+ )
+}
+
+private fun assertIsStatic(property: DProperty) {
+ val extra = property.extra[AdditionalModifiers]
+ assertNotNull(extra, "extra for property is present")
+ assertTrue(
+ extra.content.values.contains(setOf(ExtraModifiers.JavaOnlyModifiers.Static)),
+ "Property contains extra modifier static"
+ )
+}
+
+private fun assertIsStatic(function: DFunction) {
+ val extra = function.extra[AdditionalModifiers]
+ assertNotNull(extra, "extra for property is present")
+ assertTrue(
+ extra.content.values.contains(setOf(ExtraModifiers.JavaOnlyModifiers.Static)),
+ "Function contains extra modifier static"
+ )
+} \ No newline at end of file
diff --git a/plugins/kotlin-as-java/src/test/kotlin/JvmFieldTest.kt b/plugins/kotlin-as-java/src/test/kotlin/JvmFieldTest.kt
index 99ea017b..f0c44530 100644
--- a/plugins/kotlin-as-java/src/test/kotlin/JvmFieldTest.kt
+++ b/plugins/kotlin-as-java/src/test/kotlin/JvmFieldTest.kt
@@ -1,11 +1,14 @@
package kotlinAsJavaPlugin
import org.jetbrains.dokka.base.testApi.testRunner.BaseAbstractTest
+import org.jetbrains.dokka.model.AdditionalModifiers
+import org.jetbrains.dokka.model.ExtraModifiers
import org.jetbrains.dokka.model.JavaVisibility
import org.junit.jupiter.api.Test
import kotlin.test.assertEquals
import kotlin.test.assertNotNull
import kotlin.test.assertNull
+import kotlin.test.assertTrue
class JvmFieldTest : BaseAbstractTest() {
val configuration = dokkaConfiguration {
@@ -106,4 +109,62 @@ class JvmFieldTest : BaseAbstractTest() {
}
}
}
+
+ @Test
+ fun `enum jvmfield property should have no getters`(){
+ testInline(
+ """
+ |/src/main/kotlin/kotlinAsJavaPlugin/sample.kt
+ |package kotlinAsJavaPlugin
+ |enum class MyEnum {
+ | ITEM;
+ |
+ | @JvmField
+ | val property: String = TODO()
+ |}
+ """.trimMargin(),
+ configuration,
+ ) {
+ documentablesTransformationStage = { module ->
+ val classLike = module.packages.flatMap { it.classlikes }.first()
+ val property = classLike.properties.singleOrNull { it.name == "property" }
+ assertNotNull(property)
+ assertEquals(
+ emptyList(),
+ classLike.functions
+ .filter{ it.name.contains("property", ignoreCase = true) }
+ .map { it.name }
+ )
+ assertNull(property.getter)
+ assertNull(property.setter)
+ }
+ }
+ }
+
+
+ @Test
+ fun `object jvmfield property should be static`(){
+ testInline(
+ """
+ |/src/main/kotlin/kotlinAsJavaPlugin/sample.kt
+ |package kotlinAsJavaPlugin
+ |object MyObject {
+ | @JvmField
+ | val property: String = TODO()
+ |}
+ """.trimMargin(),
+ configuration,
+ ) {
+ documentablesTransformationStage = { module ->
+ val classLike = module.packages.flatMap { it.classlikes }.first()
+ val property = classLike.properties.singleOrNull { it.name == "property" }
+ assertNotNull(property)
+
+ val extra = property.extra[AdditionalModifiers]
+ assertNotNull(extra, "Additional modifiers for property are exist")
+ assertTrue(extra.content.values.contains(setOf(ExtraModifiers.JavaOnlyModifiers.Static)),
+ "Extra modifiers contains static")
+ }
+ }
+ }
}