fix code coverage test to match the new implementation logic

This commit is contained in:
Dmitry Jemerov
2015-01-14 12:12:27 +01:00
parent cb76c2a971
commit cc1a628110
6 changed files with 87 additions and 76 deletions
@@ -50,7 +50,7 @@ public class KotlinCoverageExtension(): JavaCoverageEngineExtension() {
override fun suggestQualifiedName(sourceFile: PsiFile, classes: Array<out PsiClass>, names: MutableSet<String>): Boolean {
if (sourceFile is JetFile) {
val qNames = collectGeneratedClassQualifiedNames(sourceFile)
val qNames = collectGeneratedClassQualifiedNames(findOutputRoot(sourceFile), sourceFile)
if (qNames != null) {
names.addAll(qNames)
return true
@@ -67,78 +67,10 @@ public class KotlinCoverageExtension(): JavaCoverageEngineExtension() {
}
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)
}
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
fun keepCoverageInfoForClassWithoutSource(bundle: CoverageSuitesBundle, classFile: File): Boolean {
// TODO check scope and source roots
@@ -177,10 +109,81 @@ public class KotlinCoverageExtension(): JavaCoverageEngineExtension() {
runReadAction {
val outputRoot = findOutputRoot(srcFile)
val existingClassFiles = getClassesGeneratedFromFile(outputRoot, srcFile)
existingClassFiles.mapTo(classFiles) { File(it.getPath())}
existingClassFiles.mapTo(classFiles) { File(it.getPath()) }
}
return true
}
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$bar$1
org.demo.coverage.Foo
org.demo.coverage.Foo$bar$1
@@ -2,6 +2,7 @@ package org.demo.coverage
public class Foo {
public fun forEach(fn: (Any?) -> Unit): Unit {
fn(1)
}
public fun bar() {
@@ -18,6 +18,11 @@ package org.jetbrains.kotlin.idea.coverage
import org.jetbrains.kotlin.idea.JetLightCodeInsightFixtureTestCase
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() {
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
public fun doTest(path: String) {
// val kotlinFile = myFixture.configureByFile(path) as JetFile
// val actualClasses = KotlinCoverageExtension.collectOutputClassNames(kotlinFile)
// JetTestUtils.assertEqualsToFile(File(path.replace(".kt", ".expected.txt")), actualClasses.join("\n"))
val kotlinFile = myFixture.configureByFile(path) as JetFile
val outputRoot = LocalFileSystem.getInstance().findFileByPath("$path.out")
assertNotNull(outputRoot)
val actualClasses = KotlinCoverageExtension.collectGeneratedClassQualifiedNames(outputRoot, kotlinFile)
JetTestUtils.assertEqualsToFile(File(path.replace(".kt", ".expected.txt")), actualClasses!!.join("\n"))
}
}