@@ -37,6 +37,11 @@ import org.jetbrains.kotlin.platform.TargetPlatformVersion
37
37
38
38
private val logger = KotlinLogging .logger {}
39
39
40
+ data class TestSourceRoot (
41
+ val dir : VirtualFile ,
42
+ val expectedLanguage : CodegenLanguage
43
+ )
44
+
40
45
/* *
41
46
* @return jdk version of the module
42
47
*/
@@ -60,12 +65,6 @@ fun Module.kotlinTargetPlatform(): TargetPlatformVersion {
60
65
?.singleOrNull() ? : error(" Can't determine target platform for module $this " )
61
66
}
62
67
63
- fun Module.suitableTestSourceRoots (): List <VirtualFile > =
64
- suitableTestSourceRoots(CodegenLanguage .JAVA ) + suitableTestSourceRoots(CodegenLanguage .KOTLIN )
65
-
66
- fun Module.suitableTestSourceFolders (): List <SourceFolder > =
67
- suitableTestSourceFolders(CodegenLanguage .JAVA ) + suitableTestSourceFolders(CodegenLanguage .KOTLIN )
68
-
69
68
/* *
70
69
* Gets a path to test resources source root.
71
70
*
@@ -121,8 +120,8 @@ private fun findPotentialModulesForTests(project: Project, srcModule: Module): L
121
120
/* *
122
121
* Finds all suitable test root virtual files.
123
122
*/
124
- fun Module.suitableTestSourceRoots (codegenLanguage : CodegenLanguage ): List <VirtualFile > {
125
- val sourceRootsInModule = suitableTestSourceFolders(codegenLanguage ).mapNotNull { it.file }
123
+ fun Module.suitableTestSourceRoots (): List <TestSourceRoot > {
124
+ val sourceRootsInModule = suitableTestSourceFolders().mapNotNull { it.testSourceRoot }
126
125
127
126
if (sourceRootsInModule.isNotEmpty()) {
128
127
return sourceRootsInModule
@@ -133,22 +132,30 @@ fun Module.suitableTestSourceRoots(codegenLanguage: CodegenLanguage): List<Virtu
133
132
ModuleUtilCore .collectModulesDependsOn(this , dependentModules)
134
133
135
134
return dependentModules
136
- .flatMap { it.suitableTestSourceFolders(codegenLanguage ) }
137
- .mapNotNull { it.file }
135
+ .flatMap { it.suitableTestSourceFolders() }
136
+ .mapNotNull { it.testSourceRoot }
138
137
}
139
138
140
- private fun Module.suitableTestSourceFolders (codegenLanguage : CodegenLanguage ): List <SourceFolder > {
139
+ private val SourceFolder .testSourceRoot: TestSourceRoot ?
140
+ get() {
141
+ val file = file
142
+ val expectedLanguage = expectedLanguageForTests
143
+ if (file != null && expectedLanguage != null )
144
+ return TestSourceRoot (file, expectedLanguage)
145
+ return null
146
+ }
147
+
148
+ private fun Module.suitableTestSourceFolders (): List <SourceFolder > {
141
149
val sourceFolders = ModuleRootManager .getInstance(this )
142
150
.contentEntries
143
151
.flatMap { it.sourceFolders.toList() }
144
152
.filterNotNull()
145
153
146
154
return sourceFolders
147
155
.filterNot { it.isForGeneratedSources() }
148
- .filter { it.rootType == codegenLanguage.testRootType() }
149
- // Heuristics: User is more likely to choose the shorter path
150
- .sortedBy { it.url.length }
156
+ .filter { it.isTestSource }
151
157
}
158
+
152
159
private val GRADLE_SYSTEM_ID = ProjectSystemId (" GRADLE" )
153
160
154
161
val Project .isBuildWithGradle get() =
@@ -157,19 +164,20 @@ val Project.isBuildWithGradle get() =
157
164
}
158
165
159
166
private const val dedicatedTestSourceRootName = " utbot_tests"
160
- fun Module.addDedicatedTestRoot (testSourceRoots : MutableList <VirtualFile >): VirtualFile ? {
167
+
168
+ fun Module.addDedicatedTestRoot (testSourceRoots : MutableList <TestSourceRoot >, language : CodegenLanguage ): VirtualFile ? {
161
169
// Don't suggest new test source roots for Gradle project where 'unexpected' test roots won't work
162
170
if (project.isBuildWithGradle) return null
163
171
// Dedicated test root already exists
164
- if (testSourceRoots.any { file -> file .name == dedicatedTestSourceRootName }) return null
172
+ if (testSourceRoots.any { root -> root.dir .name == dedicatedTestSourceRootName }) return null
165
173
166
174
val moduleInstance = ModuleRootManager .getInstance(this )
167
175
val testFolder = moduleInstance.contentEntries.flatMap { it.sourceFolders.toList() }
168
176
.firstOrNull { it.rootType in testSourceRootTypes }
169
177
(testFolder?.let { testFolder.file?.parent }
170
178
? : testFolder?.contentEntry?.file ? : this .guessModuleDir())?.let {
171
179
val file = FakeVirtualFile (it, dedicatedTestSourceRootName)
172
- testSourceRoots.add(file)
180
+ testSourceRoots.add(TestSourceRoot ( file, language) )
173
181
// We return "true" IFF it's case of not yet created fake directory
174
182
return if (VfsUtil .findRelativeFile(it, dedicatedTestSourceRootName) == null ) file else null
175
183
}
@@ -275,3 +283,20 @@ private fun jdkVersionBy(sdk: Sdk?): JavaSdkVersion {
275
283
}
276
284
return jdkVersion
277
285
}
286
+
287
+ private val SourceFolder .expectedLanguageForTests: CodegenLanguage ?
288
+ get() {
289
+ // unfortunately, Gradle creates Kotlin test source root with Java source root type, so type is misleading,
290
+ // and we should try looking for name first
291
+ if (file?.name == " kotlin" )
292
+ return CodegenLanguage .KOTLIN
293
+
294
+ if (file?.name == " java" )
295
+ return CodegenLanguage .JAVA
296
+
297
+ return when (rootType) {
298
+ CodegenLanguage .KOTLIN .testRootType() -> CodegenLanguage .KOTLIN
299
+ CodegenLanguage .JAVA .testRootType() -> CodegenLanguage .JAVA
300
+ else -> null
301
+ }
302
+ }
0 commit comments