From 902fe24e2417dbcaca1b1e96cee33fed37a9c94d Mon Sep 17 00:00:00 2001 From: Egipti Pavel Date: Wed, 22 Feb 2023 14:53:08 +0300 Subject: [PATCH 1/2] Delete project SDK field from UnitTestBot action dialog. Add auto detection of project SDK and error dialogs when SDK isn't setup or version less than 1.18 --- .../plugin/language/go/GoLanguageAssistant.kt | 10 ++-- .../go/generator/GoUtTestsDialogProcessor.kt | 51 ++++++++++++++++--- .../go/models/GenerateGoTestsModel.kt | 2 +- .../go/ui/GenerateGoTestsDialogWindow.kt | 15 +----- 4 files changed, 51 insertions(+), 27 deletions(-) diff --git a/utbot-intellij-go/src/main/kotlin/org/utbot/intellij/plugin/language/go/GoLanguageAssistant.kt b/utbot-intellij-go/src/main/kotlin/org/utbot/intellij/plugin/language/go/GoLanguageAssistant.kt index fde7f9334e..738d20c39a 100644 --- a/utbot-intellij-go/src/main/kotlin/org/utbot/intellij/plugin/language/go/GoLanguageAssistant.kt +++ b/utbot-intellij-go/src/main/kotlin/org/utbot/intellij/plugin/language/go/GoLanguageAssistant.kt @@ -1,10 +1,6 @@ package org.utbot.intellij.plugin.language.go -import com.goide.psi.GoFile -import com.goide.psi.GoFunctionOrMethodDeclaration -import com.goide.psi.GoMethodDeclaration -import com.goide.psi.GoPointerType -import com.goide.psi.GoStructType +import com.goide.psi.* import com.intellij.lang.Language import com.intellij.openapi.actionSystem.AnActionEvent import com.intellij.openapi.actionSystem.CommonDataKeys @@ -12,6 +8,7 @@ import com.intellij.openapi.editor.Editor import com.intellij.psi.PsiElement import com.intellij.psi.PsiFile import com.intellij.psi.util.PsiTreeUtil +import org.jetbrains.kotlin.idea.util.module import org.utbot.intellij.plugin.language.agnostic.LanguageAssistant import org.utbot.intellij.plugin.language.go.generator.GoUtTestsDialogProcessor @@ -28,9 +25,12 @@ object GoLanguageAssistant : LanguageAssistant() { override fun actionPerformed(e: AnActionEvent) { val project = e.project ?: return + val file = e.getData(CommonDataKeys.PSI_FILE) as? GoFile ?: return + val module = file.module ?: return val (targetFunctions, focusedTargetFunctions) = getPsiTargets(e) ?: return GoUtTestsDialogProcessor.createDialogAndGenerateTests( project, + module, targetFunctions, focusedTargetFunctions ) diff --git a/utbot-intellij-go/src/main/kotlin/org/utbot/intellij/plugin/language/go/generator/GoUtTestsDialogProcessor.kt b/utbot-intellij-go/src/main/kotlin/org/utbot/intellij/plugin/language/go/generator/GoUtTestsDialogProcessor.kt index 5bb39fee47..fbca87c656 100644 --- a/utbot-intellij-go/src/main/kotlin/org/utbot/intellij/plugin/language/go/generator/GoUtTestsDialogProcessor.kt +++ b/utbot-intellij-go/src/main/kotlin/org/utbot/intellij/plugin/language/go/generator/GoUtTestsDialogProcessor.kt @@ -1,36 +1,74 @@ package org.utbot.intellij.plugin.language.go.generator import com.goide.psi.GoFunctionOrMethodDeclaration +import com.goide.sdk.GoSdk +import com.goide.sdk.GoSdkService +import com.goide.sdk.GoSdkVersion import com.intellij.openapi.application.runReadAction +import com.intellij.openapi.module.Module +import com.intellij.openapi.options.ShowSettingsUtil import com.intellij.openapi.progress.ProgressIndicator import com.intellij.openapi.progress.ProgressManager import com.intellij.openapi.progress.Task import com.intellij.openapi.project.Project +import com.intellij.openapi.ui.Messages import org.utbot.go.logic.GoUtTestsGenerationConfig import org.utbot.intellij.plugin.language.go.models.GenerateGoTestsModel import org.utbot.intellij.plugin.language.go.ui.GenerateGoTestsDialogWindow +import org.utbot.intellij.plugin.language.go.ui.utils.resolveGoExecutablePath object GoUtTestsDialogProcessor { fun createDialogAndGenerateTests( project: Project, + module: Module, targetFunctions: Set, focusedTargetFunctions: Set, ) { - val dialogProcessor = createDialog(project, targetFunctions, focusedTargetFunctions) - if (!dialogProcessor.showAndGet()) return - - createTests(dialogProcessor.model) + createDialog(project, module, targetFunctions, focusedTargetFunctions)?.let { + if (it.showAndGet()) createTests(it.model) + } } private fun createDialog( project: Project, + module: Module, targetFunctions: Set, focusedTargetFunctions: Set, - ): GenerateGoTestsDialogWindow { + ): GenerateGoTestsDialogWindow? { + val goSdk = GoSdkService.getInstance(project).getSdk(module) + if (goSdk == GoSdk.NULL) { + val result = Messages.showOkCancelDialog( + project, + "GOROOT is not defined. Select it?", + "Unsupported Go SDK", + "Select", + "Cancel", + Messages.getErrorIcon() + ) + if (result == Messages.OK) { + ShowSettingsUtil.getInstance().showSettingsDialog(project, "GOROOT") + } + return null + } else if (!goSdk.isValid || GoSdkVersion.fromText(goSdk.version).isLessThan(GoSdkVersion.GO_1_18)) { + val result = Messages.showOkCancelDialog( + project, + "Go SDK isn't valid or version less than 1.18. Select another SDK?", + "Unsupported Go SDK", + "Select", + "Cancel", + Messages.getErrorIcon() + ) + if (result == Messages.OK) { + ShowSettingsUtil.getInstance().showSettingsDialog(project, "GOROOT") + } + return null + } + return GenerateGoTestsDialogWindow( GenerateGoTestsModel( project, + goSdk.resolveGoExecutablePath()!!, targetFunctions, focusedTargetFunctions, ) @@ -51,8 +89,7 @@ object GoUtTestsDialogProcessor { ) IntellijGoUtTestsGenerationController(model, indicator).generateTests( - selectedFunctionsNamesBySourceFiles, - testsGenerationConfig + selectedFunctionsNamesBySourceFiles, testsGenerationConfig ) { indicator.isCanceled } } }) diff --git a/utbot-intellij-go/src/main/kotlin/org/utbot/intellij/plugin/language/go/models/GenerateGoTestsModel.kt b/utbot-intellij-go/src/main/kotlin/org/utbot/intellij/plugin/language/go/models/GenerateGoTestsModel.kt index 5a398efd7a..903ae01cc7 100644 --- a/utbot-intellij-go/src/main/kotlin/org/utbot/intellij/plugin/language/go/models/GenerateGoTestsModel.kt +++ b/utbot-intellij-go/src/main/kotlin/org/utbot/intellij/plugin/language/go/models/GenerateGoTestsModel.kt @@ -15,11 +15,11 @@ import org.utbot.go.logic.GoUtTestsGenerationConfig */ data class GenerateGoTestsModel( val project: Project, + val goExecutableAbsolutePath: String, val targetFunctions: Set, val focusedTargetFunctions: Set, ) { lateinit var selectedFunctions: Set - lateinit var goExecutableAbsolutePath: String var eachFunctionExecutionTimeoutMillis: Long = GoUtTestsGenerationConfig.DEFAULT_EACH_EXECUTION_TIMEOUT_MILLIS var allFunctionExecutionTimeoutMillis: Long = GoUtTestsGenerationConfig.DEFAULT_ALL_EXECUTION_TIMEOUT_MILLIS } \ No newline at end of file diff --git a/utbot-intellij-go/src/main/kotlin/org/utbot/intellij/plugin/language/go/ui/GenerateGoTestsDialogWindow.kt b/utbot-intellij-go/src/main/kotlin/org/utbot/intellij/plugin/language/go/ui/GenerateGoTestsDialogWindow.kt index 3fe899f484..e424394b10 100644 --- a/utbot-intellij-go/src/main/kotlin/org/utbot/intellij/plugin/language/go/ui/GenerateGoTestsDialogWindow.kt +++ b/utbot-intellij-go/src/main/kotlin/org/utbot/intellij/plugin/language/go/ui/GenerateGoTestsDialogWindow.kt @@ -2,7 +2,6 @@ package org.utbot.intellij.plugin.language.go.ui import com.goide.psi.GoFunctionOrMethodDeclaration import com.goide.refactor.ui.GoDeclarationInfo -import com.goide.sdk.combobox.GoSdkChooserCombo import com.intellij.openapi.ui.DialogPanel import com.intellij.openapi.ui.DialogWrapper import com.intellij.openapi.ui.ValidationInfo @@ -13,7 +12,6 @@ import com.intellij.util.ui.JBUI import com.intellij.util.ui.UIUtil import org.utbot.go.logic.GoUtTestsGenerationConfig import org.utbot.intellij.plugin.language.go.models.GenerateGoTestsModel -import org.utbot.intellij.plugin.language.go.ui.utils.resolveGoExecutablePath import java.text.ParseException import java.util.concurrent.TimeUnit import javax.swing.JComponent @@ -33,7 +31,6 @@ class GenerateGoTestsDialogWindow(val model: GenerateGoTestsModel) : DialogWrapp this.preferredScrollableViewportSize = JBUI.size(-1, height) } - private val projectGoSdkField = GoSdkChooserCombo() private val allFunctionExecutionTimeoutSecondsSpinner = JBIntSpinner( TimeUnit.MILLISECONDS.toSeconds(GoUtTestsGenerationConfig.DEFAULT_ALL_EXECUTION_TIMEOUT_MILLIS).toInt(), @@ -52,7 +49,7 @@ class GenerateGoTestsDialogWindow(val model: GenerateGoTestsModel) : DialogWrapp private lateinit var panel: DialogPanel init { - title = "Generate Tests with UtBot" + title = "Generate Tests with UnitTestBot" isResizable = false init() } @@ -60,9 +57,6 @@ class GenerateGoTestsDialogWindow(val model: GenerateGoTestsModel) : DialogWrapp override fun createCenterPanel(): JComponent { panel = panel { row("Test source root: near to source files") {} - row("Project Go SDK:") { - component(projectGoSdkField) - } row("Generate test methods for:") {} row { scrollPane(targetFunctionsTable) @@ -82,7 +76,6 @@ class GenerateGoTestsDialogWindow(val model: GenerateGoTestsModel) : DialogWrapp override fun doOKAction() { model.selectedFunctions = targetFunctionsTable.selectedMemberInfos.fromInfos() - model.goExecutableAbsolutePath = projectGoSdkField.sdk.resolveGoExecutablePath()!! try { eachFunctionExecutionTimeoutMillisSpinner.commitEdit() allFunctionExecutionTimeoutSecondsSpinner.commitEdit() @@ -119,12 +112,6 @@ class GenerateGoTestsDialogWindow(val model: GenerateGoTestsModel) : DialogWrapp @Suppress("DuplicatedCode") // This method is highly inspired by GenerateTestsDialogWindow.doValidate(). override fun doValidate(): ValidationInfo? { - projectGoSdkField.sdk.resolveGoExecutablePath() - ?: return ValidationInfo( - "Go SDK is not configured", - projectGoSdkField.childComponent - ) - targetFunctionsTable.tableHeader?.background = UIUtil.getTableBackground() targetFunctionsTable.background = UIUtil.getTableBackground() if (targetFunctionsTable.selectedMemberInfos.isEmpty()) { From 9b794f01abd3ec05c2d1b62f9082bbee5b1ed2c6 Mon Sep 17 00:00:00 2001 From: Egipti Pavel Date: Wed, 22 Feb 2023 19:27:53 +0300 Subject: [PATCH 2/2] Run plugin action from context menu --- .../intellij/plugin/language/go/GoLanguageAssistant.kt | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/utbot-intellij-go/src/main/kotlin/org/utbot/intellij/plugin/language/go/GoLanguageAssistant.kt b/utbot-intellij-go/src/main/kotlin/org/utbot/intellij/plugin/language/go/GoLanguageAssistant.kt index 738d20c39a..5f0a341fab 100644 --- a/utbot-intellij-go/src/main/kotlin/org/utbot/intellij/plugin/language/go/GoLanguageAssistant.kt +++ b/utbot-intellij-go/src/main/kotlin/org/utbot/intellij/plugin/language/go/GoLanguageAssistant.kt @@ -43,11 +43,13 @@ object GoLanguageAssistant : LanguageAssistant() { private fun getPsiTargets(e: AnActionEvent): PsiTargets? { e.project ?: return null - // The action is being called from editor or return. TODO: support other cases instead of return. - val editor = e.getData(CommonDataKeys.EDITOR) ?: return null - + val editor = e.getData(CommonDataKeys.EDITOR) val file = e.getData(CommonDataKeys.PSI_FILE) as? GoFile ?: return null - val element = findPsiElement(file, editor) ?: return null + val element = if (editor != null) { + findPsiElement(file, editor) ?: return null + } else { + e.getData(CommonDataKeys.PSI_ELEMENT) ?: return null + } val containingFunction = getContainingFunction(element) val targetFunctions = extractTargetFunctionsOrMethods(file)