Skip to content

Commit

Permalink
feat(provider): add templated test prompts
Browse files Browse the repository at this point in the history
This commit adds a new feature to the provider module. It introduces a `TemplatedTestPrompt` class that allows users to lookup template files for test prompts. The class is responsible for retrieving the template code from the specified file and returning it as a string. This feature enhances the functionality of the provider module by providing users with pre-defined templates for test prompts, making it easier to write test cases.
  • Loading branch information
phodal committed Jan 12, 2024
1 parent d7e0833 commit 94d588a
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 8 deletions.
@@ -1,12 +1,14 @@
package cc.unitmesh.idea.provider

import cc.unitmesh.devti.custom.test.TemplatedTestPrompt
import cc.unitmesh.devti.gui.chat.ChatActionType
import cc.unitmesh.devti.provider.context.ChatContextItem
import cc.unitmesh.devti.provider.context.ChatContextProvider
import cc.unitmesh.devti.provider.context.ChatCreationContext
import cc.unitmesh.idea.MvcUtil
import com.intellij.lang.java.JavaLanguage
import com.intellij.openapi.application.runReadAction
import com.intellij.openapi.components.service
import com.intellij.openapi.project.Project
import com.intellij.openapi.util.NlsSafe
import com.intellij.psi.PsiClass
Expand All @@ -33,27 +35,43 @@ open class JavaTestContextProvider : ChatContextProvider {

val isSpringRelated = checkIsSpringRelated(creationContext)

val prompt = baseTestPrompt + junitRule(project)
var prompt = baseTestPrompt + junitRule(project)

val language = creationContext.sourceFile?.language?.displayName ?: "Java"

val finalPrompt = when {
isController(fileName) && isSpringRelated -> {
val testControllerPrompt = prompt + """
var testControllerPrompt = prompt + """
|- Use appropriate Spring test annotations such as `@MockBean`, `@Autowired`, `@WebMvcTest`, `@DataJpaTest`, `@AutoConfigureTestDatabase`, `@AutoConfigureMockMvc`, `@SpringBootTest` etc.
|""".trimMargin()

val lookup = project.service<TemplatedTestPrompt>().lookup("ControllerTest.java")
if (lookup != null) {
testControllerPrompt += "Here is a template as example\n```$language\n$lookup\n```\n"
}

ChatContextItem(JavaTestContextProvider::class, testControllerPrompt)
}

isService(fileName) && isSpringRelated -> {
val testServicePrompt = prompt + """
var testServicePrompt = prompt + """
|- Follow the common Spring code style by using the AssertJ library.
|- Assume that the database is empty before each test and create valid entities with consideration for data constraints (jakarta.validation.constraints).
|""".trimMargin()

val lookup = project.service<TemplatedTestPrompt>().lookup("ServiceTest.java")
if (lookup != null) {
testServicePrompt += "Here is a template as example\n```$language\n$lookup\n```\n"
}

ChatContextItem(JavaTestContextProvider::class, testServicePrompt)
}

else -> {
val lookup = project.service<TemplatedTestPrompt>().lookup("Test.java")
if (lookup != null) {
prompt += "Here is a template as example\n```$language\n$lookup\n```\n"
}
ChatContextItem(JavaTestContextProvider::class, prompt)
}
}
Expand Down
@@ -1,9 +1,11 @@
package cc.unitmesh.kotlin.provider

import cc.unitmesh.devti.custom.test.TemplatedTestPrompt
import cc.unitmesh.devti.gui.chat.ChatActionType
import cc.unitmesh.devti.provider.context.ChatContextItem
import cc.unitmesh.devti.provider.context.ChatCreationContext
import cc.unitmesh.idea.provider.JavaTestContextProvider
import com.intellij.openapi.components.service
import com.intellij.openapi.project.Project
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.idea.KotlinLanguage
Expand All @@ -25,26 +27,45 @@ class KotlinTestContextProvider : JavaTestContextProvider() {

val isSpringRelated = checkIsSpringRelated(creationContext)

val prompt = baseTestPrompt + junitRule(project)
var prompt = baseTestPrompt + junitRule(project)

val language = creationContext.sourceFile?.language?.displayName ?: "Kotlin"

val finalPrompt = when {
isController(fileName) && isSpringRelated -> {
val testControllerPrompt = prompt + "\n" + """
var testControllerPrompt = prompt + "\n" + """
|- Use appropriate Spring test annotations such as `@MockBean`, `@Autowired`, `@WebMvcTest`, `@DataJpaTest`, `@AutoConfigureTestDatabase`, `@AutoConfigureMockMvc`, `@SpringBootTest` etc.
|""".trimMargin()

val lookup = project.service<TemplatedTestPrompt>().lookup("ControllerTest.kt")
if (lookup != null) {
testControllerPrompt += "Here is a template as example\n```$language\n$lookup\n```\n"
}

ChatContextItem(JavaTestContextProvider::class, testControllerPrompt)
}

isService(fileName) && isSpringRelated -> {
val testServicePrompt = prompt + "\n" + """
var testServicePrompt = prompt + "\n" + """
|- Follow the common Spring code style by using the AssertJ library.
|- Assume that the database is empty before each test and create valid entities with consideration for data constraints (jakarta.validation.constraints).
|""".trimMargin()


val lookup = project.service<TemplatedTestPrompt>().lookup("ServiceTest.kt")
if (lookup != null) {
testServicePrompt += "Here is a template as example\n```$language\n$lookup\n```\n"
}

ChatContextItem(JavaTestContextProvider::class, testServicePrompt)
}

else -> {
val lookup = project.service<TemplatedTestPrompt>().lookup("Test.java")
if (lookup != null) {
prompt += "Here is a template as example\n```$language\n$lookup\n```\n"
}

ChatContextItem(JavaTestContextProvider::class, prompt)
}
}
Expand Down
Expand Up @@ -16,11 +16,22 @@ import com.intellij.openapi.progress.impl.BackgroundableProcessIndicator
import com.intellij.openapi.project.Project
import com.intellij.psi.PsiElement

/**
* The `TeamPromptExecTask` class is a background task that executes a team prompt action in the context of a project.
* It is responsible for handling different types of interactions based on the provided `intentionConfig` and `msgs`.
*
* @property project The project in which the team prompt action is executed.
* @property msgs The list of chat messages associated with the team prompt action.
* @property editor The editor in which the team prompt action is triggered.
* @property intentionConfig The configuration of the team prompt action.
* @property element The PSI element associated with the team prompt action.
* @constructor Creates a `TeamPromptExecTask` with the specified project, chat messages, editor, intention configuration, and PSI element.
*/
class TeamPromptExecTask(
@JvmField val project: Project,
val msgs: List<LlmMsg.ChatMessage>,
private val msgs: List<LlmMsg.ChatMessage>,
val editor: Editor,
val intentionConfig: TeamPromptAction,
private val intentionConfig: TeamPromptAction,
val element: PsiElement?,
) :
Task.Backgroundable(project, AutoDevBundle.message("intentions.request.background.process.title")) {
Expand Down
@@ -0,0 +1,20 @@
package cc.unitmesh.devti.custom.test

import cc.unitmesh.devti.settings.custom.teamPromptsSettings
import com.intellij.openapi.components.Service
import com.intellij.openapi.project.Project
import com.intellij.openapi.project.guessProjectDir

@Service(Service.Level.PROJECT)
class TemplatedTestPrompt(private val project: Project) {
val settings = project.teamPromptsSettings

fun lookup(fileName: String): String? {
val path = settings.state.teamPromptsDir
val promptsDir = project.guessProjectDir()?.findChild(path) ?: return null
val templateFile = promptsDir.findChild(fileName) ?: return null

val templateCode = templateFile.children.firstOrNull { it.name.endsWith(".vm") } ?: return null
return templateCode.inputStream.readBytes().toString(Charsets.UTF_8)
}
}

0 comments on commit 94d588a

Please sign in to comment.