Allow to assert rank value in ranking test

Update test data for lambdas.kt because of same rank check bug fixed.
This commit is contained in:
Nikolay Krasko
2018-10-24 18:09:45 +03:00
parent 122fba20da
commit 8d7829be31
5 changed files with 80 additions and 21 deletions
@@ -40,30 +40,20 @@ object FileRankingCalculatorForIde : FileRankingCalculator() {
override fun analyze(element: KtElement) = element.analyze(BodyResolveMode.PARTIAL) override fun analyze(element: KtElement) = element.analyze(BodyResolveMode.PARTIAL)
} }
abstract class FileRankingCalculator( abstract class FileRankingCalculator(private val checkClassFqName: Boolean = true) {
private val checkClassFqName: Boolean = true,
private val strictMode: Boolean = false
) {
abstract fun analyze(element: KtElement): BindingContext abstract fun analyze(element: KtElement): BindingContext
fun findMostAppropriateSource(files: Collection<KtFile>, location: Location): KtFile { fun findMostAppropriateSource(files: Collection<KtFile>, location: Location): KtFile {
assert(files.isNotEmpty()) val fileWithRankings: Map<KtFile, Int> = rankFiles(files, location)
val fileWithRankings = files.keysToMap { fileRankingSafe(it, location) }
val fileWithMaxScore = fileWithRankings.maxBy { it.value }!! val fileWithMaxScore = fileWithRankings.maxBy { it.value }!!
if (strictMode) {
require(fileWithMaxScore.value.value >= 0) { "Max score is negative" }
// Allow only one element with max ranking
require(fileWithRankings.count { it.value == fileWithMaxScore.value } == 1) {
"Score is the same for several files"
}
}
return fileWithMaxScore.key return fileWithMaxScore.key
} }
fun rankFiles(files: Collection<KtFile>, location: Location): Map<KtFile, Int> {
assert(files.isNotEmpty())
return files.keysToMap { fileRankingSafe(it, location).value }
}
private class Ranking(val value: Int) : Comparable<Ranking> { private class Ranking(val value: Int) : Comparable<Ranking> {
companion object { companion object {
val LOW = Ranking(-1000) val LOW = Ranking(-1000)
+22
View File
@@ -0,0 +1,22 @@
//FILE: a/a.kt
// DISABLE_STRICT_MODE
package a
abstract class R {
abstract fun run()
}
fun eval(r: R) {
r.run()
}
class Some {
fun foo() {
eval(object : R() { // Line with negative score
override fun run() {
val a = 1 // R: 4 L: 17
val b = 12 // R: 4 L: 18
}
})
}
}
+4 -2
View File
@@ -1,11 +1,12 @@
// DO_NOT_CHECK_CLASS_FQNAME // DO_NOT_CHECK_CLASS_FQNAME
// DISABLE_STRICT_MODE
//FILE: a/a.kt //FILE: a/a.kt
package a package a
fun block(l: () -> Unit) {} fun block(l: () -> Unit) {}
class A { class A { // Line with the same rank
fun a() { fun a() {
block { block {
val a = 5 val a = 5
@@ -18,12 +19,13 @@ class A {
//FILE: b/a.kt //FILE: b/a.kt
package b package b
// Fake Line
import a.block import a.block
class A { class A {
fun b() { fun b() {
val g = 5 val g = 5 // Line with the same rank
val x = 1 val x = 1
block { val y = 2 } block { val y = 2 }
block { block {
@@ -8,6 +8,7 @@ import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.psi.KtElement import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.org.objectweb.asm.tree.ClassNode import org.jetbrains.org.objectweb.asm.tree.ClassNode
import org.junit.Assert
abstract class AbstractFileRankingTest : LowLevelDebuggerTestBase() { abstract class AbstractFileRankingTest : LowLevelDebuggerTestBase() {
override fun doTest( override fun doTest(
@@ -23,7 +24,26 @@ abstract class AbstractFileRankingTest : LowLevelDebuggerTestBase() {
val doNotCheckClassFqName = "DO_NOT_CHECK_CLASS_FQNAME" in options val doNotCheckClassFqName = "DO_NOT_CHECK_CLASS_FQNAME" in options
val strictMode = "DISABLE_STRICT_MODE" !in options val strictMode = "DISABLE_STRICT_MODE" !in options
val calculator = object : FileRankingCalculator(checkClassFqName = !doNotCheckClassFqName, strictMode = strictMode) { val expectedRanks: Map<Pair<KtFile, Int>, Int> = allKtFiles.asSequence().flatMap { ktFile ->
ktFile.text.lines()
.asSequence()
.withIndex()
.map {
val matchResult = "^.*// (R: (-?\\d+)( L: (\\d+))?)\\s*$".toRegex().matchEntire(it.value) ?: return@map null
val rank = matchResult.groupValues[2].toInt()
val line = matchResult.groupValues.getOrNull(4)?.takeIf { !it.isEmpty() }?.toInt()
if (line != null && line != it.index + 1) {
throw IllegalArgumentException("Bad line in directive at ${ktFile.name}:${it.index + 1}\n${it.value}")
}
(ktFile to it.index + 1) to rank
}
.filterNotNull()
}.toMap()
val calculator = object : FileRankingCalculator(checkClassFqName = !doNotCheckClassFqName) {
override fun analyze(element: KtElement) = state.bindingContext override fun analyze(element: KtElement) = state.bindingContext
} }
@@ -60,7 +80,27 @@ abstract class AbstractFileRankingTest : LowLevelDebuggerTestBase() {
for (location in locations) { for (location in locations) {
if (location.method().isBridge || location.method().isSynthetic) continue if (location.method().isBridge || location.method().isSynthetic) continue
val actualFile = calculator.findMostAppropriateSource(allFilesWithSameName, location) val fileWithRankings: Map<KtFile, Int> = calculator.rankFiles(allFilesWithSameName, location)
for ((ktFile, rank) in fileWithRankings) {
val expectedRank = expectedRanks[ktFile to (location.lineNumber())]
if (expectedRank != null) {
Assert.assertEquals("Invalid expected rank at $location", expectedRank, rank)
}
}
val fileWithMaxScore = fileWithRankings.maxBy { it.value }!!
val actualFile = fileWithMaxScore.key
if (strictMode) {
require(fileWithMaxScore.value >= 0) { "Max score is negative at $location" }
// Allow only one element with max ranking
require(fileWithRankings.filter { it.value == fileWithMaxScore.value }.count() == 1) {
"Score is the same for several files at $location"
}
}
if (actualFile != expectedFile) { if (actualFile != expectedFile) {
problems += "Location ${location.sourceName()}:${location.lineNumber() - 1} is associated with a wrong KtFile:\n" + problems += "Location ${location.sourceName()}:${location.lineNumber() - 1} is associated with a wrong KtFile:\n" +
" - expected: ${expectedFile.virtualFilePath}\n" + " - expected: ${expectedFile.virtualFilePath}\n" +
@@ -29,6 +29,11 @@ public class FileRankingTestGenerated extends AbstractFileRankingTest {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/debugger/fileRanking"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true); KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/debugger/fileRanking"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true);
} }
@TestMetadata("anonymousClasses.kt")
public void testAnonymousClasses() throws Exception {
runTest("idea/testData/debugger/fileRanking/anonymousClasses.kt");
}
@TestMetadata("differentFlags.kt") @TestMetadata("differentFlags.kt")
public void testDifferentFlags() throws Exception { public void testDifferentFlags() throws Exception {
runTest("idea/testData/debugger/fileRanking/differentFlags.kt"); runTest("idea/testData/debugger/fileRanking/differentFlags.kt");