[tests] Return caret names from ExpressionMarkerProvider

Render caret names in resolve testData, so that we don't have to guess
the indices of the carets;
it makes the multi-caret testData less error-prone.

Relevant for KT-65152 and KT-62695
This commit is contained in:
Roman Golyshev
2024-01-24 16:05:23 +01:00
committed by Space Team
parent 2befd2bffb
commit fb225f5f20
20 changed files with 128 additions and 114 deletions
@@ -48,7 +48,7 @@ abstract class AbstractDanglingFileReferenceResolveTest : AbstractReferenceResol
}
override fun doTestByMainFile(mainFile: KtFile, mainModule: TestModule, testServices: TestServices) {
val caretPositions = testServices.expressionMarkerProvider.getAllCaretsPositions(mainFile)
val caretPositions = testServices.expressionMarkerProvider.getAllCarets(mainFile)
val ktPsiFactory = KtPsiFactory.contextual(mainFile, markGenerated = true, eventSystemEnabled = true)
val fakeKtFile = ktPsiFactory.createFile("fake.kt", mainFile.text)
@@ -13,6 +13,7 @@ import org.jetbrains.kotlin.analysis.api.renderer.declarations.renderers.callabl
import org.jetbrains.kotlin.analysis.api.symbols.KtSymbol
import org.jetbrains.kotlin.analysis.test.framework.AnalysisApiTestDirectives
import org.jetbrains.kotlin.analysis.test.framework.base.AbstractAnalysisApiBasedTest
import org.jetbrains.kotlin.analysis.test.framework.services.CaretMarker
import org.jetbrains.kotlin.analysis.test.framework.services.expressionMarkerProvider
import org.jetbrains.kotlin.analysis.test.framework.utils.unwrapMultiReferences
import org.jetbrains.kotlin.idea.references.KtReference
@@ -46,19 +47,19 @@ abstract class AbstractReferenceResolveTest : AbstractAnalysisApiBasedTest() {
}
override fun doTestByMainFile(mainFile: KtFile, mainModule: TestModule, testServices: TestServices) {
val caretPositions = testServices.expressionMarkerProvider.getAllCaretsPositions(mainFile)
val caretPositions = testServices.expressionMarkerProvider.getAllCarets(mainFile)
doTestByFileStructure(mainFile, caretPositions, mainModule, testServices)
}
protected fun doTestByFileStructure(ktFile: KtFile, caretPositions: List<Int>, mainModule: TestModule, testServices: TestServices) {
if (caretPositions.isEmpty()) {
protected fun doTestByFileStructure(ktFile: KtFile, carets: List<CaretMarker>, mainModule: TestModule, testServices: TestServices) {
if (carets.isEmpty()) {
testServices.assertions.fail { "No carets were specified for resolve test" }
}
fun getRenderedReferencesForCaretPosition(caretPosition: Int): String {
val ktReferences = findReferencesAtCaret(ktFile, caretPosition)
fun getRenderedReferencesForCaretPosition(caret: CaretMarker): String {
val ktReferences = findReferencesAtCaret(ktFile, caret.offset)
if (ktReferences.isEmpty()) {
testServices.assertions.fail { "No references at caret position $caretPosition found" }
testServices.assertions.fail { "No references at caret $caret found" }
}
val resolvedTo = analyzeReferenceElement(ktReferences.first().element, mainModule) {
@@ -70,18 +71,16 @@ abstract class AbstractReferenceResolveTest : AbstractAnalysisApiBasedTest() {
return resolvedTo
}
val resolutionAtPositions = caretPositions.map { getRenderedReferencesForCaretPosition(it) }
val resolutionAtPositions = carets.map { it to getRenderedReferencesForCaretPosition(it) }
val actual = if (resolutionAtPositions.size == 1) {
val singleResolutionResult = resolutionAtPositions.single()
val (_, singleResolutionResult) = resolutionAtPositions.single()
"Resolved to:\n$singleResolutionResult"
} else {
resolutionAtPositions
.withIndex()
.joinToString(separator = "\n\n") { (idx, resolutionResult) ->
"Caret ${idx + 1} resolved to:\n$resolutionResult"
}
resolutionAtPositions.joinToString(separator = "\n\n") { (caret, resolutionResult) ->
"${caret.fullTag} resolved to:\n$resolutionResult"
}
}
testServices.assertions.assertEqualsToTestDataFileSibling(actual)
@@ -1,26 +1,26 @@
Caret 1 resolved to:
<caret_1> resolved to:
0: (in A) var something: kotlin.Int
Caret 2 resolved to:
<caret_2> resolved to:
0: (in A) var something: kotlin.Int
Caret 3 resolved to:
<caret_3> resolved to:
0: (in A) var something: kotlin.Int
Caret 4 resolved to:
<caret_4> resolved to:
0: (in A) var something: kotlin.Int
Caret 5 resolved to:
<caret_5> resolved to:
0: (in A) var something: kotlin.Int
Caret 6 resolved to:
<caret_6> resolved to:
0: (in A) var something: kotlin.Int
Caret 7 resolved to:
<caret_7> resolved to:
0: (in A) var something: kotlin.Int
Caret 8 resolved to:
<caret_8> resolved to:
0: (in A) var something: kotlin.Int
Caret 9 resolved to:
<caret_9> resolved to:
0: (in A) var something: kotlin.Int
@@ -1,31 +1,31 @@
Caret 1 resolved to:
<caret_1> resolved to:
0: (in A) var something: kotlin.Int
Caret 2 resolved to:
<caret_2> resolved to:
0: (in A) var something: kotlin.Int
Caret 3 resolved to:
<caret_3> resolved to:
0: (in A) var something: kotlin.Int
1: (in A) var something: kotlin.Int
Caret 4 resolved to:
<caret_4> resolved to:
0: (in A) var something: kotlin.Int
1: (in A) var something: kotlin.Int
Caret 5 resolved to:
<caret_5> resolved to:
0: (in A) var something: kotlin.Int
1: (in A) var something: kotlin.Int
Caret 6 resolved to:
<caret_6> resolved to:
0: (in A) var something: kotlin.Int
1: (in A) var something: kotlin.Int
Caret 7 resolved to:
<caret_7> resolved to:
0: (in A) var something: kotlin.Int
1: (in A) var something: kotlin.Int
Caret 8 resolved to:
<caret_8> resolved to:
0: (in A) var something: kotlin.Int
Caret 9 resolved to:
<caret_9> resolved to:
0: (in A) var something: kotlin.Int
@@ -1,15 +1,15 @@
Caret 1 resolved to:
<caret_1> resolved to:
0: (in test) fun test.Foo.ext()
1: (in test) val test.Foo.ext: kotlin.Int
Caret 2 resolved to:
<caret_2> resolved to:
0: (in test) fun test.Foo.ext()
1: (in test) val test.Foo.ext: kotlin.Int
Caret 3 resolved to:
<caret_3> resolved to:
0: (in test) fun test.Foo.ext()
1: (in test) val test.Foo.ext: kotlin.Int
Caret 4 resolved to:
<caret_4> resolved to:
0: (in test) fun test.Foo.ext()
1: (in test) val test.Foo.ext: kotlin.Int
@@ -1,5 +1,5 @@
Caret 1 resolved to:
<caret_1> resolved to:
0: (in test.Base) fun test.Receiver.ext()
Caret 2 resolved to:
<caret_2> resolved to:
0: (in test.Base) fun test.Receiver.ext()
@@ -1,16 +1,16 @@
Caret 1 resolved to:
<caret_1> resolved to:
0: (in test) fun kotlin.Any.function()
1: (in test) fun test.Base.function(i: kotlin.Int)
Caret 2 resolved to:
<caret_2> resolved to:
0: (in test) fun kotlin.Any.function()
1: (in test) fun test.Base.function(i: kotlin.Int)
Caret 3 resolved to:
<caret_3> resolved to:
0: (in test) fun kotlin.Any.function()
1: (in test) fun test.Base.function(i: kotlin.Int)
2: (in test.Base) fun function()
Caret 4 resolved to:
<caret_4> resolved to:
0: (in test) fun kotlin.Any.function()
1: (in test) fun test.Base.function(i: kotlin.Int)
@@ -1,11 +1,11 @@
Caret 1 resolved to:
<caret_1> resolved to:
Nothing (Unresolved reference)
Caret 2 resolved to:
<caret_2> resolved to:
Nothing (Unresolved reference)
Caret 3 resolved to:
<caret_3> resolved to:
Nothing (Unresolved reference)
Caret 4 resolved to:
<caret_4> resolved to:
Nothing (Unresolved reference)
@@ -1,26 +1,26 @@
Caret 1 resolved to:
<caret_1> resolved to:
0: (in test) fun <T> T.anyExt()
Caret 2 resolved to:
<caret_2> resolved to:
0: (in test) fun <T> T.anyExt()
Caret 3 resolved to:
<caret_3> resolved to:
0: (in test) fun <T> T.anyExt()
Caret 4 resolved to:
<caret_4> resolved to:
Nothing (Unresolved reference)
Caret 5 resolved to:
<caret_5> resolved to:
0: (in test) fun <T : test.Base> T.baseExt()
Caret 6 resolved to:
<caret_6> resolved to:
0: (in test) fun <T : test.Base> T.baseExt()
Caret 7 resolved to:
<caret_7> resolved to:
Nothing (Unresolved reference)
Caret 8 resolved to:
<caret_8> resolved to:
Nothing (Unresolved reference)
Caret 9 resolved to:
<caret_9> resolved to:
0: (in test) fun <T : test.Child> T.childExt()
@@ -1,5 +1,5 @@
Caret 1 resolved to:
<caret_1> resolved to:
0: (in test) fun test.WithGenerics<kotlin.Int>.intExt()
Caret 2 resolved to:
<caret_2> resolved to:
0: (in test) fun test.WithGenerics<kotlin.String>.stringExt()
@@ -1,11 +1,11 @@
Caret 1 resolved to:
<caret_1> resolved to:
Nothing (Unresolved reference)
Caret 2 resolved to:
<caret_2> resolved to:
Nothing (Unresolved reference)
Caret 3 resolved to:
<caret_3> resolved to:
Nothing (Unresolved reference)
Caret 4 resolved to:
Nothing (Unresolved reference)
<caret_4> resolved to:
Nothing (Unresolved reference)
@@ -1,17 +1,17 @@
Caret 1 resolved to:
<caret_1> resolved to:
0: package one
Caret 2 resolved to:
<caret_2> resolved to:
0: package one.two
Caret 3 resolved to:
<caret_3> resolved to:
0: (in one.two) class Foo
Caret 4 resolved to:
<caret_4> resolved to:
0: (in one.two) class Foo
Caret 5 resolved to:
<caret_5> resolved to:
0: package one
Caret 6 resolved to:
0: package one.two
<caret_6> resolved to:
0: package one.two
@@ -1,11 +1,11 @@
Caret 1 resolved to:
<caret_1> resolved to:
0: (in test) fun test.Foo.extFun()
Caret 2 resolved to:
<caret_2> resolved to:
0: (in test) fun test.Foo.extFun()
Caret 3 resolved to:
<caret_3> resolved to:
0: (in test) fun test.Foo.extFun()
Caret 4 resolved to:
<caret_4> resolved to:
0: (in test) fun test.Foo.extFun()
@@ -1,11 +1,11 @@
Caret 1 resolved to:
<caret_1> resolved to:
0: (in test) val test.Foo.extProp: kotlin.Int
Caret 2 resolved to:
<caret_2> resolved to:
0: (in test) val test.Foo.extProp: kotlin.Int
Caret 3 resolved to:
<caret_3> resolved to:
0: (in test) val test.Foo.extProp: kotlin.Int
Caret 4 resolved to:
<caret_4> resolved to:
0: (in test) val test.Foo.extProp: kotlin.Int
@@ -1,8 +1,8 @@
Caret 1 resolved to:
<caret_1> resolved to:
Nothing (Unresolved reference)
Caret 2 resolved to:
<caret_2> resolved to:
0: (in test.WithMember) fun Foo()
Caret 3 resolved to:
0: (in test.WithMember) fun Foo()
<caret_3> resolved to:
0: (in test.WithMember) fun Foo()
@@ -1,14 +1,14 @@
Caret 1 resolved to:
<caret_1> resolved to:
0: (in test) fun test.Foo.fooExt()
Caret 2 resolved to:
<caret_2> resolved to:
0: (in test) fun test.FooAlias.fooAliasExt()
Caret 3 resolved to:
<caret_3> resolved to:
0: (in test) fun test.FooAlias.fooAliasExt()
Caret 4 resolved to:
<caret_4> resolved to:
0: (in test) fun kotlin.Any.anyExt()
Caret 5 resolved to:
<caret_5> resolved to:
Nothing (Unresolved reference)
@@ -1,26 +1,26 @@
Caret 1 resolved to:
<caret_1> resolved to:
0: (in test) fun kotlin.Any.anyExt()
Caret 2 resolved to:
<caret_2> resolved to:
0: (in test) fun kotlin.Any.anyExt()
Caret 3 resolved to:
<caret_3> resolved to:
0: (in test) fun kotlin.Any.anyExt()
Caret 4 resolved to:
<caret_4> resolved to:
Nothing (Unresolved reference)
Caret 5 resolved to:
<caret_5> resolved to:
0: (in test) fun test.Base.baseExt()
Caret 6 resolved to:
<caret_6> resolved to:
0: (in test) fun test.Base.baseExt()
Caret 7 resolved to:
<caret_7> resolved to:
Nothing (Unresolved reference)
Caret 8 resolved to:
<caret_8> resolved to:
Nothing (Unresolved reference)
Caret 9 resolved to:
<caret_9> resolved to:
0: (in test) fun test.Child.childExt()
@@ -1,26 +1,26 @@
Caret 1 resolved to:
<caret_1> resolved to:
0: package one
Caret 2 resolved to:
<caret_2> resolved to:
0: package one
Caret 3 resolved to:
<caret_3> resolved to:
0: package one.two
Caret 4 resolved to:
<caret_4> resolved to:
0: package one
Caret 5 resolved to:
<caret_5> resolved to:
0: package one.two
Caret 6 resolved to:
<caret_6> resolved to:
0: package one.two.three
Caret 7 resolved to:
<caret_7> resolved to:
0: package one
Caret 8 resolved to:
<caret_8> resolved to:
0: package one.two
Caret 9 resolved to:
<caret_9> resolved to:
0: package one.two.three
@@ -1,11 +1,11 @@
Caret 1 resolved to:
<caret_1> resolved to:
0: (in foo) fun foo()
1: (in foo) interface foo
2: package foo
Caret 2 resolved to:
<caret_2> resolved to:
0: package foo
Caret 3 resolved to:
<caret_3> resolved to:
0: (in foo) fun foo()
1: (in foo) interface foo
1: (in foo) interface foo
@@ -99,8 +99,8 @@ class ExpressionMarkerProvider : TestService {
}
}
fun getAllCaretsPositions(file: PsiFile): List<Int> {
return carets.getAllCaretsOffsets(file.name)
fun getAllCarets(file: PsiFile): List<CaretMarker> {
return carets.getAllCarets(file.name)
}
fun getSelectedRangeOrNull(file: PsiFile): TextRange? = selected[file.name]
@@ -261,6 +261,21 @@ class ExpressionMarkerProvider : TestService {
}
}
data class CaretMarker(val tag: String, val offset: Int) {
/**
* Full render of this caret marker in the `<caret>` or `<caret_$tag>` form.
*
* @see ExpressionMarkersSourceFilePreprocessor.TAGS.CARET_REGEXP
*/
val fullTag: String
get() = if (tag.isEmpty()) {
"<caret>"
} else {
"<caret_${tag}>"
}
}
private class CaretProvider {
private val caretToFile = mutableMapOf<String, CaretsInFile>()
@@ -269,8 +284,8 @@ private class CaretProvider {
return cartsInFile.getCaretOffsetByTag(caretTag)
}
fun getAllCaretsOffsets(filename: String): List<Int> {
return caretToFile[filename]?.getAllCaretsOffsets().orEmpty()
fun getAllCarets(filename: String): List<CaretMarker> {
return caretToFile[filename]?.getAllCarets().orEmpty()
}
fun addCaret(filename: String, caretTag: String?, caretOffset: Int) {
@@ -285,8 +300,8 @@ private class CaretProvider {
return carets[tag.orEmpty()]
}
fun getAllCaretsOffsets(): List<Int> {
return carets.values.toList()
fun getAllCarets(): List<CaretMarker> {
return carets.map { (tag, offset) -> CaretMarker(tag, offset) }
}
fun addCaret(caretTag: String?, caretOffset: Int) {