Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactoring before the release #321

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
0ea4113
rename factories to builders
arksap2002 Aug 19, 2024
4037864
remove listener
arksap2002 Aug 19, 2024
eba2299
reformat display files
arksap2002 Aug 19, 2024
663e3ff
move test samples detection inside actions folder
arksap2002 Aug 19, 2024
a8474f2
convert TopButtonsPanelStrategy to object
arksap2002 Aug 19, 2024
fd1b383
convert factories to objects
arksap2002 Aug 19, 2024
440a7e4
rename TestClassCode to Test
arksap2002 Aug 19, 2024
0de4f8f
create template folders, and put interfaces there
arksap2002 Aug 20, 2024
d80db7e
move test code analyzer and generator to a separate folder
arksap2002 Aug 20, 2024
b7e1d2f
rename TestCaseDisplayServices to TestCaseDisplayBuilders
arksap2002 Aug 20, 2024
0f45ad1
reformat the display services implementation
arksap2002 Aug 20, 2024
8036cea
remove test suite views
arksap2002 Aug 20, 2024
52dd9bc
remove TopButtonsPanelStrategy.kt
arksap2002 Aug 20, 2024
04ef483
remove CoverageVisualisationService.kt
arksap2002 Aug 21, 2024
b7ea44b
remove coverage helpers
arksap2002 Aug 21, 2024
cf7f0f3
create folder generatedTests
arksap2002 Aug 21, 2024
aeb4566
rename factories to builders
arksap2002 Aug 21, 2024
b18ac25
remove TestCaseDisplayBuilder.kt
arksap2002 Aug 21, 2024
82cc0f9
move testSparkDisplayBuilder to TestSparkAction
arksap2002 Aug 21, 2024
26b493e
move language utils to display.utils folder
arksap2002 Aug 21, 2024
e054a74
refactor GeneratedTestsTabBuilder
arksap2002 Aug 21, 2024
04dc234
remove EditorService.kt
arksap2002 Aug 21, 2024
e9956eb
ktlint
arksap2002 Aug 21, 2024
844f9aa
rename TestSparkDisplayBuilder to TestSparkDisplayManager
arksap2002 Aug 22, 2024
bdf4676
remove TestsExecutionResultService
arksap2002 Aug 22, 2024
979416e
move factories to a separate folder
arksap2002 Aug 22, 2024
6f93428
ktlint
arksap2002 Aug 22, 2024
28bad1d
move file to another folder
arksap2002 Aug 22, 2024
b567f75
fix separators
arksap2002 Aug 23, 2024
76aaae4
move factories to tools.llm
arksap2002 Aug 28, 2024
c2d9e11
ktlint
arksap2002 Aug 28, 2024
babb48e
add comments
arksap2002 Aug 28, 2024
4ac5913
ktlint
arksap2002 Aug 28, 2024
1077de6
add dark icon
arksap2002 Aug 28, 2024
a4c658b
Merge branch 'ebraun/bugs/psi-related-bugs/top-level-function' into a…
arksap2002 Aug 28, 2024
e5cc2e8
Merge branch 'arksap2002/refactoring/remove-services' into arksap2002…
arksap2002 Aug 28, 2024
ad66bbe
Merge pull request #323 from JetBrains-Research/arksap2002/improvment…
arksap2002 Aug 28, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,12 @@ data class TestCasesCompilationResult(
val compilableTestCases: MutableSet<TestCaseGeneratedByLLM>,
)

abstract class TestCompiler(
private val libPaths: List<String>,
private val junitLibPaths: List<String>,
) {
abstract class TestCompiler(libPaths: List<String>, junitLibPaths: List<String>) {
val separator = DataFilesUtil.classpathSeparator
val dependencyLibPath = libPaths.joinToString(separator.toString())
val junitPath = junitLibPaths.joinToString(separator.toString())
val commonPath = "$junitPath${separator}$dependencyLibPath$separator"

/**
* Compiles a list of test cases and returns the compilation result.
*
Expand Down Expand Up @@ -55,15 +57,5 @@ abstract class TestCompiler(
* @param buildPath The path of the build file.
* @return The generated path as a string.
*/
fun getClassPaths(buildPath: String): String {
// create the path for the command
val separator = DataFilesUtil.classpathSeparator
val dependencyLibPath = libPaths.joinToString(separator.toString())
val junitPath = junitLibPaths.joinToString(separator.toString())

val path = "$junitPath${separator}$dependencyLibPath${separator}$buildPath"
println("[TestCompiler]: the path is: $path")

return path
}
abstract fun getClassPaths(buildPath: String): String
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,4 +50,12 @@ class JavaTestCompiler(
// check is .class file exists
return Pair(File(classFilePath).exists(), errorMsg)
}

override fun getClassPaths(buildPath: String): String {
var path = commonPath.plus(buildPath)

if (path.endsWith(separator)) path = path.removeSuffix(separator.toString())

return path
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,6 @@ class KotlinTestCompiler(libPaths: List<String>, junitLibPaths: List<String>) :
// No need to save the .class file for kotlin, so checking the error message is enough
return Pair(errorMsg.isBlank(), errorMsg)
}

override fun getClassPaths(buildPath: String): String = commonPath.plus(buildPath)
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,22 @@ import com.intellij.ui.components.JBScrollPane
import com.intellij.util.ui.FormBuilder
import org.jetbrains.research.testspark.actions.controllers.TestGenerationController
import org.jetbrains.research.testspark.actions.controllers.VisibilityController
import org.jetbrains.research.testspark.actions.evosuite.EvoSuitePanelFactory
import org.jetbrains.research.testspark.actions.llm.LLMSampleSelectorFactory
import org.jetbrains.research.testspark.actions.llm.LLMSetupPanelFactory
import org.jetbrains.research.testspark.actions.template.PanelFactory
import org.jetbrains.research.testspark.actions.evosuite.EvoSuitePanelBuilder
import org.jetbrains.research.testspark.actions.llm.LLMSampleSelectorBuilder
import org.jetbrains.research.testspark.actions.llm.LLMSetupPanelBuilder
import org.jetbrains.research.testspark.actions.template.PanelBuilder
import org.jetbrains.research.testspark.bundles.plugin.PluginLabelsBundle
import org.jetbrains.research.testspark.bundles.plugin.PluginMessagesBundle
import org.jetbrains.research.testspark.core.test.data.CodeType
import org.jetbrains.research.testspark.display.TestSparkDisplayManager
import org.jetbrains.research.testspark.display.TestSparkIcons
import org.jetbrains.research.testspark.langwrappers.PsiHelper
import org.jetbrains.research.testspark.langwrappers.PsiHelperProvider
import org.jetbrains.research.testspark.services.EvoSuiteSettingsService
import org.jetbrains.research.testspark.services.LLMSettingsService
import org.jetbrains.research.testspark.settings.evosuite.EvoSuiteSettingsState
import org.jetbrains.research.testspark.settings.llm.LLMSettingsState
import org.jetbrains.research.testspark.tools.TestsExecutionResultManager
import org.jetbrains.research.testspark.tools.evosuite.EvoSuite
import org.jetbrains.research.testspark.tools.llm.Llm
import org.jetbrains.research.testspark.tools.template.Tool
Expand Down Expand Up @@ -53,6 +55,9 @@ class TestSparkAction : AnAction() {
private val visibilityController = VisibilityController()
private val testGenerationController = TestGenerationController()

private val testSparkDisplayManager = TestSparkDisplayManager()
private val testsExecutionResultManager = TestsExecutionResultManager()

/**
* Handles the action performed event.
*
Expand All @@ -63,7 +68,7 @@ class TestSparkAction : AnAction() {
* This parameter is required.
*/
override fun actionPerformed(e: AnActionEvent) {
TestSparkActionWindow(e, visibilityController, testGenerationController)
TestSparkActionWindow(e, visibilityController, testGenerationController, testSparkDisplayManager, testsExecutionResultManager)
}

/**
Expand All @@ -88,6 +93,8 @@ class TestSparkAction : AnAction() {
private val e: AnActionEvent,
private val visibilityController: VisibilityController,
private val testGenerationController: TestGenerationController,
private val testSparkDisplayManager: TestSparkDisplayManager,
private val testsExecutionResultManager: TestsExecutionResultManager,
) :
JFrame("TestSpark") {
private val project: Project = e.project!!
Expand Down Expand Up @@ -121,9 +128,9 @@ class TestSparkAction : AnAction() {
private val nextButton = JButton(PluginLabelsBundle.get("next"))

private val cardLayout = CardLayout()
private val llmSetupPanelFactory = LLMSetupPanelFactory(e, project)
private val llmSampleSelectorFactory = LLMSampleSelectorFactory(project, psiHelper.language)
private val evoSuitePanelFactory = EvoSuitePanelFactory(project)
private val llmSetupPanelFactory = LLMSetupPanelBuilder(e, project)
private val llmSampleSelectorFactory = LLMSampleSelectorBuilder(project, psiHelper.language)
private val evoSuitePanelFactory = EvoSuitePanelBuilder(project)

init {
if (!visibilityController.isVisible) {
Expand Down Expand Up @@ -167,11 +174,11 @@ class TestSparkAction : AnAction() {
}
}

private fun createCardPanel(toolPanelFactory: PanelFactory): JPanel {
private fun createCardPanel(toolPanelBuilder: PanelBuilder): JPanel {
val cardPanel = JPanel(BorderLayout())
cardPanel.add(toolPanelFactory.getTitlePanel(), BorderLayout.NORTH)
cardPanel.add(toolPanelFactory.getMiddlePanel(), BorderLayout.CENTER)
cardPanel.add(toolPanelFactory.getBottomPanel(), BorderLayout.SOUTH)
cardPanel.add(toolPanelBuilder.getTitlePanel(), BorderLayout.NORTH)
cardPanel.add(toolPanelBuilder.getMiddlePanel(), BorderLayout.CENTER)
cardPanel.add(toolPanelBuilder.getBottomPanel(), BorderLayout.SOUTH)

return cardPanel
}
Expand Down Expand Up @@ -343,6 +350,8 @@ class TestSparkAction : AnAction() {
fileUrl,
testSamplesCode,
testGenerationController,
testSparkDisplayManager,
testsExecutionResultManager,
)
CodeType.METHOD -> tool.generateTestsForMethod(
project,
Expand All @@ -351,6 +360,8 @@ class TestSparkAction : AnAction() {
fileUrl,
testSamplesCode,
testGenerationController,
testSparkDisplayManager,
testsExecutionResultManager,
)
CodeType.LINE -> tool.generateTestsForLine(
project,
Expand All @@ -359,6 +370,8 @@ class TestSparkAction : AnAction() {
fileUrl,
testSamplesCode,
testGenerationController,
testSparkDisplayManager,
testsExecutionResultManager,
)
}
break
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import com.intellij.openapi.project.Project
import com.intellij.openapi.ui.ComboBox
import com.intellij.ui.components.JBLabel
import com.intellij.util.ui.FormBuilder
import org.jetbrains.research.testspark.actions.template.PanelFactory
import org.jetbrains.research.testspark.actions.template.PanelBuilder
import org.jetbrains.research.testspark.bundles.evosuite.EvoSuiteLabelsBundle
import org.jetbrains.research.testspark.bundles.evosuite.EvoSuiteSettingsBundle
import org.jetbrains.research.testspark.bundles.plugin.PluginLabelsBundle
Expand All @@ -17,7 +17,7 @@ import javax.swing.JLabel
import javax.swing.JPanel
import javax.swing.JTextField

class EvoSuitePanelFactory(private val project: Project) : PanelFactory {
class EvoSuitePanelBuilder(private val project: Project) : PanelBuilder {
private val evoSuiteSettingsState: EvoSuiteSettingsState
get() = project.getService(EvoSuiteSettingsService::class.java).state

Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,27 @@
package org.jetbrains.research.testspark.actions.llm

import com.intellij.openapi.fileTypes.FileType
import com.intellij.openapi.fileTypes.FileTypeManager
import com.intellij.openapi.project.Project
import com.intellij.openapi.roots.ProjectFileIndex
import com.intellij.openapi.roots.ProjectRootManager
import com.intellij.psi.PsiClass
import com.intellij.psi.PsiJavaFile
import com.intellij.psi.PsiManager
import com.intellij.psi.PsiMethod
import com.intellij.util.containers.stream
import com.intellij.util.ui.FormBuilder
import org.jetbrains.research.testspark.actions.template.PanelFactory
import org.jetbrains.research.testspark.actions.template.PanelBuilder
import org.jetbrains.research.testspark.bundles.plugin.PluginLabelsBundle
import org.jetbrains.research.testspark.core.test.SupportedLanguage
import org.jetbrains.research.testspark.helpers.LLMTestSampleHelper
import java.awt.Font
import javax.swing.ButtonGroup
import javax.swing.JButton
import javax.swing.JLabel
import javax.swing.JPanel
import javax.swing.JRadioButton

class LLMSampleSelectorFactory(private val project: Project, private val language: SupportedLanguage) : PanelFactory {
class LLMSampleSelectorBuilder(private val project: Project, private val language: SupportedLanguage) : PanelBuilder {
// init components
private val selectionTypeButtons: MutableList<JRadioButton> = mutableListOf(
JRadioButton(PluginLabelsBundle.get("provideTestSample")),
Expand All @@ -25,8 +33,8 @@ class LLMSampleSelectorFactory(private val project: Project, private val languag
private val defaultTestName = "<html>provide manually</html>"
private val defaultTestCode = "// provide test method code here"
private val testNames = mutableListOf(defaultTestName)
private val initialTestCodes = mutableListOf(LLMTestSampleHelper.createTestSampleClass("", defaultTestCode))
private val testSamplePanelFactories: MutableList<TestSamplePanelFactory> = mutableListOf()
private val initialTestCodes = mutableListOf(createTestSampleClass("", defaultTestCode))
private val testSamplePanelFactories: MutableList<TestSamplePanelBuilder> = mutableListOf()
private var testSamplesCode: String = ""

private val addButtonPanel = JPanel()
Expand All @@ -46,7 +54,7 @@ class LLMSampleSelectorFactory(private val project: Project, private val languag
init {
addListeners()

LLMTestSampleHelper.collectTestSamples(project, testNames, initialTestCodes)
collectTestSamples(project, testNames, initialTestCodes)
}

override fun getTitlePanel(): JPanel {
Expand Down Expand Up @@ -129,18 +137,19 @@ class LLMSampleSelectorFactory(private val project: Project, private val languag
}

addButton.addActionListener {
val testSamplePanelFactory = TestSamplePanelFactory(project, middlePanel, testNames, initialTestCodes, language)
testSamplePanelFactories.add(testSamplePanelFactory)
val testSamplePanel = testSamplePanelFactory.getTestSamplePanel()
val codeScrollPanel = testSamplePanelFactory.getCodeScrollPanel()
val testSamplePanelBuilder =
TestSamplePanelBuilder(project, middlePanel, testNames, initialTestCodes, language)
testSamplePanelFactories.add(testSamplePanelBuilder)
val testSamplePanel = testSamplePanelBuilder.getTestSamplePanel()
val codeScrollPanel = testSamplePanelBuilder.getCodeScrollPanel()
formBuilder = formBuilder
.addComponent(testSamplePanel, 10)
.addComponent(codeScrollPanel, 10)
middlePanel = formBuilder.panel
middlePanel.revalidate()

testSamplePanelFactory.getRemoveButton().addActionListener {
testSamplePanelFactories.remove(testSamplePanelFactory)
testSamplePanelBuilder.getRemoveButton().addActionListener {
testSamplePanelFactories.remove(testSamplePanelBuilder)
middlePanel.remove(testSamplePanel)
middlePanel.remove(codeScrollPanel)
middlePanel.revalidate()
Expand Down Expand Up @@ -173,4 +182,55 @@ class LLMSampleSelectorFactory(private val project: Project, private val languag
testSamplePanelFactory.enabledComponents(isEnabled)
}
}

/**
* Retrieves a list of test samples from the given project.
*
* @return A list of strings, representing the names of the test samples.
*/
private fun collectTestSamples(project: Project, testNames: MutableList<String>, initialTestCodes: MutableList<String>) {
val projectFileIndex: ProjectFileIndex = ProjectRootManager.getInstance(project).fileIndex
val javaFileType: FileType = FileTypeManager.getInstance().getFileTypeByExtension("java")

projectFileIndex.iterateContent { file ->
if (file.fileType === javaFileType) {
try {
val psiJavaFile = (PsiManager.getInstance(project).findFile(file) as PsiJavaFile)
val psiClass = psiJavaFile.classes[
psiJavaFile.classes.stream().map { it.name }.toArray()
.indexOf(psiJavaFile.name.removeSuffix(".java")),
]
var imports = psiJavaFile.importList?.allImportStatements?.map { it.text }?.toList()
?.joinToString("\n") ?: ""
if (psiClass.qualifiedName != null && psiClass.qualifiedName!!.contains(".")) {
imports += "\nimport ${psiClass.qualifiedName?.substringBeforeLast(".") + ".*"};"
}
psiClass.allMethods.forEach { method ->
val annotations = method.modifierList.annotations
annotations.forEach { annotation ->
if (annotation.qualifiedName == "org.junit.jupiter.api.Test" || annotation.qualifiedName == "org.junit.Test") {
val code: String = createTestSampleClass(imports, method.text)
testNames.add(createMethodName(psiClass, method))
initialTestCodes.add(code)
}
}
}
} catch (_: Exception) {
}
}
true
}
}

private fun createTestSampleClass(imports: String, methodCode: String): String {
var normalizedImports = imports
if (normalizedImports.isNotBlank()) normalizedImports += "\n\n"
return normalizedImports +
"public class TestSample {\n" +
" $methodCode\n" +
"}"
}

private fun createMethodName(psiClass: PsiClass, method: PsiMethod): String =
"<html>${psiClass.qualifiedName}#${method.name}</html>"
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import com.intellij.openapi.project.Project
import com.intellij.openapi.ui.ComboBox
import com.intellij.ui.components.JBLabel
import com.intellij.util.ui.FormBuilder
import org.jetbrains.research.testspark.actions.template.PanelFactory
import org.jetbrains.research.testspark.actions.template.PanelBuilder
import org.jetbrains.research.testspark.bundles.llm.LLMLabelsBundle
import org.jetbrains.research.testspark.bundles.plugin.PluginLabelsBundle
import org.jetbrains.research.testspark.core.data.JUnitVersion
Expand All @@ -26,7 +26,7 @@ import javax.swing.JLabel
import javax.swing.JPanel
import javax.swing.JTextField

class LLMSetupPanelFactory(e: AnActionEvent, private val project: Project) : PanelFactory {
class LLMSetupPanelBuilder(e: AnActionEvent, private val project: Project) : PanelBuilder {
private val llmSettingsState: LLMSettingsState
get() = project.getService(LLMSettingsService::class.java).state

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,17 @@ import com.intellij.ui.LanguageTextField
import com.intellij.ui.components.JBScrollPane
import org.jetbrains.research.testspark.bundles.plugin.PluginLabelsBundle
import org.jetbrains.research.testspark.core.test.SupportedLanguage
import org.jetbrains.research.testspark.display.IconButtonCreator
import org.jetbrains.research.testspark.display.ModifiedLinesGetter
import org.jetbrains.research.testspark.display.TestCaseDocumentCreator
import org.jetbrains.research.testspark.display.TestSparkIcons
import org.jetbrains.research.testspark.display.utils.IconButtonCreator
import org.jetbrains.research.testspark.display.utils.ModifiedLinesGetter
import javax.swing.BoxLayout
import javax.swing.DefaultComboBoxModel
import javax.swing.JButton
import javax.swing.JPanel
import javax.swing.ScrollPaneConstants

class TestSamplePanelFactory(
class TestSamplePanelBuilder(
project: Project,
private val middlePanel: JPanel,
private val testNames: MutableList<String>,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package org.jetbrains.research.testspark.actions.template
import javax.swing.JButton
import javax.swing.JPanel

interface PanelFactory {
interface PanelBuilder {
/**
* Returns a JPanel object containing the title panel.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,10 @@ import org.jetbrains.research.testspark.langwrappers.PsiHelperProvider
import org.jetbrains.research.testspark.progress.HeadlessProgressIndicator
import org.jetbrains.research.testspark.services.LLMSettingsService
import org.jetbrains.research.testspark.services.PluginSettingsService
import org.jetbrains.research.testspark.tools.TestCompilerFactory
import org.jetbrains.research.testspark.tools.TestProcessor
import org.jetbrains.research.testspark.tools.TestsExecutionResultManager
import org.jetbrains.research.testspark.tools.ToolUtils
import org.jetbrains.research.testspark.tools.factories.TestCompilerFactory
import org.jetbrains.research.testspark.tools.llm.Llm
import java.io.File
import java.nio.file.Path
Expand Down Expand Up @@ -71,6 +72,8 @@ class TestSparkStarter : ApplicationStarter {
// Run coverage
val runCoverage = args[10].toBoolean()

val testsExecutionResultManager = TestsExecutionResultManager()

println("Test generation requested for $projectPath")

// remove the `.idea` folder in the $projectPath if exists
Expand Down Expand Up @@ -187,6 +190,7 @@ class TestSparkStarter : ApplicationStarter {
projectContext,
testGenerationData,
errorMonitor,
testsExecutionResultManager,
)

// Check test Generation Output
Expand Down
Loading
Loading