Skip to content

Commit

Permalink
feat(cpp): add test file creation logic
Browse files Browse the repository at this point in the history
- Add logic to create a test file for a given source file in the CppWriteTestService class.
- Check if the project root test folder exists, and create it if not.
- Generate the test file name based on the source file name.
- Use WriteAction to create the test file in the project directory.
- Update the TestFileContext to include the newly created test file.
- Also, add logic to determine the test framework used in the CLionWorkspaceContextProvider class.
- Check the CMakeWorkspace for dependencies
  • Loading branch information
phodal committed Jan 17, 2024
1 parent 4aceadd commit 89cda73
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 2 deletions.
Expand Up @@ -7,8 +7,10 @@ import com.intellij.execution.wsl.WslPath
import com.intellij.openapi.project.Project
import com.intellij.openapi.roots.ProjectRootManager
import com.intellij.openapi.vfs.VirtualFile
import com.jetbrains.cidr.cpp.cmake.workspace.CMakeWorkspace
import com.jetbrains.cidr.lang.OCLanguage
import com.jetbrains.cidr.project.workspace.CidrWorkspace
import java.io.File

class CLionWorkspaceContextProvider : ChatContextProvider {
private val configFiles = listOf(
Expand All @@ -26,7 +28,12 @@ class CLionWorkspaceContextProvider : ChatContextProvider {
val isUnderWslItem = createIsUnderWslItem(project)
val preferredLanguageItem = createPreferredLanguageItem(project, creationContext)

return (listOf(projectNameItem, configFileItem) + isUnderWslItem + preferredLanguageItem)
val testFrameworkItem = createTestFrameworkItem(project, creationContext)

return (listOf(
projectNameItem,
configFileItem
) + isUnderWslItem + preferredLanguageItem + testFrameworkItem).filterNotNull()
}

private fun createProjectNameItem(project: Project): ChatContextItem {
Expand All @@ -53,6 +60,32 @@ class CLionWorkspaceContextProvider : ChatContextProvider {
}
}

private fun createTestFrameworkItem(project: Project, creationContext: ChatCreationContext): ChatContextItem? {
val cmakeWorkspace = CMakeWorkspace.getInstance(project)
if (!cmakeWorkspace.isInitialized) {
return null
}

cmakeWorkspace.cMakeDependencyFiles.forEach { file ->
val text = file.readText()
if (text.contains("gtest") || text.contains("gmock")) {
return ChatContextItem(
CLionWorkspaceContextProvider::class,
"The project uses Google Test framework."
)
}

if (text.contains("catch")) {
return ChatContextItem(
CLionWorkspaceContextProvider::class,
"The project uses Catch2 framework."
)
}
}

return null
}

private fun createPreferredLanguageItem(
project: Project,
creationContext: ChatCreationContext
Expand Down
Expand Up @@ -5,12 +5,25 @@ import cc.unitmesh.devti.context.ClassContext
import cc.unitmesh.devti.provider.WriteTestService
import cc.unitmesh.devti.provider.context.TestFileContext
import com.intellij.execution.configurations.RunProfile
import com.intellij.openapi.application.ReadAction
import com.intellij.openapi.application.WriteAction
import com.intellij.openapi.application.runReadAction
import com.intellij.openapi.application.runWriteAction
import com.intellij.openapi.project.Project
import com.intellij.openapi.project.guessProjectDir
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.psi.PsiDirectory
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiFile
import com.jetbrains.cidr.cpp.execution.testing.CMakeTestRunConfiguration
import com.jetbrains.cidr.lang.psi.OCFunctionDeclaration

private val String.nameWithoutExtension: String
get() {
val lastDot = lastIndexOf('.')
return if (lastDot == -1) this else substring(0, lastDot)
}

// use Google Test or CATCH?
class CppWriteTestService : WriteTestService() {
override fun runConfigurationClass(project: Project): Class<out RunProfile> = CMakeTestRunConfiguration::class.java
Expand All @@ -20,18 +33,29 @@ class CppWriteTestService : WriteTestService() {
}

override fun findOrCreateTestFile(sourceFile: PsiFile, project: Project, element: PsiElement): TestFileContext? {
// 1. check project root test folder, if not exist, create it
val baseDir = project.guessProjectDir() ?: return null

val sourceFilePath = sourceFile.virtualFile.name

val testFilePath = sourceFilePath.nameWithoutExtension + "_test" + "." + sourceFile.virtualFile.extension
val testFile = WriteAction.computeAndWait<VirtualFile?, Throwable> {
baseDir.findOrCreateChildData(this, testFilePath)
} ?: return null

val currentClass = when (element) {
is OCFunctionDeclaration -> {
CppContextPrettify.printParentStructure(element)
}

else -> null
}

val relatedClasses = lookupRelevantClass(project, element)

return TestFileContext(
true,
sourceFile.virtualFile,
testFile,
relatedClasses,
"",
sourceFile.language,
Expand Down

0 comments on commit 89cda73

Please sign in to comment.