Skip to content

Commit 89cda73

Browse files
committed
feat(cpp): add test file creation logic
- 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
1 parent 4aceadd commit 89cda73

File tree

2 files changed

+59
-2
lines changed

2 files changed

+59
-2
lines changed

cpp/src/main/kotlin/cc/unitmesh/cpp/provider/CLionWorkspaceContextProvider.kt

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,10 @@ import com.intellij.execution.wsl.WslPath
77
import com.intellij.openapi.project.Project
88
import com.intellij.openapi.roots.ProjectRootManager
99
import com.intellij.openapi.vfs.VirtualFile
10+
import com.jetbrains.cidr.cpp.cmake.workspace.CMakeWorkspace
1011
import com.jetbrains.cidr.lang.OCLanguage
1112
import com.jetbrains.cidr.project.workspace.CidrWorkspace
13+
import java.io.File
1214

1315
class CLionWorkspaceContextProvider : ChatContextProvider {
1416
private val configFiles = listOf(
@@ -26,7 +28,12 @@ class CLionWorkspaceContextProvider : ChatContextProvider {
2628
val isUnderWslItem = createIsUnderWslItem(project)
2729
val preferredLanguageItem = createPreferredLanguageItem(project, creationContext)
2830

29-
return (listOf(projectNameItem, configFileItem) + isUnderWslItem + preferredLanguageItem)
31+
val testFrameworkItem = createTestFrameworkItem(project, creationContext)
32+
33+
return (listOf(
34+
projectNameItem,
35+
configFileItem
36+
) + isUnderWslItem + preferredLanguageItem + testFrameworkItem).filterNotNull()
3037
}
3138

3239
private fun createProjectNameItem(project: Project): ChatContextItem {
@@ -53,6 +60,32 @@ class CLionWorkspaceContextProvider : ChatContextProvider {
5360
}
5461
}
5562

63+
private fun createTestFrameworkItem(project: Project, creationContext: ChatCreationContext): ChatContextItem? {
64+
val cmakeWorkspace = CMakeWorkspace.getInstance(project)
65+
if (!cmakeWorkspace.isInitialized) {
66+
return null
67+
}
68+
69+
cmakeWorkspace.cMakeDependencyFiles.forEach { file ->
70+
val text = file.readText()
71+
if (text.contains("gtest") || text.contains("gmock")) {
72+
return ChatContextItem(
73+
CLionWorkspaceContextProvider::class,
74+
"The project uses Google Test framework."
75+
)
76+
}
77+
78+
if (text.contains("catch")) {
79+
return ChatContextItem(
80+
CLionWorkspaceContextProvider::class,
81+
"The project uses Catch2 framework."
82+
)
83+
}
84+
}
85+
86+
return null
87+
}
88+
5689
private fun createPreferredLanguageItem(
5790
project: Project,
5891
creationContext: ChatCreationContext

cpp/src/main/kotlin/cc/unitmesh/cpp/provider/testing/CppWriteTestService.kt

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,25 @@ import cc.unitmesh.devti.context.ClassContext
55
import cc.unitmesh.devti.provider.WriteTestService
66
import cc.unitmesh.devti.provider.context.TestFileContext
77
import com.intellij.execution.configurations.RunProfile
8+
import com.intellij.openapi.application.ReadAction
9+
import com.intellij.openapi.application.WriteAction
10+
import com.intellij.openapi.application.runReadAction
11+
import com.intellij.openapi.application.runWriteAction
812
import com.intellij.openapi.project.Project
13+
import com.intellij.openapi.project.guessProjectDir
14+
import com.intellij.openapi.vfs.VirtualFile
15+
import com.intellij.psi.PsiDirectory
916
import com.intellij.psi.PsiElement
1017
import com.intellij.psi.PsiFile
1118
import com.jetbrains.cidr.cpp.execution.testing.CMakeTestRunConfiguration
1219
import com.jetbrains.cidr.lang.psi.OCFunctionDeclaration
1320

21+
private val String.nameWithoutExtension: String
22+
get() {
23+
val lastDot = lastIndexOf('.')
24+
return if (lastDot == -1) this else substring(0, lastDot)
25+
}
26+
1427
// use Google Test or CATCH?
1528
class CppWriteTestService : WriteTestService() {
1629
override fun runConfigurationClass(project: Project): Class<out RunProfile> = CMakeTestRunConfiguration::class.java
@@ -20,18 +33,29 @@ class CppWriteTestService : WriteTestService() {
2033
}
2134

2235
override fun findOrCreateTestFile(sourceFile: PsiFile, project: Project, element: PsiElement): TestFileContext? {
36+
// 1. check project root test folder, if not exist, create it
37+
val baseDir = project.guessProjectDir() ?: return null
38+
39+
val sourceFilePath = sourceFile.virtualFile.name
40+
41+
val testFilePath = sourceFilePath.nameWithoutExtension + "_test" + "." + sourceFile.virtualFile.extension
42+
val testFile = WriteAction.computeAndWait<VirtualFile?, Throwable> {
43+
baseDir.findOrCreateChildData(this, testFilePath)
44+
} ?: return null
45+
2346
val currentClass = when (element) {
2447
is OCFunctionDeclaration -> {
2548
CppContextPrettify.printParentStructure(element)
2649
}
2750

2851
else -> null
2952
}
53+
3054
val relatedClasses = lookupRelevantClass(project, element)
3155

3256
return TestFileContext(
3357
true,
34-
sourceFile.virtualFile,
58+
testFile,
3559
relatedClasses,
3660
"",
3761
sourceFile.language,

0 commit comments

Comments
 (0)