diff --git a/platform/platform-tests/testSrc/com/intellij/ide/plugins/ClassLoaderConfiguratorTest.kt b/platform/platform-tests/testSrc/com/intellij/ide/plugins/ClassLoaderConfiguratorTest.kt index aaf4679809e2..46ab99297695 100644 --- a/platform/platform-tests/testSrc/com/intellij/ide/plugins/ClassLoaderConfiguratorTest.kt +++ b/platform/platform-tests/testSrc/com/intellij/ide/plugins/ClassLoaderConfiguratorTest.kt @@ -178,7 +178,7 @@ internal class ClassLoaderConfiguratorTest { } } -private fun loadDescriptors(dir: Path): PluginLoadingResult { +internal fun loadDescriptors(dir: Path): PluginLoadingResult { val result = PluginLoadingResult() val context = DescriptorListLoadingContext(customDisabledPlugins = emptySet(), customBrokenPluginVersions = emptyMap(), diff --git a/platform/platform-tests/testSrc/com/intellij/ide/plugins/KotlinK1andK2ModesTest.kt b/platform/platform-tests/testSrc/com/intellij/ide/plugins/KotlinK1andK2ModesTest.kt new file mode 100644 index 000000000000..5d5eb09b7592 --- /dev/null +++ b/platform/platform-tests/testSrc/com/intellij/ide/plugins/KotlinK1andK2ModesTest.kt @@ -0,0 +1,151 @@ +// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +package com.intellij.ide.plugins + +import com.intellij.testFramework.assertions.Assertions.assertThat +import com.intellij.testFramework.rules.InMemoryFsRule +import kotlinx.coroutines.runBlocking +import org.junit.Rule +import org.junit.Test +import org.junit.jupiter.api.parallel.Execution +import org.junit.jupiter.api.parallel.ExecutionMode +import java.nio.file.Path + +// The system property `idea.kotlin.plugin.use.k2` is changed so tests should be sequential +@Execution(ExecutionMode.SAME_THREAD) +class KotlinK1andK2ModesTest { + @Rule + @JvmField + val inMemoryFs = InMemoryFsRule() + + private val rootDir: Path get() = inMemoryFs.fs.getPath("/") + + @Test + fun `plugin depending on kotlin disabled by default in K2 mode`() = withKotlinPluginMode(isK2 = true) { + plugin(rootDir, """ + + foo + org.jetbrains.kotlin + + """) + + assertThat(getSinglePlugin(rootDir).isEnabled).isFalse() + } + + @Test + fun `explicitly incompatible plugin depending on kotlin disabled in K2 Mode`() = withKotlinPluginMode(isK2 = true) { + plugin(rootDir, """ + + foo + org.jetbrains.kotlin + + + + + + """) + + assertThat(getSinglePlugin(rootDir).isEnabled).isFalse() + } + + @Test + fun `explicitly incompatible plugin depending on kotlin disabled in K1 Mode`() = withKotlinPluginMode(isK2 = false) { + plugin(rootDir, """ + + foo + org.jetbrains.kotlin + + + + + + """) + + assertThat(getSinglePlugin(rootDir).isEnabled).isFalse() + } + + @Test + fun `plugin depending on kotlin is enabled when with supportsK2`() = withKotlinPluginMode(isK2 = true) { + plugin(rootDir, """ + + foo + org.jetbrains.kotlin + + + + + + + """) + + assertThat(getSinglePlugin(rootDir).isEnabled).isTrue() + } + + + @Test + fun `plugin optionally depending on kotlin plugin is not disabled by default in K2 mode and optional dependency is disabled`() = withKotlinPluginMode(isK2 = true) { + plugin(rootDir, """ + + foo + org.jetbrains.kotlin + + """) + + dependencyXml(rootDir, "foo", "kt.xml", """ + + + """) + + val plugin = getSinglePlugin(rootDir) + assertThat(plugin.isEnabled).isTrue() + + val dependency = plugin.pluginDependencies.single() + assertThat(dependency.subDescriptor).isNull() + } + + @Test + fun `plugin optionally depending on kotlin plugin is not disabled by default in K2 mode and optional dependency is not disabled`() = withKotlinPluginMode(isK2 = true) { + plugin(rootDir, """ + + foo + + + + org.jetbrains.kotlin + + """) + + dependencyXml(rootDir, "foo", "kt.xml", """ + + + """) + + val plugin = getSinglePlugin(rootDir) + assertThat(plugin.isEnabled).isTrue() + + val dependency = plugin.pluginDependencies.single() + assertThat(dependency.subDescriptor).isNotNull() + } +} + +private fun getSinglePlugin(rootDir: Path): IdeaPluginDescriptorImpl { + val pluginResult = runBlocking { loadDescriptors(rootDir) } + val allPlugins = pluginResult.getIncompleteIdMap().values + pluginResult.enabledPlugins + val plugin = allPlugins.single() + return plugin +} + +private inline fun withKotlinPluginMode(isK2: Boolean, action: () -> Unit) { + val current = System.getProperty("idea.kotlin.plugin.use.k2") + System.setProperty("idea.kotlin.plugin.use.k2", isK2.toString()) + try { + action() + } + finally { + if (current == null) { + System.clearProperty("idea.kotlin.plugin.use.k2") + } + else { + System.setProperty("idea.kotlin.plugin.use.k2", current) + } + } +} \ No newline at end of file diff --git a/platform/platform-tests/testSrc/com/intellij/ide/plugins/PluginBuilder.kt b/platform/platform-tests/testSrc/com/intellij/ide/plugins/PluginBuilder.kt index e971a9da61ae..2ef4a7ec75c7 100644 --- a/platform/platform-tests/testSrc/com/intellij/ide/plugins/PluginBuilder.kt +++ b/platform/platform-tests/testSrc/com/intellij/ide/plugins/PluginBuilder.kt @@ -23,6 +23,16 @@ fun plugin(outDir: Path, @Language("XML") descriptor: String) { outDir.resolve("${rawDescriptor.id!!}/${PluginManagerCore.PLUGIN_XML_PATH}").write(descriptor.trimIndent()) } +fun dependencyXml(outDir: Path, ownerId: String, filename: String, @Language("XML") descriptor: String) { + try { + readModuleDescriptorForTest(descriptor.toByteArray()) + } + catch (e: Throwable) { + throw RuntimeException("Cannot parse:\n ${descriptor.trimIndent().prependIndent(" ")}", e) + } + outDir.resolve("${ownerId}/${PluginManagerCore.META_INF}${filename}").write(descriptor.trimIndent()) +} + fun module(outDir: Path, ownerId: String, moduleId: String, @Language("XML") descriptor: String) { try { readModuleDescriptorForTest(descriptor.toByteArray())