@@ -8,22 +8,24 @@ import com.intellij.openapi.project.guessProjectDir
88import com.intellij.openapi.ui.ComboBox
99import com.intellij.openapi.ui.ComponentWithBrowseButton
1010import com.intellij.openapi.ui.FixedSizeButton
11+ import com.intellij.openapi.util.text.StringUtil
1112import com.intellij.openapi.vfs.VirtualFile
1213import com.intellij.openapi.vfs.newvfs.impl.FakeVirtualFile
1314import com.intellij.ui.ColoredListCellRenderer
1415import com.intellij.ui.SimpleTextAttributes
1516import com.intellij.util.ArrayUtil
1617import com.intellij.util.ui.UIUtil
1718import java.io.File
19+ import java.util.Comparator
1820import javax.swing.DefaultComboBoxModel
1921import javax.swing.JList
20- import org.jetbrains.kotlin.idea.util.projectStructure.allModules
22+ import org.jetbrains.kotlin.idea.util.rootManager
2123import org.utbot.common.PathUtil
24+ import org.utbot.intellij.plugin.generator.CodeGenerationController.getAllTestSourceRoots
2225import org.utbot.intellij.plugin.models.GenerateTestsModel
2326import org.utbot.intellij.plugin.ui.utils.TestSourceRoot
2427import org.utbot.intellij.plugin.ui.utils.addDedicatedTestRoot
2528import org.utbot.intellij.plugin.ui.utils.isBuildWithGradle
26- import org.utbot.intellij.plugin.ui.utils.suitableTestSourceRoots
2729
2830class TestFolderComboWithBrowseButton (private val model : GenerateTestsModel ) :
2931 ComponentWithBrowseButton <ComboBox <Any >>(ComboBox (), null ) {
@@ -57,20 +59,42 @@ class TestFolderComboWithBrowseButton(private val model: GenerateTestsModel) :
5759 }
5860 }
5961
60- val suggestedModules =
61- if (model.project.isBuildWithGradle) model.project.allModules() else model.potentialTestModules
62+ var commonModuleSourceDirectory = " "
63+ for ((i, sourceRoot) in model.srcModule.rootManager.sourceRoots.withIndex()) {
64+ commonModuleSourceDirectory = if (i == 0 ) {
65+ sourceRoot.toNioPath().toString()
66+ } else {
67+ StringUtil .commonPrefix(commonModuleSourceDirectory, sourceRoot.toNioPath().toString())
68+ }
69+ }
70+ // The first sorting to obtain the best candidate
71+ val testRoots = model.getAllTestSourceRoots().distinct().sortedWith(object : Comparator <TestSourceRoot > {
72+ override fun compare (o1 : TestSourceRoot , o2 : TestSourceRoot ): Int {
73+ // Heuristics: Dirs with language == codegenLanguage should go first
74+ val languageOrder = (o1.expectedLanguage == model.codegenLanguage).compareTo(o2.expectedLanguage == model.codegenLanguage)
75+ if (languageOrder != 0 ) return - languageOrder
76+ // Heuristics: move root that is 'closer' to module 'common' directory to the first position
77+ return - StringUtil .commonPrefixLength(commonModuleSourceDirectory, o1.dir.toNioPath().toString())
78+ .compareTo(StringUtil .commonPrefixLength(commonModuleSourceDirectory, o2.dir.toNioPath().toString()))
79+ }
80+ }).toMutableList()
81+
82+ val theBest = if (testRoots.isNotEmpty()) testRoots[0 ] else null
6283
63- val testRoots = suggestedModules.flatMap {
64- it.suitableTestSourceRoots()
65- }.sortedWith(
66- compareByDescending<TestSourceRoot > {
84+ // The second sorting to make full list ordered
85+ testRoots.sortWith(compareByDescending<TestSourceRoot > {
6786 // Heuristics: Dirs with language == codegenLanguage should go first
6887 it.expectedLanguage == model.codegenLanguage
6988 }.thenBy {
70- // Heuristics: User is more likely to choose the shorter path
71- it.dir.path.length
89+ // ABC-sorting
90+ it.dir.toNioPath()
7291 }
73- ).toMutableList()
92+ )
93+ // The best candidate should go first to be pre-selected
94+ theBest?.let {
95+ testRoots.remove(it)
96+ testRoots.add(0 , it)
97+ }
7498
7599 // this method is blocked for Gradle, where multiple test modules can exist
76100 model.testModule.addDedicatedTestRoot(testRoots, model.codegenLanguage)
0 commit comments