Skip to content

Commit 15cb259

Browse files
authored
Support separators in SpringConfiguration ComboBox (#2090)
1 parent be95266 commit 15cb259

File tree

2 files changed

+34
-36
lines changed

2 files changed

+34
-36
lines changed

utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/ui/GenerateTestsDialogWindow.kt

Lines changed: 28 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import com.intellij.openapi.roots.ModuleRootManager
2222
import com.intellij.openapi.roots.ModuleRootModificationUtil
2323
import com.intellij.openapi.roots.ModuleSourceOrderEntry
2424
import com.intellij.openapi.roots.ui.configuration.ClasspathEditor
25+
import com.intellij.openapi.roots.ui.configuration.ComboBoxWithSeparators
2526
import com.intellij.openapi.roots.ui.configuration.ProjectStructureConfigurable
2627
import com.intellij.openapi.ui.ComboBox
2728
import com.intellij.openapi.ui.DialogPanel
@@ -194,12 +195,12 @@ class GenerateTestsDialogWindow(val model: GenerateTestsModel) : DialogWrapper(m
194195
private val codegenLanguages = createComboBox(CodegenLanguage.values())
195196
private val testFrameworks = createComboBox(TestFramework.allItems.toTypedArray())
196197

197-
private val modelSpringConfigs = (
198-
listOf(NO_SPRING_CONFIGURATION_OPTION) +
199-
model.getSortedSpringConfigurationClasses() +
200-
model.getSpringXMLConfigurationFiles()
201-
).toTypedArray()
202-
private val springConfig = createComboBox(modelSpringConfigs)
198+
private val modelSpringConfigs = setOf(
199+
null to listOf(NO_SPRING_CONFIGURATION_OPTION),
200+
"Java-based configurations" to model.getSortedSpringConfigurationClasses(),
201+
"XML-based configurations" to model.getSpringXMLConfigurationFiles()
202+
)
203+
private val springConfig = createComboBoxWithSeparatorsForSpringConfigs(modelSpringConfigs)
203204

204205
private val mockStrategies = createComboBox(MockStrategyApi.values())
205206
private val staticsMocking = JCheckBox("Mock static methods")
@@ -240,27 +241,27 @@ class GenerateTestsDialogWindow(val model: GenerateTestsModel) : DialogWrapper(m
240241
}
241242
}
242243

243-
private fun <T> createComboBox(values: Array<T>): ComboBox<T> {
244-
val comboBoxWidth = 300
245-
val maxComboBoxElementLength = 50
246-
return object : ComboBox<T>(DefaultComboBoxModel(values), comboBoxWidth) {}.also {
247-
it.renderer = object : DefaultListCellRenderer() {
248-
override fun getListCellRendererComponent(
249-
list: JList<*>?,
250-
value: Any?,
251-
index: Int,
252-
isSelected: Boolean,
253-
cellHasFocus: Boolean
254-
): Component {
255-
val label =
256-
super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus)
257-
text = StringUtil.trimMiddle(value.toString(), maxComboBoxElementLength)
258-
return label
244+
private fun <T> createComboBoxWithSeparatorsForSpringConfigs(
245+
separatorToValues: Collection<Pair<T?, Collection<T>>>,
246+
width: Int = 300
247+
): ComboBoxWithSeparators<T> {
248+
val comboBox = object : ComboBoxWithSeparators<T>() {}.apply {
249+
fun wrapInEntryModel(value: T) = object : ComboBoxWithSeparators<T>.EntryModel<T>(value) {
250+
override fun getPresentableText(): String = value.toString()
251+
}
252+
253+
setMinimumAndPreferredWidth(width)
254+
separatorToValues.forEach { (separator, values) ->
255+
if (values.isEmpty()) return@forEach
256+
separator?.let { addItem(Separator(it.toString())) }
257+
values.forEach { value ->
258+
addItem(wrapInEntryModel(value))
259259
}
260260
}
261261
}
262-
}
263262

263+
return comboBox
264+
}
264265

265266
private fun createHelpLabel(commonTooltip: String? = null) = JBLabel(AllIcons.General.ContextHelp).apply {
266267
if (!commonTooltip.isNullOrEmpty()) toolTipText = commonTooltip
@@ -341,7 +342,7 @@ class GenerateTestsDialogWindow(val model: GenerateTestsModel) : DialogWrapper(m
341342
"Otherwise, mock nothing. Mockito will be installed, if you don't have one.")
342343
)
343344
}.enableIf(ComboBoxPredicate(springConfig) {
344-
model.projectType != ProjectType.Spring || springConfig.item == NO_SPRING_CONFIGURATION_OPTION
345+
model.projectType != ProjectType.Spring || springConfig.item.getItem() == NO_SPRING_CONFIGURATION_OPTION
345346
})
346347
row { component(staticsMocking)}
347348
row {
@@ -580,9 +581,9 @@ class GenerateTestsDialogWindow(val model: GenerateTestsModel) : DialogWrapper(m
580581
model.testSourceRoot?.apply { model.updateSourceRootHistory(this.toNioPath().toString()) }
581582

582583
model.typeReplacementApproach =
583-
when (springConfig.item) {
584+
when (springConfig.item.getItem()) {
584585
NO_SPRING_CONFIGURATION_OPTION -> TypeReplacementApproach.DoNotReplace
585-
else -> TypeReplacementApproach.ReplaceIfPossible(springConfig.item)
586+
else -> TypeReplacementApproach.ReplaceIfPossible(springConfig.item.getItem().toString())
586587
}
587588

588589
val settings = model.project.service<Settings>()
@@ -1023,7 +1024,7 @@ class GenerateTestsDialogWindow(val model: GenerateTestsModel) : DialogWrapper(m
10231024
}
10241025

10251026
springConfig.addActionListener { _ ->
1026-
val isSpringConfigSelected = springConfig.item != NO_SPRING_CONFIGURATION_OPTION
1027+
val isSpringConfigSelected = springConfig.item.getItem() != NO_SPRING_CONFIGURATION_OPTION
10271028
if (isSpringConfigSelected) {
10281029
// Here mock strategy gains more meaning in Spring Projects.
10291030
// We use OTHER_CLASSES strategy combined with type replacement being enabled.
@@ -1114,10 +1115,6 @@ class GenerateTestsDialogWindow(val model: GenerateTestsModel) : DialogWrapper(m
11141115
// We check for > 1 because there is already extra-dummy NO_SPRING_CONFIGURATION_OPTION option
11151116
springConfig.isEnabled = model.projectType == ProjectType.Spring
11161117
&& modelSpringConfigs.size > 1
1117-
1118-
if (!springConfig.isEnabled) {
1119-
springConfig.item = NO_SPRING_CONFIGURATION_OPTION
1120-
}
11211118
}
11221119

11231120
private fun staticsMockingConfigured(): Boolean {

utbot-ui-commons/src/main/kotlin/org/utbot/intellij/plugin/models/BaseTestModel.kt

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ open class BaseTestsModel(
9090
* - firstly, from test source roots (in the order provided by [getSortedTestRoots])
9191
* - after that, from source roots
9292
*/
93-
fun getSortedSpringConfigurationClasses(): List<String> {
93+
fun getSortedSpringConfigurationClasses(): Set<String> {
9494
val testRootToIndex = getSortedTestRoots().withIndex().associate { (i, root) -> root.dir to i }
9595

9696
// Not using `srcModule.testModules(project)` here because it returns
@@ -116,19 +116,20 @@ open class BaseTestsModel(
116116
.searchPsiClasses(annotation, searchScope)
117117
.findAll()
118118
.sortedBy { testRootToIndex[it.containingFile.sourceRoot] ?: Int.MAX_VALUE }
119-
}.mapNotNull { it.qualifiedName }
119+
}.mapNotNullTo(mutableSetOf()) { it.qualifiedName }
120120
}
121121

122-
fun getSpringXMLConfigurationFiles(): List<String> {
123-
val resourcesPaths = srcModule.getResourcesPaths()
122+
fun getSpringXMLConfigurationFiles(): Set<String> {
123+
val resourcesPaths =
124+
setOf(testModule, srcModule).flatMapTo(mutableSetOf()) { it.getResourcesPaths() }
124125
val xmlFilePaths = resourcesPaths.flatMapTo(mutableListOf()) { path ->
125126
Files.list(path)
126127
.asSequence()
127128
.filter { it.fileExtension == ".xml" }
128129
}
129130

130131
val builder = DocumentBuilderFactory.newInstance().newDocumentBuilder()
131-
return xmlFilePaths.mapNotNull { path ->
132+
return xmlFilePaths.mapNotNullTo(mutableSetOf()) { path ->
132133
val doc = builder.parse(path.toFile())
133134

134135
val isBeanTagName = doc.documentElement.tagName == "beans"

0 commit comments

Comments
 (0)