[inline-completion] ML-1632: add some tests to the platform

GitOrigin-RevId: d94f8fe8e0c7d10234e9ad727e1f9c1d9932c464
This commit is contained in:
Kirill.Karnaukhov
2023-10-24 19:23:54 +02:00
committed by intellij-monorepo-bot
parent 9771189e07
commit 2e09640133
4 changed files with 124 additions and 1 deletions

View File

@@ -245,7 +245,7 @@ class InlineCompletionHandler(
private fun getProvider(event: InlineCompletionEvent): InlineCompletionProvider? {
if (application.isUnitTestMode && testProvider != null) {
return testProvider
return testProvider?.takeIf { it.isEnabled(event) }
}
return InlineCompletionProvider.extensions().firstOrNull {
@@ -335,6 +335,12 @@ class InlineCompletionHandler(
testProvider = provider
}
@TestOnly
fun registerTestHandler(provider: InlineCompletionProvider, disposable: Disposable) {
registerTestHandler(provider)
disposable.whenDisposed { unRegisterTestHandler() }
}
@TestOnly
fun unRegisterTestHandler() {
testProvider = null

View File

@@ -54,6 +54,15 @@ class InlineCompletionContext internal constructor(val editor: Editor, val langu
isDisposed = true
}
override fun toString(): String {
return if (!isDisposed) {
"InlineCompletionContext(disposed=false, textToInsert=${textToInsert()})"
}
else {
"InlineCompletionContext(disposed=true)"
}
}
private inline fun <T> assureNotDisposed(block: () -> T): T {
check(!isDisposed) { "Context is disposed. Cannot access elements." }
return block()

View File

@@ -0,0 +1,100 @@
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.codeInsight.inline.completion
import com.intellij.codeInsight.inline.completion.elements.InlineCompletionElement
import com.intellij.codeInsight.inline.completion.elements.InlineCompletionGrayTextElement
import com.intellij.codeInsight.inline.completion.elements.InlineCompletionSkipTextElement
import com.intellij.openapi.fileTypes.PlainTextFileType
import com.intellij.testFramework.fixtures.BasePlatformTestCase
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
@RunWith(JUnit4::class)
internal class SimpleInlineCompletionTest : BasePlatformTestCase() {
private fun registerSuggestion(vararg suggestion: InlineCompletionElement) {
InlineCompletionHandler.registerTestHandler(SimpleInlineCompletionProvider(suggestion.toList()), testRootDisposable)
}
// !!! VERY IMPORTANT !!!
override fun runInDispatchThread(): Boolean {
return false
}
@Test
fun `test inline completion renders on typings`() = myFixture.testInlineCompletion {
init(PlainTextFileType.INSTANCE, "fu<caret>")
registerSuggestion(InlineCompletionGrayTextElement(" main(args: List<String>) { }"))
typeChar('n') // Type a symbol into the editor
delay() // Waiting for request to inline completion to finish
assertInlineRender(" main(args: List<String>) { }") // Checking what is shown with inlays
insert()
assertFileContent("fun main(args: List<String>) { }<caret>")
assertInlineHidden()
}
@Test
fun `test inline completion does not render on direct action call`() = myFixture.testInlineCompletion {
init(PlainTextFileType.INSTANCE, "")
registerSuggestion(InlineCompletionGrayTextElement("This is tutorial"))
callInlineCompletion() // Direct action call
delay()
assertInlineHidden()
}
@Test
fun `test inline completion renders skip elements`() = myFixture.testInlineCompletion {
init(PlainTextFileType.INSTANCE, "<caret>)")
registerSuggestion(
InlineCompletionGrayTextElement("1"),
InlineCompletionSkipTextElement(")"),
InlineCompletionGrayTextElement(" + (2)")
)
typeChar('(')
assertFileContent("(<caret>)")
delay()
assertInlineElements {
gray("1")
skip(")")
gray(" + (2)")
}
insert()
assertFileContent("(1) + (2)<caret>")
assertInlineHidden()
}
@Test
fun `test inline completion simple over typing`() = myFixture.testInlineCompletion {
init(PlainTextFileType.INSTANCE, "<caret>")
registerSuggestion(InlineCompletionGrayTextElement("his is tutorial"))
typeChar('T')
delay()
assertInlineRender("his is tutorial")
typeChar('h') // No 'delay' as this update is called instantly
assertInlineRender("is is tutorial")
typeChar('i')
assertInlineRender("s is tutorial")
assertFileContent("Thi<caret>")
insert()
assertFileContent("This is tutorial<caret>")
assertInlineHidden()
}
private class SimpleInlineCompletionProvider(val suggestion: List<InlineCompletionElement>) : InlineCompletionProvider {
override val id: InlineCompletionProviderID = InlineCompletionProviderID("SimpleInlineCompletionProvider")
override suspend fun getSuggestion(request: InlineCompletionRequest): InlineCompletionSuggestion {
return InlineCompletionSuggestion.withFlow {
suggestion.forEach { emit(it) }
}
}
override fun isEnabled(event: InlineCompletionEvent): Boolean {
return event is InlineCompletionEvent.DocumentChange
}
}
}

View File

@@ -343,6 +343,14 @@ class InlineCompletionLifecycleTestDSL(val fixture: CodeInsightTestFixture) {
}
}
/**
* This is **Experimental API**.
*
* If you use this DSL to write a test in JUnit3 or JUnit4 test classes, **please set `runInDispatchThread` to `false`**, otherwise, you'll
* get a deadlock.
*
* Example: [com.intellij.codeInsight.inline.completion.SimpleInlineCompletionTest]
*/
@ApiStatus.Experimental
fun CodeInsightTestFixture.testInlineCompletion(
timeout: Duration = DEFAULT_TEST_TIMEOUT,