@@ -37,6 +37,11 @@ import org.jetbrains.kotlin.platform.TargetPlatformVersion
3737
3838private val logger = KotlinLogging .logger {}
3939
40+ data class TestSourceRoot (
41+ val dir : VirtualFile ,
42+ val expectedLanguage : CodegenLanguage
43+ )
44+
4045/* *
4146 * @return jdk version of the module
4247 */
@@ -60,12 +65,6 @@ fun Module.kotlinTargetPlatform(): TargetPlatformVersion {
6065 ?.singleOrNull() ? : error(" Can't determine target platform for module $this " )
6166}
6267
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-
6968/* *
7069 * Gets a path to test resources source root.
7170 *
@@ -121,8 +120,8 @@ private fun findPotentialModulesForTests(project: Project, srcModule: Module): L
121120/* *
122121 * Finds all suitable test root virtual files.
123122 */
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 }
126125
127126 if (sourceRootsInModule.isNotEmpty()) {
128127 return sourceRootsInModule
@@ -133,22 +132,30 @@ fun Module.suitableTestSourceRoots(codegenLanguage: CodegenLanguage): List<Virtu
133132 ModuleUtilCore .collectModulesDependsOn(this , dependentModules)
134133
135134 return dependentModules
136- .flatMap { it.suitableTestSourceFolders(codegenLanguage ) }
137- .mapNotNull { it.file }
135+ .flatMap { it.suitableTestSourceFolders() }
136+ .mapNotNull { it.testSourceRoot }
138137}
139138
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 > {
141149 val sourceFolders = ModuleRootManager .getInstance(this )
142150 .contentEntries
143151 .flatMap { it.sourceFolders.toList() }
144152 .filterNotNull()
145153
146154 return sourceFolders
147155 .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 }
151157}
158+
152159private val GRADLE_SYSTEM_ID = ProjectSystemId (" GRADLE" )
153160
154161val Project .isBuildWithGradle get() =
@@ -157,19 +164,20 @@ val Project.isBuildWithGradle get() =
157164 }
158165
159166private const val dedicatedTestSourceRootName = " utbot_tests"
160- fun Module.addDedicatedTestRoot (testSourceRoots : MutableList <VirtualFile >): VirtualFile ? {
167+
168+ fun Module.addDedicatedTestRoot (testSourceRoots : MutableList <TestSourceRoot >, language : CodegenLanguage ): VirtualFile ? {
161169 // Don't suggest new test source roots for Gradle project where 'unexpected' test roots won't work
162170 if (project.isBuildWithGradle) return null
163171 // 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
165173
166174 val moduleInstance = ModuleRootManager .getInstance(this )
167175 val testFolder = moduleInstance.contentEntries.flatMap { it.sourceFolders.toList() }
168176 .firstOrNull { it.rootType in testSourceRootTypes }
169177 (testFolder?.let { testFolder.file?.parent }
170178 ? : testFolder?.contentEntry?.file ? : this .guessModuleDir())?.let {
171179 val file = FakeVirtualFile (it, dedicatedTestSourceRootName)
172- testSourceRoots.add(file)
180+ testSourceRoots.add(TestSourceRoot ( file, language) )
173181 // We return "true" IFF it's case of not yet created fake directory
174182 return if (VfsUtil .findRelativeFile(it, dedicatedTestSourceRootName) == null ) file else null
175183 }
@@ -275,3 +283,20 @@ private fun jdkVersionBy(sdk: Sdk?): JavaSdkVersion {
275283 }
276284 return jdkVersion
277285}
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