diff --git a/plugins/devkit/devkit-core/resources/intellij.devkit.core.xml b/plugins/devkit/devkit-core/resources/intellij.devkit.core.xml index ee571be5d810..90f490ee12e7 100644 --- a/plugins/devkit/devkit-core/resources/intellij.devkit.core.xml +++ b/plugins/devkit/devkit-core/resources/intellij.devkit.core.xml @@ -585,6 +585,9 @@ + + diff --git a/plugins/devkit/devkit-core/src/run/JUnitDevKitPatcher.java b/plugins/devkit/devkit-core/src/run/JUnitDevKitPatcher.java index 733e3d931c73..d56f8e5f4fb4 100644 --- a/plugins/devkit/devkit-core/src/run/JUnitDevKitPatcher.java +++ b/plugins/devkit/devkit-core/src/run/JUnitDevKitPatcher.java @@ -82,6 +82,10 @@ final class JUnitDevKitPatcher extends JUnitPatcher { } appendAddOpensWhenNeeded(project, jdk, vm); + + if (!Boolean.parseBoolean(vm.getPropertyValue("intellij.devkit.junit.skip.settings.from.intellij.yaml"))) { + JUnitDevKitUnitTestingSettings.getInstance(project).apply(module, javaParameters); + } } jdk = IdeaJdk.findIdeaJdk(jdk); diff --git a/plugins/devkit/devkit-core/src/run/JUnitDevKitUnitTestingSettings.kt b/plugins/devkit/devkit-core/src/run/JUnitDevKitUnitTestingSettings.kt new file mode 100644 index 000000000000..88a0f52bdbad --- /dev/null +++ b/plugins/devkit/devkit-core/src/run/JUnitDevKitUnitTestingSettings.kt @@ -0,0 +1,103 @@ +// Copyright 2000-2024 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +package org.jetbrains.idea.devkit.run + +import com.intellij.configurationStore.Property +import com.intellij.execution.ShortenCommandLine +import com.intellij.execution.configurations.JavaParameters +import com.intellij.openapi.components.* +import com.intellij.openapi.module.Module +import com.intellij.openapi.module.ModuleManager +import com.intellij.openapi.project.Project +import org.jetbrains.annotations.ApiStatus + +@ApiStatus.Internal +@Suppress("LightServiceMigrationCode") // IJI-2399 +internal class JUnitDevKitUnitTestingSettings( + private val project: Project, +) : SimplePersistentStateComponent(JUnitDevKitUnitTestingSettingsState()) { + companion object { + @JvmStatic + fun getInstance(project: Project): JUnitDevKitUnitTestingSettings = project.service() + } + + fun apply(module: Module?, javaParameters: JavaParameters) { + if (module == null) return + val runner = state.runners.firstOrNull { + it.enabledForModules.any { matchesName(module.name, it) } && it.disabledForModules.none { matchesName(module.name, it) } + } ?: return + + for (arg in runner.jvmArgs) { + if (arg.startsWith("-D")) { + val parts = arg.substring(2).split('=', limit = 2) + if (parts.size == 1) { + javaParameters.vmParametersList.addProperty(parts[0]) + } + else { + javaParameters.vmParametersList.addProperty(parts[0], expandMacros(parts[1], module, javaParameters, project)) + } + } + else { + javaParameters.vmParametersList.add(arg) + } + } + + for (env in runner.envs) { + val parts = env.split('=', limit = 2) + if (parts.size == 1) continue + javaParameters.addEnv(parts[0], expandMacros(parts[1], module, javaParameters, project)) + } + + val mainClassModule = runner.mainClassModule?.let { ModuleManager.getInstance(project).findModuleByName(it) } + if (mainClassModule != null) { + javaParameters.mainClass = runner.mainClass + javaParameters.classPath.clear() + javaParameters.configureByModule(mainClassModule, JavaParameters.CLASSES_ONLY) + } + + javaParameters.setShortenCommandLine(ShortenCommandLine.ARGS_FILE) + javaParameters.setUseDynamicVMOptions(true) + } + + private fun expandMacros(value: String, module: Module, javaParameters: JavaParameters, project: Project) = value + .replace("${'$'}TEST_MODULE_CLASSPATH$", javaParameters.classPath.pathsString) + .replace("${'$'}TEST_MODULE_NAME$", module.name) + .replace("${'$'}TEST_PROJECT_BASE_PATH$", project.basePath ?: "") + + private fun matchesName(moduleName: String, pattern: String) = + if (pattern.lastOrNull() == '*') { + moduleName.startsWith(pattern.substring(0, pattern.length - 1)) + } + else { + moduleName == pattern + } +} + +@ApiStatus.Internal +internal class JUnitDevKitUnitTestingSettingsState : BaseState() { + @Property(description = "List of available runners") + var runners by list() +} + +@ApiStatus.Internal +internal class JUnitDevKitUnitTestingSettingsRunner : BaseState() { + @Property(description = "Name") + var name by string() + + @Property(description = "Module name where the main class is defined") + var mainClassModule by string() + + @Property(description = "Main class") + var mainClass by string() + + @Property(description = "List of module names (or patterns) this runner should be applied to") + var enabledForModules by list() + + @Property(description = "List of module names (or patterns) this runner must not be applied to") + var disabledForModules by list() + + @Property(description = "Additional JVM arguments") + var jvmArgs by list() + + @Property(description = "Additional environment variables") + var envs by list() +}