[KPM] Implement IdeaKotlinProjectModelObjectGraphTest

KT-51262
KT-51220
This commit is contained in:
sebastian.sellmair
2022-02-17 13:51:16 +01:00
committed by Space
parent 7a2eaa5101
commit 18d3854097
6 changed files with 119 additions and 2 deletions
+10
View File
@@ -5946,6 +5946,11 @@
<sha256 value="e6531a278b4f632f198a6e45b9e11de1b2b678cd5a4e0fdff442f604c2439a42" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="org.javassist" name="javassist" version="3.28.0-GA">
<artifact name="javassist-3.28.0-GA.jar">
<sha256 value="57d0a9e9286f82f4eaa851125186997f811befce0e2060ff0a15a77f5a9dd9a7" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="org.jboss" name="jboss-parent" version="5">
<artifact name="jboss-parent-5.pom">
<md5 value="46faf8173525fc8e982213ff1696ad2d" origin="Generated by Gradle"/>
@@ -7849,6 +7854,11 @@
<sha256 value="7206cbbfd6efd5e85bceff29545633645650be58d58910a23b0d4835fbd15ed7" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="org.reflections" name="reflections" version="0.10.2">
<artifact name="reflections-0.10.2.jar">
<sha256 value="938a2d08fe54050d7610b944d8ddc3a09355710d9e6be0aac838dbc04e9a2825" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="org.robolectric" name="android-all" version="4.4_r1-robolectric-1">
<artifact name="android-all-4.4_r1-robolectric-1.jar">
<md5 value="1e478f10e107d1dddad09d32508f2ec9" origin="Generated by Gradle"/>
@@ -3,7 +3,7 @@ plugins {
}
object BackwardsCompatibilityTestConfiguration {
const val minimalBackwardsCompatibleVersion = "1.7.0-dev-1924"
const val minimalBackwardsCompatibleVersion = "1.7.0-dev-1987"
}
kotlin.sourceSets.configureEach {
@@ -18,6 +18,9 @@ dependencies {
testImplementation(gradleKotlinDsl())
testImplementation(project(":kotlin-gradle-plugin"))
testImplementation(project(":kotlin-test:kotlin-test-junit"))
testImplementation("org.reflections:reflections:0.10.2") {
because("Tests on the object graph are performed. This library will find implementations of interfaces at runtime")
}
}
publish()
@@ -38,6 +38,9 @@ sealed class KotlinExternalModelContainer : Serializable {
override val ids: Set<KotlinExternalModelId<*>> = emptySet()
override fun <T : Any> contains(key: KotlinExternalModelKey<T>): Boolean = false
override fun <T : Any> get(key: KotlinExternalModelKey<T>): T? = null
private const val serialVersionUID = 0L
}
override fun toString(): String {
@@ -18,6 +18,8 @@ data class IdeaKotlinVariantImpl(
override val variantAttributes: Map<String, String>,
override val compilationOutputs: IdeaKotlinCompilationOutput,
) : IdeaKotlinVariant, IdeaKotlinFragment by fragment {
@InternalKotlinGradlePluginApi
companion object {
private const val serialVersionUID = 0L
}
@@ -26,7 +26,6 @@ import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinIosX64Variant
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinLinuxX64Variant
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinPm20ProjectExtension
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.jvm
import org.junit.Test
import serialize
import unwrapProxyInstance
import java.io.File
@@ -0,0 +1,100 @@
/*
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.gradle.kpm.idea
import org.junit.runner.RunWith
import org.junit.runners.Parameterized
import org.reflections.Reflections
import java.lang.reflect.Field
import java.lang.reflect.Modifier
import kotlin.reflect.KClass
import kotlin.reflect.full.memberProperties
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertNotNull
import kotlin.test.assertTrue
@OptIn(kotlin.ExperimentalStdlibApi::class)
@RunWith(Parameterized::class)
class IdeaKotlinProjectModelObjectGraphTest(private val node: KClass<*>, @Suppress("unused_parameter") clazzName: String) {
@Test
fun `test - node implements Serializable`() {
assertTrue(
java.io.Serializable::class.java.isAssignableFrom(node.java),
"Expected node ${node.simpleName} to implement `Serializable`"
)
}
@Test
fun `test - node implementations contain serialVersionUID`() {
val reflections = Reflections("org.jetbrains.kotlin")
reflections.getSubTypesOf(node.java).forEach { subtype ->
if (!subtype.isInterface && !Modifier.isAbstract(subtype.modifiers)) {
assertNodeImplementationDefinesSerialVersionUID(subtype)
}
}
}
private fun assertNodeImplementationDefinesSerialVersionUID(implementationClass: Class<*>) {
val serialVersionUID = assertNotNull(
implementationClass.getDeclaredFieldOrNull("serialVersionUID"),
"Expected $implementationClass to declare 'serialVersionUID' field"
)
assertTrue(
Modifier.isStatic(serialVersionUID.modifiers),
"Expected $implementationClass to declare 'serialVersionUID' statically"
)
assertTrue(
serialVersionUID.type.isPrimitive,
"Expected $implementationClass to declare primitive 'serialVersionUID'"
)
assertEquals(
serialVersionUID.type, Long::class.javaPrimitiveType,
"Expected $implementationClass to declare 'serialVersionUID' of type Long"
)
}
private fun Class<*>.getDeclaredFieldOrNull(name: String): Field? {
return try {
getDeclaredField(name)
} catch (t: NoSuchFieldException) {
return null
}
}
companion object {
@JvmStatic
@Parameterized.Parameters(name = "{1}")
fun findNodes(): List<Array<Any>> {
val classes = mutableSetOf<KClass<*>>(IdeaKotlinProjectModel::class)
val resolveQueue = ArrayDeque(classes)
while (resolveQueue.isNotEmpty()) {
val children = resolveQueue.removeFirst().resolveReachableClasses()
children.forEach { child ->
if (classes.add(child)) {
resolveQueue.add(child)
}
}
}
return classes.map { clazz -> arrayOf<Any>(clazz, checkNotNull(clazz.simpleName)) }
}
private fun KClass<*>.resolveReachableClasses(): Set<KClass<*>> {
return this.memberProperties
.map { member -> member.returnType }
.flatMap { type -> setOf(type) + type.arguments.mapNotNull { it.type } }
.mapNotNull { type -> type.classifier as? KClass<*> }
.filter { clazz -> clazz.java.name.startsWith("org.jetbrains") }
.toSet()
}
}
}