fix code coverage test to match the new implementation logic
This commit is contained in:
@@ -50,7 +50,7 @@ public class KotlinCoverageExtension(): JavaCoverageEngineExtension() {
|
|||||||
|
|
||||||
override fun suggestQualifiedName(sourceFile: PsiFile, classes: Array<out PsiClass>, names: MutableSet<String>): Boolean {
|
override fun suggestQualifiedName(sourceFile: PsiFile, classes: Array<out PsiClass>, names: MutableSet<String>): Boolean {
|
||||||
if (sourceFile is JetFile) {
|
if (sourceFile is JetFile) {
|
||||||
val qNames = collectGeneratedClassQualifiedNames(sourceFile)
|
val qNames = collectGeneratedClassQualifiedNames(findOutputRoot(sourceFile), sourceFile)
|
||||||
if (qNames != null) {
|
if (qNames != null) {
|
||||||
names.addAll(qNames)
|
names.addAll(qNames)
|
||||||
return true
|
return true
|
||||||
@@ -67,78 +67,10 @@ public class KotlinCoverageExtension(): JavaCoverageEngineExtension() {
|
|||||||
}
|
}
|
||||||
LOG.info("Retrieving coverage for " + element.getName())
|
LOG.info("Retrieving coverage for " + element.getName())
|
||||||
|
|
||||||
val qualifiedNames = collectGeneratedClassQualifiedNames(element)
|
val qualifiedNames = collectGeneratedClassQualifiedNames(findOutputRoot(element), element)
|
||||||
return if (qualifiedNames == null) null else totalCoverageForQualifiedNames(coverageAnnotator, qualifiedNames)
|
return if (qualifiedNames == null) null else totalCoverageForQualifiedNames(coverageAnnotator, qualifiedNames)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun collectGeneratedClassQualifiedNames(file: JetFile): List<String>? {
|
|
||||||
val outputRoot = findOutputRoot(file)
|
|
||||||
val existingClassFiles = getClassesGeneratedFromFile(outputRoot, file)
|
|
||||||
if (existingClassFiles.isEmpty()) {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
LOG.debug("Classfiles: [${existingClassFiles.map { it.getName() }.join()}]")
|
|
||||||
return existingClassFiles.map {
|
|
||||||
val relativePath = VfsUtilCore.getRelativePath(it, outputRoot)
|
|
||||||
StringUtil.trimEnd(relativePath, ".class").replace("/", ".")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getClassesGeneratedFromFile(outputRoot: VirtualFile?, file: JetFile): List<VirtualFile> {
|
|
||||||
val relativePath = file.getPackageFqName().asString().replace('.', '/')
|
|
||||||
val packageOutputDir = outputRoot?.findFileByRelativePath(relativePath)
|
|
||||||
if (packageOutputDir == null) return listOf()
|
|
||||||
|
|
||||||
val prefixes = collectClassFilePrefixes(file)
|
|
||||||
LOG.debug("Classfile prefixes: [${prefixes.join(", ")}]")
|
|
||||||
return packageOutputDir.getChildren().filter {
|
|
||||||
file -> prefixes.any {
|
|
||||||
(file.getName().startsWith(it + "$") && FileUtilRt.getExtension(file.getName()) == "class") ||
|
|
||||||
file.getName() == it + ".class"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun totalCoverageForQualifiedNames(coverageAnnotator: JavaCoverageAnnotator,
|
|
||||||
qualifiedNames: List<String>): PackageAnnotator.ClassCoverageInfo {
|
|
||||||
val result = PackageAnnotator.ClassCoverageInfo()
|
|
||||||
result.totalClassCount = 0
|
|
||||||
qualifiedNames.forEach {
|
|
||||||
val classInfo = coverageAnnotator.getClassCoverageInfo(it)
|
|
||||||
if (classInfo != null) {
|
|
||||||
result.totalClassCount += classInfo.totalClassCount
|
|
||||||
result.coveredClassCount += classInfo.coveredClassCount
|
|
||||||
result.totalMethodCount += classInfo.totalMethodCount
|
|
||||||
result.coveredMethodCount += classInfo.coveredMethodCount
|
|
||||||
result.totalLineCount += classInfo.totalLineCount
|
|
||||||
result.fullyCoveredLineCount += classInfo.fullyCoveredLineCount
|
|
||||||
result.partiallyCoveredLineCount += classInfo.partiallyCoveredLineCount
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
LOG.debug("Found no coverage for ${it}")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun findOutputRoot(file: JetFile): VirtualFile? {
|
|
||||||
val module = ModuleUtilCore.findModuleForPsiElement(file)
|
|
||||||
if (module == null) return null
|
|
||||||
val fileIndex = ProjectRootManager.getInstance(file.getProject()).getFileIndex()
|
|
||||||
val inTests = fileIndex.isInTestSourceContent(file.getVirtualFile())
|
|
||||||
val compilerOutputExtension = CompilerModuleExtension.getInstance(module)
|
|
||||||
return if (inTests)
|
|
||||||
compilerOutputExtension.getCompilerOutputPathForTests()
|
|
||||||
else
|
|
||||||
compilerOutputExtension.getCompilerOutputPath()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun collectClassFilePrefixes(file: JetFile): Collection<String> {
|
|
||||||
val result = file.getChildren().filter { it is JetClassOrObject }.map { (it as JetClassOrObject).getName() }
|
|
||||||
val packagePartFqName = PackagePartClassUtils.getPackagePartFqName(file)
|
|
||||||
return result.union(arrayListOf(packagePartFqName.shortName().asString()))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Implements API added in IDEA 14.1
|
// Implements API added in IDEA 14.1
|
||||||
fun keepCoverageInfoForClassWithoutSource(bundle: CoverageSuitesBundle, classFile: File): Boolean {
|
fun keepCoverageInfoForClassWithoutSource(bundle: CoverageSuitesBundle, classFile: File): Boolean {
|
||||||
// TODO check scope and source roots
|
// TODO check scope and source roots
|
||||||
@@ -177,10 +109,81 @@ public class KotlinCoverageExtension(): JavaCoverageEngineExtension() {
|
|||||||
runReadAction {
|
runReadAction {
|
||||||
val outputRoot = findOutputRoot(srcFile)
|
val outputRoot = findOutputRoot(srcFile)
|
||||||
val existingClassFiles = getClassesGeneratedFromFile(outputRoot, srcFile)
|
val existingClassFiles = getClassesGeneratedFromFile(outputRoot, srcFile)
|
||||||
existingClassFiles.mapTo(classFiles) { File(it.getPath())}
|
existingClassFiles.mapTo(classFiles) { File(it.getPath()) }
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class object {
|
||||||
|
private val LOG = Logger.getInstance(javaClass<KotlinCoverageExtension>())
|
||||||
|
|
||||||
|
fun collectGeneratedClassQualifiedNames(outputRoot: VirtualFile?, file: JetFile): List<String>? {
|
||||||
|
val existingClassFiles = getClassesGeneratedFromFile(outputRoot, file)
|
||||||
|
if (existingClassFiles.isEmpty()) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
LOG.debug("Classfiles: [${existingClassFiles.map { it.getName() }.join()}]")
|
||||||
|
return existingClassFiles.map {
|
||||||
|
val relativePath = VfsUtilCore.getRelativePath(it, outputRoot)
|
||||||
|
StringUtil.trimEnd(relativePath, ".class").replace("/", ".")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun totalCoverageForQualifiedNames(coverageAnnotator: JavaCoverageAnnotator,
|
||||||
|
qualifiedNames: List<String>): PackageAnnotator.ClassCoverageInfo {
|
||||||
|
val result = PackageAnnotator.ClassCoverageInfo()
|
||||||
|
result.totalClassCount = 0
|
||||||
|
qualifiedNames.forEach {
|
||||||
|
val classInfo = coverageAnnotator.getClassCoverageInfo(it)
|
||||||
|
if (classInfo != null) {
|
||||||
|
result.totalClassCount += classInfo.totalClassCount
|
||||||
|
result.coveredClassCount += classInfo.coveredClassCount
|
||||||
|
result.totalMethodCount += classInfo.totalMethodCount
|
||||||
|
result.coveredMethodCount += classInfo.coveredMethodCount
|
||||||
|
result.totalLineCount += classInfo.totalLineCount
|
||||||
|
result.fullyCoveredLineCount += classInfo.fullyCoveredLineCount
|
||||||
|
result.partiallyCoveredLineCount += classInfo.partiallyCoveredLineCount
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
LOG.debug("Found no coverage for ${it}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getClassesGeneratedFromFile(outputRoot: VirtualFile?, file: JetFile): List<VirtualFile> {
|
||||||
|
val relativePath = file.getPackageFqName().asString().replace('.', '/')
|
||||||
|
val packageOutputDir = outputRoot?.findFileByRelativePath(relativePath)
|
||||||
|
if (packageOutputDir == null) return listOf()
|
||||||
|
|
||||||
|
val prefixes = collectClassFilePrefixes(file)
|
||||||
|
LOG.debug("Classfile prefixes: [${prefixes.join(", ")}]")
|
||||||
|
return packageOutputDir.getChildren().filter {
|
||||||
|
file -> prefixes.any {
|
||||||
|
(file.getName().startsWith(it + "$") && FileUtilRt.getExtension(file.getName()) == "class") ||
|
||||||
|
file.getName() == it + ".class"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun findOutputRoot(file: JetFile): VirtualFile? {
|
||||||
|
val module = ModuleUtilCore.findModuleForPsiElement(file)
|
||||||
|
if (module == null) return null
|
||||||
|
val fileIndex = ProjectRootManager.getInstance(file.getProject()).getFileIndex()
|
||||||
|
val inTests = fileIndex.isInTestSourceContent(file.getVirtualFile())
|
||||||
|
val compilerOutputExtension = CompilerModuleExtension.getInstance(module)
|
||||||
|
return if (inTests)
|
||||||
|
compilerOutputExtension.getCompilerOutputPathForTests()
|
||||||
|
else
|
||||||
|
compilerOutputExtension.getCompilerOutputPath()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun collectClassFilePrefixes(file: JetFile): Collection<String> {
|
||||||
|
val result = file.getChildren().filter { it is JetClassOrObject }.map { (it as JetClassOrObject).getName() }
|
||||||
|
val packagePartFqName = PackagePartClassUtils.getPackagePartFqName(file)
|
||||||
|
return result.union(arrayListOf(packagePartFqName.shortName().asString()))
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
org/demo/coverage/Foo
|
org.demo.coverage.Foo
|
||||||
org/demo/coverage/Foo$bar$1
|
org.demo.coverage.Foo$bar$1
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package org.demo.coverage
|
|||||||
|
|
||||||
public class Foo {
|
public class Foo {
|
||||||
public fun forEach(fn: (Any?) -> Unit): Unit {
|
public fun forEach(fn: (Any?) -> Unit): Unit {
|
||||||
|
fn(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
public fun bar() {
|
public fun bar() {
|
||||||
|
|||||||
BIN
Binary file not shown.
BIN
Binary file not shown.
+10
-3
@@ -18,6 +18,11 @@ package org.jetbrains.kotlin.idea.coverage
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.idea.JetLightCodeInsightFixtureTestCase
|
import org.jetbrains.kotlin.idea.JetLightCodeInsightFixtureTestCase
|
||||||
import org.jetbrains.kotlin.idea.PluginTestCaseBase
|
import org.jetbrains.kotlin.idea.PluginTestCaseBase
|
||||||
|
import org.jetbrains.kotlin.psi.JetFile
|
||||||
|
import org.jetbrains.kotlin.test.JetTestUtils
|
||||||
|
import java.io.File
|
||||||
|
import com.intellij.openapi.vfs.LocalFileSystem
|
||||||
|
import kotlin.test.assertNotNull
|
||||||
|
|
||||||
public abstract class AbstractKotlinCoverageOutputFilesTest(): JetLightCodeInsightFixtureTestCase() {
|
public abstract class AbstractKotlinCoverageOutputFilesTest(): JetLightCodeInsightFixtureTestCase() {
|
||||||
private val TEST_DATA_PATH = PluginTestCaseBase.getTestDataPathBase() + "/coverage/outputFiles"
|
private val TEST_DATA_PATH = PluginTestCaseBase.getTestDataPathBase() + "/coverage/outputFiles"
|
||||||
@@ -25,8 +30,10 @@ public abstract class AbstractKotlinCoverageOutputFilesTest(): JetLightCodeInsig
|
|||||||
override fun getTestDataPath(): String? = TEST_DATA_PATH
|
override fun getTestDataPath(): String? = TEST_DATA_PATH
|
||||||
|
|
||||||
public fun doTest(path: String) {
|
public fun doTest(path: String) {
|
||||||
// val kotlinFile = myFixture.configureByFile(path) as JetFile
|
val kotlinFile = myFixture.configureByFile(path) as JetFile
|
||||||
// val actualClasses = KotlinCoverageExtension.collectOutputClassNames(kotlinFile)
|
val outputRoot = LocalFileSystem.getInstance().findFileByPath("$path.out")
|
||||||
// JetTestUtils.assertEqualsToFile(File(path.replace(".kt", ".expected.txt")), actualClasses.join("\n"))
|
assertNotNull(outputRoot)
|
||||||
|
val actualClasses = KotlinCoverageExtension.collectGeneratedClassQualifiedNames(outputRoot, kotlinFile)
|
||||||
|
JetTestUtils.assertEqualsToFile(File(path.replace(".kt", ".expected.txt")), actualClasses!!.join("\n"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user