Open bkahlert opened 3 years ago
An ugly as ugly can be workaround that works for my time being is
val (matchDir, buildDir) = when {
classFilePath.contains("${FS}out${FS}") -> "${FS}out${FS}" to "out${FS}test${FS}classes" // running inside IDEA
classFilePath.contains("build${FS}classes${FS}java") -> "build${FS}classes${FS}java" to "build${FS}classes${FS}java${FS}test" // gradle 4.x java source
classFilePath.contains("build${FS}classes${FS}kotlin") -> "build${FS}classes${FS}kotlin" to "build${FS}classes${FS}kotlin${FS}test" // gradle 4.x kotlin sources
classFilePath.contains("target${FS}classes") -> "target${FS}classes" to "target${FS}classes" // maven
else -> "build${FS}classes${FS}test" to "build${FS}classes${FS}test" // older gradle
}
val sourceFileCandidates: List<File> = this.sourceRoots
.map { sourceRoot ->
val replace = classFilePath.replace(buildDir, sourceRoot)
val sourceFileWithoutExtension =
replace
.plus(FS + className.replace(".", FS))
File(sourceFileWithoutExtension).parentFile
.resolve(callerStackTraceElement.fileName!!)
}.let {
val (baseDir, suffix) = classFilePath.split(matchDir).let {
val baseDir = it.first()
val suffixDir = it.last().withoutPrefix(FS).replace(FS, "-").convertKebabCaseToCamelCase()
baseDir to suffixDir
}
val sourceDir = baseDir.asPath().resolve("src").resolve(suffix).resolve("kotlin")
val sourceFileWithoutExtension = sourceDir.resolve(className.replace(".", FS))
it + sourceFileWithoutExtension.parent
.resolve(callerStackTraceElement.fileName!!).toFile()
}
Basically I compute a third default candidate that only removes the "contains" pattern from the class path and uses the sanitized right half of the split path (here: /jvm/test
→ jvm/test
) to heuristically map to jvmTest
which leads me to the right directory.
I just recognized there seems to be a problem with inlined functions as in this stack trace element:
koodies.io.path.LocationsTest$paths$1$invoke$$inlined$asA$1.invoke(Tests.kt:420)
FilePeek takes koodies/io/path/LocationsTest
as the sourceFileWithoutExtension
and replaces the whole file LocationsTest
with Tests.kt
. imho only the extension should be appended as the name already correctly states.
sorry i totally missed this issue, i was under the impression nobody uses filepeek. can you supply a test case for the problem with inlined functions?
Hey Christoph, first of all. Compliments! Your tiny little helper is amazing. Thanks to it I managed to implement some kind of JUnit-Strikt crossover where all descriptors / test names are optional:
Here's the problem: It doesn't work with Kotlin's MPP file layout but just be easily fixed as the code simply missed the right directory by level: namely
jvm
. In my setting (Kotlin 1.4.21 and Gradle 6.8) FilePeek starts to look atcom.bkahlert/koodies/build/classes/kotlin/jvm/test
FilePeek findsbuild/classes/kotlin
so it attempts to replacebuild/classes/kotlin/test
with relative source root candidates... which is doomed to fail because of the target dir level (jvm
,js
, etc). Consequently the replace does not take place and FilePeek continues to look in the unchangedcom.bkahlert/koodies/build/classes/kotlin/jvm/test
.There is nothing that can be done on the configuration side by what I can see. Providing source roots does not help because the when block
does to finish with a valid search pattern for the replacement.