Skip to content

Go plugin fixes #1851

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Feb 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,17 +1,14 @@
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
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

Expand All @@ -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
)
Expand All @@ -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)
Expand Down
Original file line number Diff line number Diff line change
@@ -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<GoFunctionOrMethodDeclaration>,
focusedTargetFunctions: Set<GoFunctionOrMethodDeclaration>,
) {
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<GoFunctionOrMethodDeclaration>,
focusedTargetFunctions: Set<GoFunctionOrMethodDeclaration>,
): 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,
)
Expand All @@ -51,8 +89,7 @@ object GoUtTestsDialogProcessor {
)

IntellijGoUtTestsGenerationController(model, indicator).generateTests(
selectedFunctionsNamesBySourceFiles,
testsGenerationConfig
selectedFunctionsNamesBySourceFiles, testsGenerationConfig
) { indicator.isCanceled }
}
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@ import org.utbot.go.logic.GoUtTestsGenerationConfig
*/
data class GenerateGoTestsModel(
val project: Project,
val goExecutableAbsolutePath: String,
val targetFunctions: Set<GoFunctionOrMethodDeclaration>,
val focusedTargetFunctions: Set<GoFunctionOrMethodDeclaration>,
) {
lateinit var selectedFunctions: Set<GoFunctionOrMethodDeclaration>
lateinit var goExecutableAbsolutePath: String
var eachFunctionExecutionTimeoutMillis: Long = GoUtTestsGenerationConfig.DEFAULT_EACH_EXECUTION_TIMEOUT_MILLIS
var allFunctionExecutionTimeoutMillis: Long = GoUtTestsGenerationConfig.DEFAULT_ALL_EXECUTION_TIMEOUT_MILLIS
}
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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(),
Expand All @@ -52,17 +49,14 @@ 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()
}

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)
Expand All @@ -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()
Expand Down Expand Up @@ -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()) {
Expand Down