diff --git a/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/ui/GenerateTestsDialogWindow.kt b/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/ui/GenerateTestsDialogWindow.kt index d1fdf4a429..954f9e6177 100644 --- a/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/ui/GenerateTestsDialogWindow.kt +++ b/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/ui/GenerateTestsDialogWindow.kt @@ -22,6 +22,7 @@ import com.intellij.openapi.roots.ModuleRootManager import com.intellij.openapi.roots.ModuleRootModificationUtil import com.intellij.openapi.roots.ModuleSourceOrderEntry import com.intellij.openapi.roots.ui.configuration.ClasspathEditor +import com.intellij.openapi.roots.ui.configuration.ComboBoxWithSeparators import com.intellij.openapi.roots.ui.configuration.ProjectStructureConfigurable import com.intellij.openapi.ui.ComboBox import com.intellij.openapi.ui.DialogPanel @@ -194,12 +195,12 @@ class GenerateTestsDialogWindow(val model: GenerateTestsModel) : DialogWrapper(m private val codegenLanguages = createComboBox(CodegenLanguage.values()) private val testFrameworks = createComboBox(TestFramework.allItems.toTypedArray()) - private val modelSpringConfigs = ( - listOf(NO_SPRING_CONFIGURATION_OPTION) + - model.getSortedSpringConfigurationClasses() + - model.getSpringXMLConfigurationFiles() - ).toTypedArray() - private val springConfig = createComboBox(modelSpringConfigs) + private val modelSpringConfigs = setOf( + null to listOf(NO_SPRING_CONFIGURATION_OPTION), + "Java-based configurations" to model.getSortedSpringConfigurationClasses(), + "XML-based configurations" to model.getSpringXMLConfigurationFiles() + ) + private val springConfig = createComboBoxWithSeparatorsForSpringConfigs(modelSpringConfigs) private val mockStrategies = createComboBox(MockStrategyApi.values()) private val staticsMocking = JCheckBox("Mock static methods") @@ -240,27 +241,27 @@ class GenerateTestsDialogWindow(val model: GenerateTestsModel) : DialogWrapper(m } } - private fun createComboBox(values: Array): ComboBox { - val comboBoxWidth = 300 - val maxComboBoxElementLength = 50 - return object : ComboBox(DefaultComboBoxModel(values), comboBoxWidth) {}.also { - it.renderer = object : DefaultListCellRenderer() { - override fun getListCellRendererComponent( - list: JList<*>?, - value: Any?, - index: Int, - isSelected: Boolean, - cellHasFocus: Boolean - ): Component { - val label = - super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus) - text = StringUtil.trimMiddle(value.toString(), maxComboBoxElementLength) - return label + private fun createComboBoxWithSeparatorsForSpringConfigs( + separatorToValues: Collection>>, + width: Int = 300 + ): ComboBoxWithSeparators { + val comboBox = object : ComboBoxWithSeparators() {}.apply { + fun wrapInEntryModel(value: T) = object : ComboBoxWithSeparators.EntryModel(value) { + override fun getPresentableText(): String = value.toString() + } + + setMinimumAndPreferredWidth(width) + separatorToValues.forEach { (separator, values) -> + if (values.isEmpty()) return@forEach + separator?.let { addItem(Separator(it.toString())) } + values.forEach { value -> + addItem(wrapInEntryModel(value)) } } } - } + return comboBox + } private fun createHelpLabel(commonTooltip: String? = null) = JBLabel(AllIcons.General.ContextHelp).apply { if (!commonTooltip.isNullOrEmpty()) toolTipText = commonTooltip @@ -341,7 +342,7 @@ class GenerateTestsDialogWindow(val model: GenerateTestsModel) : DialogWrapper(m "Otherwise, mock nothing. Mockito will be installed, if you don't have one.") ) }.enableIf(ComboBoxPredicate(springConfig) { - model.projectType != ProjectType.Spring || springConfig.item == NO_SPRING_CONFIGURATION_OPTION + model.projectType != ProjectType.Spring || springConfig.item.getItem() == NO_SPRING_CONFIGURATION_OPTION }) row { component(staticsMocking)} row { @@ -580,9 +581,9 @@ class GenerateTestsDialogWindow(val model: GenerateTestsModel) : DialogWrapper(m model.testSourceRoot?.apply { model.updateSourceRootHistory(this.toNioPath().toString()) } model.typeReplacementApproach = - when (springConfig.item) { + when (springConfig.item.getItem()) { NO_SPRING_CONFIGURATION_OPTION -> TypeReplacementApproach.DoNotReplace - else -> TypeReplacementApproach.ReplaceIfPossible(springConfig.item) + else -> TypeReplacementApproach.ReplaceIfPossible(springConfig.item.getItem().toString()) } val settings = model.project.service() @@ -1023,7 +1024,7 @@ class GenerateTestsDialogWindow(val model: GenerateTestsModel) : DialogWrapper(m } springConfig.addActionListener { _ -> - val isSpringConfigSelected = springConfig.item != NO_SPRING_CONFIGURATION_OPTION + val isSpringConfigSelected = springConfig.item.getItem() != NO_SPRING_CONFIGURATION_OPTION if (isSpringConfigSelected) { // Here mock strategy gains more meaning in Spring Projects. // We use OTHER_CLASSES strategy combined with type replacement being enabled. @@ -1114,10 +1115,6 @@ class GenerateTestsDialogWindow(val model: GenerateTestsModel) : DialogWrapper(m // We check for > 1 because there is already extra-dummy NO_SPRING_CONFIGURATION_OPTION option springConfig.isEnabled = model.projectType == ProjectType.Spring && modelSpringConfigs.size > 1 - - if (!springConfig.isEnabled) { - springConfig.item = NO_SPRING_CONFIGURATION_OPTION - } } private fun staticsMockingConfigured(): Boolean { diff --git a/utbot-ui-commons/src/main/kotlin/org/utbot/intellij/plugin/models/BaseTestModel.kt b/utbot-ui-commons/src/main/kotlin/org/utbot/intellij/plugin/models/BaseTestModel.kt index 9708eeb16c..6dcd85202a 100644 --- a/utbot-ui-commons/src/main/kotlin/org/utbot/intellij/plugin/models/BaseTestModel.kt +++ b/utbot-ui-commons/src/main/kotlin/org/utbot/intellij/plugin/models/BaseTestModel.kt @@ -90,7 +90,7 @@ open class BaseTestsModel( * - firstly, from test source roots (in the order provided by [getSortedTestRoots]) * - after that, from source roots */ - fun getSortedSpringConfigurationClasses(): List { + fun getSortedSpringConfigurationClasses(): Set { val testRootToIndex = getSortedTestRoots().withIndex().associate { (i, root) -> root.dir to i } // Not using `srcModule.testModules(project)` here because it returns @@ -116,11 +116,12 @@ open class BaseTestsModel( .searchPsiClasses(annotation, searchScope) .findAll() .sortedBy { testRootToIndex[it.containingFile.sourceRoot] ?: Int.MAX_VALUE } - }.mapNotNull { it.qualifiedName } + }.mapNotNullTo(mutableSetOf()) { it.qualifiedName } } - fun getSpringXMLConfigurationFiles(): List { - val resourcesPaths = srcModule.getResourcesPaths() + fun getSpringXMLConfigurationFiles(): Set { + val resourcesPaths = + setOf(testModule, srcModule).flatMapTo(mutableSetOf()) { it.getResourcesPaths() } val xmlFilePaths = resourcesPaths.flatMapTo(mutableListOf()) { path -> Files.list(path) .asSequence() @@ -128,7 +129,7 @@ open class BaseTestsModel( } val builder = DocumentBuilderFactory.newInstance().newDocumentBuilder() - return xmlFilePaths.mapNotNull { path -> + return xmlFilePaths.mapNotNullTo(mutableSetOf()) { path -> val doc = builder.parse(path.toFile()) val isBeanTagName = doc.documentElement.tagName == "beans"