Skip to content

Commit 195999f

Browse files
UTBot doesn't show test source from other modules for Gradle project … (#1119)
Better source roots sorting
1 parent 9e2a1bd commit 195999f

File tree

3 files changed

+57
-25
lines changed

3 files changed

+57
-25
lines changed

utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/generator/CodeGenerationController.kt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import com.intellij.openapi.progress.ProgressIndicator
2222
import com.intellij.openapi.project.DumbService
2323
import com.intellij.openapi.project.Project
2424
import com.intellij.openapi.util.Computable
25+
import com.intellij.openapi.vfs.VirtualFile
2526
import com.intellij.openapi.wm.ToolWindowManager
2627
import com.intellij.psi.*
2728
import com.intellij.psi.codeStyle.CodeStyleManager
@@ -73,6 +74,9 @@ import java.nio.file.Path
7374
import java.util.concurrent.CancellationException
7475
import java.util.concurrent.CountDownLatch
7576
import java.util.concurrent.TimeUnit
77+
import org.jetbrains.kotlin.idea.util.projectStructure.allModules
78+
import org.utbot.intellij.plugin.ui.utils.TestSourceRoot
79+
import org.utbot.intellij.plugin.ui.utils.isBuildWithGradle
7680

7781
object CodeGenerationController {
7882
private val logger = KotlinLogging.logger {}
@@ -433,6 +437,12 @@ object CodeGenerationController {
433437
}
434438
}
435439

440+
fun GenerateTestsModel.getAllTestSourceRoots() : MutableList<TestSourceRoot> {
441+
with(if (project.isBuildWithGradle) project.allModules() else potentialTestModules) {
442+
return this.flatMap { it.suitableTestSourceRoots().toList() }.toMutableList()
443+
}
444+
}
445+
436446
private val CodegenLanguage.utilClassFileName: String
437447
get() = "$UT_UTILS_CLASS_NAME${this.extension}"
438448

utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/generator/UtTestsDialogProcessor.kt

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,7 @@ import org.utbot.intellij.plugin.process.EngineProcess
3838
import org.utbot.intellij.plugin.process.RdTestGenerationResult
3939
import org.utbot.intellij.plugin.settings.Settings
4040
import org.utbot.intellij.plugin.ui.GenerateTestsDialogWindow
41-
import org.utbot.intellij.plugin.ui.utils.isBuildWithGradle
4241
import org.utbot.intellij.plugin.ui.utils.showErrorDialogLater
43-
import org.utbot.intellij.plugin.ui.utils.suitableTestSourceRoots
4442
import org.utbot.intellij.plugin.ui.utils.testModules
4543
import org.utbot.intellij.plugin.util.*
4644
import org.utbot.rd.terminateOnException
@@ -49,6 +47,7 @@ import java.nio.file.Path
4947
import java.nio.file.Paths
5048
import java.util.concurrent.TimeUnit
5149
import kotlin.io.path.pathString
50+
import org.utbot.intellij.plugin.generator.CodeGenerationController.getAllTestSourceRoots
5251
import org.utbot.framework.plugin.api.util.LockFile
5352

5453
object UtTestsDialogProcessor {
@@ -97,7 +96,16 @@ object UtTestsDialogProcessor {
9796
// we want to start the child process in the same directory as the test runner
9897
WorkingDirService.workingDirProvider = PluginWorkingDirProvider(project)
9998

100-
if (project.isBuildWithGradle && testModules.flatMap { it.suitableTestSourceRoots() }.isEmpty()) {
99+
val model = GenerateTestsModel(
100+
project,
101+
srcModule,
102+
testModules,
103+
srcClasses,
104+
extractMembersFromSrcClasses,
105+
focusedMethods,
106+
UtSettings.utBotGenerationTimeoutInMillis,
107+
)
108+
if (model.getAllTestSourceRoots().isEmpty()) {
101109
val errorMessage = """
102110
<html>No test source roots found in the project.<br>
103111
Please, <a href="https://www.jetbrains.com/help/idea/testing.html#add-test-root">create or configure</a> at least one test source root.
@@ -106,17 +114,7 @@ object UtTestsDialogProcessor {
106114
return null
107115
}
108116

109-
return GenerateTestsDialogWindow(
110-
GenerateTestsModel(
111-
project,
112-
srcModule,
113-
testModules,
114-
srcClasses,
115-
extractMembersFromSrcClasses,
116-
focusedMethods,
117-
UtSettings.utBotGenerationTimeoutInMillis,
118-
)
119-
)
117+
return GenerateTestsDialogWindow(model)
120118
}
121119

122120
private fun createTests(project: Project, model: GenerateTestsModel) {

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

Lines changed: 35 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,22 +8,24 @@ import com.intellij.openapi.project.guessProjectDir
88
import com.intellij.openapi.ui.ComboBox
99
import com.intellij.openapi.ui.ComponentWithBrowseButton
1010
import com.intellij.openapi.ui.FixedSizeButton
11+
import com.intellij.openapi.util.text.StringUtil
1112
import com.intellij.openapi.vfs.VirtualFile
1213
import com.intellij.openapi.vfs.newvfs.impl.FakeVirtualFile
1314
import com.intellij.ui.ColoredListCellRenderer
1415
import com.intellij.ui.SimpleTextAttributes
1516
import com.intellij.util.ArrayUtil
1617
import com.intellij.util.ui.UIUtil
1718
import java.io.File
19+
import java.util.Comparator
1820
import javax.swing.DefaultComboBoxModel
1921
import javax.swing.JList
20-
import org.jetbrains.kotlin.idea.util.projectStructure.allModules
22+
import org.jetbrains.kotlin.idea.util.rootManager
2123
import org.utbot.common.PathUtil
24+
import org.utbot.intellij.plugin.generator.CodeGenerationController.getAllTestSourceRoots
2225
import org.utbot.intellij.plugin.models.GenerateTestsModel
2326
import org.utbot.intellij.plugin.ui.utils.TestSourceRoot
2427
import org.utbot.intellij.plugin.ui.utils.addDedicatedTestRoot
2528
import org.utbot.intellij.plugin.ui.utils.isBuildWithGradle
26-
import org.utbot.intellij.plugin.ui.utils.suitableTestSourceRoots
2729

2830
class 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

Comments
 (0)