[terminal] IJPL-191343 Make ShellCompletionTestFixture available for external plugins

It required moving `ShellCompletionTestFixture` and connected test services to the production sources.

GitOrigin-RevId: f5ebef9bf74841cc67c5aa98e65e68b6438378f7
This commit is contained in:
Konstantin Hudyakov
2025-08-01 15:12:44 +00:00
committed by intellij-monorepo-bot
parent 4d8bc34470
commit c6b1e3d95d
11 changed files with 52 additions and 34 deletions
@@ -1,5 +1,5 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.terminal.tests.block.util
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package org.jetbrains.plugins.terminal.testFramework.completion
import com.intellij.openapi.project.Project
import com.intellij.openapi.project.guessProjectDir
@@ -7,15 +7,22 @@ import com.intellij.terminal.completion.ShellCommandSpecCompletion
import com.intellij.terminal.completion.ShellDataGeneratorsExecutor
import com.intellij.terminal.completion.spec.*
import org.jetbrains.annotations.ApiStatus
import org.jetbrains.annotations.TestOnly
import org.jetbrains.plugins.terminal.block.completion.ShellCommandSpecsManagerImpl
import org.jetbrains.plugins.terminal.testFramework.completion.impl.TestCommandSpecsManager
import org.jetbrains.plugins.terminal.testFramework.completion.impl.TestGeneratorCommandsRunner
import org.jetbrains.plugins.terminal.testFramework.completion.impl.TestGeneratorsExecutor
import org.jetbrains.plugins.terminal.testFramework.completion.impl.TestRuntimeContextProvider
/**
* Fixture for testing shell command specification-based completion in a New Terminal.
*
* Can be used to test new [ShellCommandSpec]'s and ensure that completion items are relevant in the test cases.
* Allows mocking the shell current directory, shell name, and [ShellRuntimeDataGenerator] results.
* This fixture is not running the terminal session, mocking is used to provide the actual results for shell commands.
*/
@ApiStatus.Experimental
@TestOnly
class ShellCompletionTestFixture private constructor(
private val project: Project?,
private val curDirectory: String,
@@ -41,7 +48,7 @@ class ShellCompletionTestFixture private constructor(
val commandSpecsManager = if (commandSpecs != null) {
TestCommandSpecsManager(commandSpecs)
}
else ShellCommandSpecsManagerImpl.getInstance()
else ShellCommandSpecsManagerImpl.Companion.getInstance()
val completion = ShellCommandSpecCompletion(
commandSpecsManager,
@@ -54,6 +61,7 @@ class ShellCompletionTestFixture private constructor(
return completion.computeCompletionItems(command, arguments) ?: error("Not found command spec for command: $command")
}
@TestOnly
class Builder internal constructor(private val project: Project?) {
private var curDirectory: String = project?.guessProjectDir()?.path ?: ""
private var shellName: ShellName = ShellName("dummy")
@@ -112,7 +120,7 @@ class ShellCompletionTestFixture private constructor(
* By default, the generator is just executed for the provided [ShellRuntimeContext].
*/
fun mockDataGeneratorResults(
mock: suspend (context: ShellRuntimeContext, generator: ShellRuntimeDataGenerator<*>) -> Any
mock: suspend (context: ShellRuntimeContext, generator: ShellRuntimeDataGenerator<*>) -> Any,
): Builder {
generatorsExecutor = TestGeneratorsExecutor(mock)
return this
@@ -123,7 +131,8 @@ class ShellCompletionTestFixture private constructor(
}
}
@TestOnly
companion object {
fun builder(project: Project?): Builder = Builder(project)
}
}
}
@@ -1,10 +1,12 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.terminal.tests.block.util
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package org.jetbrains.plugins.terminal.testFramework.completion.impl
import com.intellij.terminal.completion.ShellCommandSpecsManager
import com.intellij.terminal.completion.spec.ShellCommandSpec
import org.jetbrains.annotations.ApiStatus
internal class TestCommandSpecsManager(vararg specs: ShellCommandSpec) : ShellCommandSpecsManager {
@ApiStatus.Internal
class TestCommandSpecsManager(vararg specs: ShellCommandSpec) : ShellCommandSpecsManager {
constructor(specs: List<ShellCommandSpec>) : this(*specs.toTypedArray())
private val specs: Map<String, ShellCommandSpec> = specs.associateBy { it.name }
@@ -16,4 +18,4 @@ internal class TestCommandSpecsManager(vararg specs: ShellCommandSpec) : ShellCo
override suspend fun getFullCommandSpec(spec: ShellCommandSpec): ShellCommandSpec {
return spec
}
}
}
@@ -1,13 +1,15 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.terminal.tests.block.util
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package org.jetbrains.plugins.terminal.testFramework.completion.impl
import com.intellij.terminal.completion.spec.ShellCommandExecutor
import com.intellij.terminal.completion.spec.ShellCommandResult
import org.jetbrains.annotations.ApiStatus
internal class TestGeneratorCommandsRunner {
@ApiStatus.Internal
class TestGeneratorCommandsRunner {
companion object {
val DUMMY: ShellCommandExecutor = ShellCommandExecutor {
ShellCommandResult.create("", 0)
ShellCommandResult.Companion.create("", 0)
}
}
}
@@ -1,16 +1,18 @@
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.terminal.tests.block.util
package org.jetbrains.plugins.terminal.testFramework.completion.impl
import com.intellij.terminal.completion.ShellDataGeneratorsExecutor
import com.intellij.terminal.completion.spec.ShellRuntimeContext
import com.intellij.terminal.completion.spec.ShellRuntimeDataGenerator
import org.jetbrains.annotations.ApiStatus
internal class TestGeneratorsExecutor(
private val mockGeneratorResult: suspend (context: ShellRuntimeContext, generator: ShellRuntimeDataGenerator<*>) -> Any = { context, generator -> generator.generate(context)!! }
@ApiStatus.Internal
class TestGeneratorsExecutor(
private val mockGeneratorResult: suspend (context: ShellRuntimeContext, generator: ShellRuntimeDataGenerator<*>) -> Any = { context, generator -> generator.generate(context)!! },
) : ShellDataGeneratorsExecutor {
override suspend fun <T : Any> execute(context: ShellRuntimeContext, generator: ShellRuntimeDataGenerator<T>): T {
val result = mockGeneratorResult(context, generator)
@Suppress("UNCHECKED_CAST") // Client should be responsible to match the result type with the generator return type.
return result as? T ?: error("Mocked result type is not the same as the generator result type. Generator: $generator, result: $result")
}
}
}
@@ -1,23 +1,25 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.terminal.tests.block.util
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package org.jetbrains.plugins.terminal.testFramework.completion.impl
import com.intellij.openapi.project.Project
import com.intellij.terminal.completion.ShellRuntimeContextProvider
import com.intellij.terminal.completion.spec.ShellCommandExecutor
import com.intellij.terminal.completion.spec.ShellName
import com.intellij.terminal.completion.spec.ShellRuntimeContext
import org.jetbrains.annotations.ApiStatus
import org.jetbrains.plugins.terminal.block.completion.spec.PROJECT_KEY
import org.jetbrains.plugins.terminal.block.completion.spec.impl.ShellRuntimeContextImpl
internal class TestRuntimeContextProvider(
@ApiStatus.Internal
class TestRuntimeContextProvider(
private val project: Project? = null,
private val directory: String = "",
private val shellName: ShellName = ShellName("dummy"),
private val generatorCommandsRunner: ShellCommandExecutor = TestGeneratorCommandsRunner.DUMMY
private val generatorCommandsRunner: ShellCommandExecutor = TestGeneratorCommandsRunner.DUMMY,
) : ShellRuntimeContextProvider {
override fun getContext(typedPrefix: String): ShellRuntimeContext {
return ShellRuntimeContextImpl(directory, typedPrefix, shellName, generatorCommandsRunner).also {
it.putUserData(PROJECT_KEY, project)
}
}
}
}
@@ -4,7 +4,6 @@ package com.intellij.terminal.tests.block
import com.intellij.terminal.completion.spec.ShellName
import com.intellij.terminal.completion.spec.ShellRuntimeContext
import com.intellij.terminal.tests.block.util.TestCommandSpecsProvider
import com.intellij.terminal.tests.block.util.TestGeneratorCommandsRunner
import com.intellij.terminal.tests.block.util.TestJsonCommandSpecsProvider
import com.intellij.testFramework.ExtensionTestUtil
import com.intellij.testFramework.fixtures.BasePlatformTestCase
@@ -16,6 +15,7 @@ import org.jetbrains.plugins.terminal.block.completion.spec.ShellCommandSpecInfo
import org.jetbrains.plugins.terminal.block.completion.spec.ShellCommandSpecsProvider
import org.jetbrains.plugins.terminal.block.completion.spec.impl.ShellMergedCommandSpec
import org.jetbrains.plugins.terminal.block.completion.spec.impl.ShellRuntimeContextImpl
import org.jetbrains.plugins.terminal.testFramework.completion.impl.TestGeneratorCommandsRunner
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
@@ -2,10 +2,10 @@
package com.intellij.terminal.tests.block.completion
import com.intellij.terminal.completion.spec.ShellCommandResult
import com.intellij.terminal.tests.block.util.ShellCompletionTestFixture
import com.intellij.testFramework.fixtures.BasePlatformTestCase
import kotlinx.coroutines.runBlocking
import org.jetbrains.plugins.terminal.block.session.ShellIntegrationFunctions.GET_DIRECTORY_FILES
import org.jetbrains.plugins.terminal.testFramework.completion.ShellCompletionTestFixture
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
@@ -5,13 +5,13 @@ import com.intellij.terminal.completion.ShellCommandSpecCompletion
import com.intellij.terminal.completion.spec.ShellCommandExecutor
import com.intellij.terminal.completion.spec.ShellCommandParserOptions
import com.intellij.terminal.completion.spec.ShellCommandResult
import com.intellij.terminal.tests.block.util.TestCommandSpecsManager
import com.intellij.terminal.tests.block.util.TestGeneratorsExecutor
import com.intellij.terminal.tests.block.util.TestRuntimeContextProvider
import com.intellij.testFramework.UsefulTestCase.assertSameElements
import kotlinx.coroutines.runBlocking
import org.jetbrains.plugins.terminal.block.completion.spec.ShellCommandSpec
import org.jetbrains.plugins.terminal.block.completion.spec.ShellDataGenerators.fileSuggestionsGenerator
import org.jetbrains.plugins.terminal.testFramework.completion.impl.TestCommandSpecsManager
import org.jetbrains.plugins.terminal.testFramework.completion.impl.TestGeneratorsExecutor
import org.jetbrains.plugins.terminal.testFramework.completion.impl.TestRuntimeContextProvider
import org.junit.Before
import org.junit.Test
import org.junit.jupiter.api.fail
@@ -6,15 +6,15 @@ import com.intellij.terminal.completion.ShellCommandTreeBuilderFixture
import com.intellij.terminal.completion.spec.ShellCommandExecutor
import com.intellij.terminal.completion.spec.ShellCommandParserOptions
import com.intellij.terminal.completion.spec.ShellCommandResult
import com.intellij.terminal.tests.block.util.TestCommandSpecsManager
import com.intellij.terminal.tests.block.util.TestGeneratorsExecutor
import com.intellij.terminal.tests.block.util.TestRuntimeContextProvider
import com.intellij.testFramework.common.timeoutRunBlocking
import kotlinx.coroutines.runBlocking
import org.jetbrains.plugins.terminal.block.completion.spec.ShellAliasSuggestion
import org.jetbrains.plugins.terminal.block.completion.spec.ShellCommandSpec
import org.jetbrains.plugins.terminal.block.completion.spec.ShellDataGenerators.fileSuggestionsGenerator
import org.jetbrains.plugins.terminal.block.session.ShellIntegrationFunctions.GET_DIRECTORY_FILES
import org.jetbrains.plugins.terminal.testFramework.completion.impl.TestCommandSpecsManager
import org.jetbrains.plugins.terminal.testFramework.completion.impl.TestGeneratorsExecutor
import org.jetbrains.plugins.terminal.testFramework.completion.impl.TestRuntimeContextProvider
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
@@ -3,12 +3,12 @@ package com.intellij.terminal.tests.block.completion
import com.intellij.terminal.completion.spec.ShellCommandResult
import com.intellij.terminal.completion.spec.ShellCompletionSuggestion
import com.intellij.terminal.tests.block.util.ShellCompletionTestFixture
import com.intellij.testFramework.UsefulTestCase.assertEmpty
import com.intellij.testFramework.UsefulTestCase.assertSameElements
import kotlinx.coroutines.runBlocking
import org.intellij.lang.annotations.Language
import org.jetbrains.plugins.terminal.block.completion.spec.specs.make.ShellMakeCommandSpec
import org.jetbrains.plugins.terminal.testFramework.completion.ShellCompletionTestFixture
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
@@ -1,11 +1,12 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.terminal.tests.block.util
import org.jetbrains.annotations.ApiStatus
import org.jetbrains.plugins.terminal.block.completion.spec.ShellCommandSpecInfo
import org.jetbrains.plugins.terminal.block.completion.spec.ShellCommandSpecsProvider
internal class TestCommandSpecsProvider(private vararg val specs: ShellCommandSpecInfo) : ShellCommandSpecsProvider {
@ApiStatus.Internal
class TestCommandSpecsProvider(private vararg val specs: ShellCommandSpecInfo) : ShellCommandSpecsProvider {
override fun getCommandSpecs(): List<ShellCommandSpecInfo> {
return specs.toList()
}
}
}