-
Notifications
You must be signed in to change notification settings - Fork 23
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
fa17914
commit f77a23f
Showing
26 changed files
with
2,380 additions
and
0 deletions.
There are no files selected for viewing
8 changes: 8 additions & 0 deletions
8
core/src/main/kotlin/org/jetbrains/research/testspark/core/test/SupportedLanguage.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
package org.jetbrains.research.testspark.core.test | ||
|
||
/** | ||
* Language ID string should be the same as the language name in com.intellij.lang.Language | ||
*/ | ||
enum class SupportedLanguage(val languageId: String) { | ||
Java("JAVA"), Kotlin("kotlin") | ||
} |
21 changes: 21 additions & 0 deletions
21
core/src/main/kotlin/org/jetbrains/research/testspark/core/test/TestBodyPrinter.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
package org.jetbrains.research.testspark.core.test | ||
|
||
import org.jetbrains.research.testspark.core.test.data.TestLine | ||
|
||
interface TestBodyPrinter { | ||
/** | ||
* Generates a test body as a string based on the provided parameters. | ||
* | ||
* @param testInitiatedText A string containing the upper part of the test case. | ||
* @param lines A mutable list of `TestLine` objects representing the lines of the test body. | ||
* @param throwsException The exception type that the test function throws, if any. | ||
* @param name The name of the test function. | ||
* @return A string representing the complete test body. | ||
*/ | ||
fun printTestBody( | ||
testInitiatedText: String, | ||
lines: MutableList<TestLine>, | ||
throwsException: String, | ||
name: String, | ||
): String | ||
} |
20 changes: 20 additions & 0 deletions
20
core/src/main/kotlin/org/jetbrains/research/testspark/core/test/TestSuiteParser.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
package org.jetbrains.research.testspark.core.test | ||
|
||
import org.jetbrains.research.testspark.core.test.data.TestCaseGeneratedByLLM | ||
import org.jetbrains.research.testspark.core.test.data.TestSuiteGeneratedByLLM | ||
|
||
data class TestCaseParseResult( | ||
val testCase: TestCaseGeneratedByLLM?, | ||
val errorMessage: String, | ||
val errorOccurred: Boolean, | ||
) | ||
|
||
interface TestSuiteParser { | ||
/** | ||
* Extracts test cases from raw text and generates a test suite. | ||
* | ||
* @param rawText The raw text provided by the LLM that contains the generated test cases. | ||
* @return A GeneratedTestSuite instance containing the extracted test cases. | ||
*/ | ||
fun parseTestSuite(rawText: String): TestSuiteGeneratedByLLM? | ||
} |
8 changes: 8 additions & 0 deletions
8
core/src/main/kotlin/org/jetbrains/research/testspark/core/test/data/CodeType.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
package org.jetbrains.research.testspark.core.test.data | ||
|
||
/** | ||
* Enum class, which contains all code elements for which it is possible to request test generation. | ||
*/ | ||
enum class CodeType { | ||
CLASS, METHOD, LINE | ||
} |
30 changes: 30 additions & 0 deletions
30
...g/jetbrains/research/testspark/core/test/data/dependencies/TestCompilationDependencies.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
package org.jetbrains.research.testspark.core.test.data.dependencies | ||
|
||
import org.jetbrains.research.testspark.core.data.JarLibraryDescriptor | ||
|
||
/** | ||
* The class represents a list of dependencies required for java test compilation. | ||
* The libraries listed are used during test suite/test case compilation. | ||
*/ | ||
class TestCompilationDependencies { | ||
companion object { | ||
fun getJarDescriptors() = listOf( | ||
JarLibraryDescriptor( | ||
"mockito-core-5.0.0.jar", | ||
"https://repo1.maven.org/maven2/org/mockito/mockito-core/5.0.0/mockito-core-5.0.0.jar", | ||
), | ||
JarLibraryDescriptor( | ||
"hamcrest-core-1.3.jar", | ||
"https://repo1.maven.org/maven2/org/hamcrest/hamcrest-core/1.3/hamcrest-core-1.3.jar", | ||
), | ||
JarLibraryDescriptor( | ||
"byte-buddy-1.14.6.jar", | ||
"https://repo1.maven.org/maven2/net/bytebuddy/byte-buddy/1.14.6/byte-buddy-1.14.6.jar", | ||
), | ||
JarLibraryDescriptor( | ||
"byte-buddy-agent-1.14.6.jar", | ||
"https://repo1.maven.org/maven2/net/bytebuddy/byte-buddy-agent/1.14.6/byte-buddy-agent-1.14.6.jar", | ||
), | ||
) | ||
} | ||
} |
32 changes: 32 additions & 0 deletions
32
...c/main/kotlin/org/jetbrains/research/testspark/core/test/java/JavaJUnitTestSuiteParser.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
package org.jetbrains.research.testspark.core.test.java | ||
|
||
import org.jetbrains.research.testspark.core.data.JUnitVersion | ||
import org.jetbrains.research.testspark.core.generation.llm.getPackageFromTestSuiteCode | ||
import org.jetbrains.research.testspark.core.test.SupportedLanguage | ||
import org.jetbrains.research.testspark.core.test.TestBodyPrinter | ||
import org.jetbrains.research.testspark.core.test.TestSuiteParser | ||
import org.jetbrains.research.testspark.core.test.data.TestSuiteGeneratedByLLM | ||
import org.jetbrains.research.testspark.core.test.strategies.JUnitTestSuiteParserStrategy | ||
import org.jetbrains.research.testspark.core.utils.javaImportPattern | ||
|
||
class JavaJUnitTestSuiteParser( | ||
private var packageName: String, | ||
private val junitVersion: JUnitVersion, | ||
private val testBodyPrinter: TestBodyPrinter, | ||
) : TestSuiteParser { | ||
override fun parseTestSuite(rawText: String): TestSuiteGeneratedByLLM? { | ||
val packageInsideTestText = getPackageFromTestSuiteCode(rawText, SupportedLanguage.Java) | ||
if (packageInsideTestText.isNotBlank()) { | ||
packageName = packageInsideTestText | ||
} | ||
|
||
return JUnitTestSuiteParserStrategy.parseJUnitTestSuite( | ||
rawText, | ||
junitVersion, | ||
javaImportPattern, | ||
packageName, | ||
testNamePattern = "void", | ||
testBodyPrinter, | ||
) | ||
} | ||
} |
40 changes: 40 additions & 0 deletions
40
core/src/main/kotlin/org/jetbrains/research/testspark/core/test/java/JavaTestBodyPrinter.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
package org.jetbrains.research.testspark.core.test.java | ||
|
||
import org.jetbrains.research.testspark.core.test.TestBodyPrinter | ||
import org.jetbrains.research.testspark.core.test.data.TestLine | ||
import org.jetbrains.research.testspark.core.test.data.TestLineType | ||
|
||
class JavaTestBodyPrinter : TestBodyPrinter { | ||
override fun printTestBody( | ||
testInitiatedText: String, | ||
lines: MutableList<TestLine>, | ||
throwsException: String, | ||
name: String, | ||
): String { | ||
var testFullText = testInitiatedText | ||
|
||
// start writing the test signature | ||
testFullText += "\n\tpublic void $name() " | ||
|
||
// add throws exception if exists | ||
if (throwsException.isNotBlank()) { | ||
testFullText += "throws $throwsException" | ||
} | ||
|
||
// start writing the test lines | ||
testFullText += "{\n" | ||
|
||
// write each line | ||
lines.forEach { line -> | ||
testFullText += when (line.type) { | ||
TestLineType.BREAK -> "\t\t\n" | ||
else -> "\t\t${line.text}\n" | ||
} | ||
} | ||
|
||
// close test case | ||
testFullText += "\t}\n" | ||
|
||
return testFullText | ||
} | ||
} |
53 changes: 53 additions & 0 deletions
53
core/src/main/kotlin/org/jetbrains/research/testspark/core/test/java/JavaTestCompiler.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
package org.jetbrains.research.testspark.core.test.java | ||
|
||
import io.github.oshai.kotlinlogging.KotlinLogging | ||
import org.jetbrains.research.testspark.core.test.TestCompiler | ||
import org.jetbrains.research.testspark.core.utils.CommandLineRunner | ||
import org.jetbrains.research.testspark.core.utils.DataFilesUtil | ||
import java.io.File | ||
|
||
class JavaTestCompiler( | ||
libPaths: List<String>, | ||
junitLibPaths: List<String>, | ||
private val javaHomeDirectoryPath: String, | ||
) : TestCompiler(libPaths, junitLibPaths) { | ||
|
||
private val log = KotlinLogging.logger { this::class.java } | ||
|
||
override fun compileCode(path: String, projectBuildPath: String): Pair<Boolean, String> { | ||
val classPaths = "\"${getClassPaths(projectBuildPath)}\"" | ||
// find the proper javac | ||
val javaCompile = File(javaHomeDirectoryPath).walk() | ||
.filter { | ||
val isCompilerName = | ||
if (DataFilesUtil.isWindows()) it.name.equals("javac.exe") else it.name.equals("javac") | ||
isCompilerName && it.isFile | ||
} | ||
.firstOrNull() | ||
|
||
if (javaCompile == null) { | ||
val msg = "Cannot find java compiler 'javac' at '$javaHomeDirectoryPath'" | ||
log.error { msg } | ||
throw RuntimeException(msg) | ||
} | ||
|
||
println("javac found at '${javaCompile.absolutePath}'") | ||
|
||
// compile file | ||
val errorMsg = CommandLineRunner.run( | ||
arrayListOf( | ||
javaCompile.absolutePath, | ||
"-cp", | ||
classPaths, | ||
path, | ||
), | ||
) | ||
|
||
log.info { "Error message: '$errorMsg'" } | ||
// create .class file path | ||
val classFilePath = path.replace(".java", ".class") | ||
|
||
// check is .class file exists | ||
return Pair(File(classFilePath).exists(), errorMsg) | ||
} | ||
} |
32 changes: 32 additions & 0 deletions
32
...in/kotlin/org/jetbrains/research/testspark/core/test/kotlin/KotlinJUnitTestSuiteParser.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
package org.jetbrains.research.testspark.core.test.kotlin | ||
|
||
import org.jetbrains.research.testspark.core.data.JUnitVersion | ||
import org.jetbrains.research.testspark.core.generation.llm.getPackageFromTestSuiteCode | ||
import org.jetbrains.research.testspark.core.test.SupportedLanguage | ||
import org.jetbrains.research.testspark.core.test.TestBodyPrinter | ||
import org.jetbrains.research.testspark.core.test.TestSuiteParser | ||
import org.jetbrains.research.testspark.core.test.data.TestSuiteGeneratedByLLM | ||
import org.jetbrains.research.testspark.core.test.strategies.JUnitTestSuiteParserStrategy | ||
import org.jetbrains.research.testspark.core.utils.kotlinImportPattern | ||
|
||
class KotlinJUnitTestSuiteParser( | ||
private var packageName: String, | ||
private val junitVersion: JUnitVersion, | ||
private val testBodyPrinter: TestBodyPrinter, | ||
) : TestSuiteParser { | ||
override fun parseTestSuite(rawText: String): TestSuiteGeneratedByLLM? { | ||
val packageInsideTestText = getPackageFromTestSuiteCode(rawText, SupportedLanguage.Kotlin) | ||
if (packageInsideTestText.isNotBlank()) { | ||
packageName = packageInsideTestText | ||
} | ||
|
||
return JUnitTestSuiteParserStrategy.parseJUnitTestSuite( | ||
rawText, | ||
junitVersion, | ||
kotlinImportPattern, | ||
packageName, | ||
testNamePattern = "fun", | ||
testBodyPrinter, | ||
) | ||
} | ||
} |
40 changes: 40 additions & 0 deletions
40
...rc/main/kotlin/org/jetbrains/research/testspark/core/test/kotlin/KotlinTestBodyPrinter.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
package org.jetbrains.research.testspark.core.test.kotlin | ||
|
||
import org.jetbrains.research.testspark.core.test.TestBodyPrinter | ||
import org.jetbrains.research.testspark.core.test.data.TestLine | ||
import org.jetbrains.research.testspark.core.test.data.TestLineType | ||
|
||
class KotlinTestBodyPrinter : TestBodyPrinter { | ||
override fun printTestBody( | ||
testInitiatedText: String, | ||
lines: MutableList<TestLine>, | ||
throwsException: String, | ||
name: String, | ||
): String { | ||
var testFullText = testInitiatedText | ||
|
||
// start writing the test signature | ||
testFullText += "\n\tfun $name() " | ||
|
||
// add throws exception if exists | ||
if (throwsException.isNotBlank()) { | ||
testFullText += "throws $throwsException" | ||
} | ||
|
||
// start writing the test lines | ||
testFullText += "{\n" | ||
|
||
// write each line | ||
lines.forEach { line -> | ||
testFullText += when (line.type) { | ||
TestLineType.BREAK -> "\t\t\n" | ||
else -> "\t\t${line.text}\n" | ||
} | ||
} | ||
|
||
// close test case | ||
testFullText += "\t}\n" | ||
|
||
return testFullText | ||
} | ||
} |
31 changes: 31 additions & 0 deletions
31
core/src/main/kotlin/org/jetbrains/research/testspark/core/test/kotlin/KotlinTestCompiler.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
package org.jetbrains.research.testspark.core.test.kotlin | ||
|
||
import io.github.oshai.kotlinlogging.KotlinLogging | ||
import org.jetbrains.research.testspark.core.test.TestCompiler | ||
import org.jetbrains.research.testspark.core.utils.CommandLineRunner | ||
|
||
class KotlinTestCompiler(libPaths: List<String>, junitLibPaths: List<String>) : | ||
TestCompiler(libPaths, junitLibPaths) { | ||
|
||
private val log = KotlinLogging.logger { this::class.java } | ||
|
||
override fun compileCode(path: String, projectBuildPath: String): Pair<Boolean, String> { | ||
log.info { "[KotlinTestCompiler] Compiling ${path.substringAfterLast('/')}" } | ||
|
||
val classPaths = "\"${getClassPaths(projectBuildPath)}\"" | ||
// Compile file | ||
val errorMsg = CommandLineRunner.run( | ||
arrayListOf( | ||
"kotlinc", | ||
"-cp", | ||
classPaths, | ||
path, | ||
), | ||
) | ||
|
||
log.info { "Error message: '$errorMsg'" } | ||
|
||
// No need to save the .class file for kotlin, so checking the error message is enough | ||
return Pair(errorMsg.isBlank(), errorMsg) | ||
} | ||
} |
Oops, something went wrong.