Skip to content

Commit d5e9d50

Browse files
committed
Fix code generator pipeline for cases when util class is generated separately
1 parent d8d40f9 commit d5e9d50

File tree

4 files changed

+56
-20
lines changed

4 files changed

+56
-20
lines changed

utbot-framework/src/main/kotlin/org/utbot/framework/codegen/model/CodeGenerator.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -65,19 +65,19 @@ class CodeGenerator(
6565
fun generateAsStringWithTestReport(
6666
testSets: Collection<UtMethodTestSet>,
6767
testClassCustomName: String? = null,
68-
): CodeGenerationResult {
68+
): CodeGeneratorResult {
6969
val cgTestSets = testSets.map { CgMethodTestSet(it) }.toList()
7070
return generateAsStringWithTestReport(cgTestSets, testClassCustomName)
7171
}
7272

7373
private fun generateAsStringWithTestReport(
7474
cgTestSets: List<CgMethodTestSet>,
7575
testClassCustomName: String? = null,
76-
): CodeGenerationResult = withCustomContext(testClassCustomName) {
76+
): CodeGeneratorResult = withCustomContext(testClassCustomName) {
7777
context.withTestClassFileScope {
7878
val testClassModel = TestClassModel.fromTestSets(classUnderTest, cgTestSets)
7979
val testClassFile = CgTestClassConstructor(context).construct(testClassModel)
80-
CodeGenerationResult(
80+
CodeGeneratorResult(
8181
generatedCode = renderClassFile(testClassFile),
8282
utilClassKind = UtilClassKind.fromCgContextOrNull(context),
8383
testsGenerationReport = testClassFile.testsGenerationReport,
@@ -117,7 +117,7 @@ class CodeGenerator(
117117
* @property testsGenerationReport some info about test generation process
118118
* @property mockFrameworkUsed flag indicating whether any mock objects have been created during code generation ot not
119119
*/
120-
data class CodeGenerationResult(
120+
data class CodeGeneratorResult(
121121
val generatedCode: String,
122122
// null if no util class needed, e.g. when we are generating utils directly into test class
123123
val utilClassKind: UtilClassKind?,

utbot-framework/src/test/kotlin/org/utbot/framework/codegen/CompilationAndRunUtils.kt

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,13 @@ data class ClassUnderTest(
1414

1515
private val logger = KotlinLogging.logger {}
1616

17+
fun writeFile(fileContents: String, targetFile: File): File {
18+
val targetDir = targetFile.parentFile
19+
targetDir.mkdirs()
20+
targetFile.writeText(fileContents)
21+
return targetFile
22+
}
23+
1724
fun writeTest(
1825
testContents: String,
1926
testClassName: String,
@@ -26,13 +33,10 @@ fun writeTest(
2633
File(buildDirectory.toFile(), "${testClassName.substringAfterLast(".")}${generatedLanguage.extension}")
2734
)
2835

29-
val targetDir = classUnderTest.generatedTestFile.parentFile
30-
targetDir.mkdirs()
3136
logger.info {
3237
"File size for ${classUnderTest.testClassSimpleName}: ${FileUtil.byteCountToDisplaySize(testContents.length.toLong())}"
3338
}
34-
classUnderTest.generatedTestFile.writeText(testContents)
35-
return classUnderTest.generatedTestFile
39+
return writeFile(testContents, classUnderTest.generatedTestFile)
3640
}
3741

3842
fun compileTests(

utbot-framework/src/test/kotlin/org/utbot/framework/codegen/TestCodeGeneratorPipeline.kt

Lines changed: 41 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ import org.utbot.common.packageName
99
import org.utbot.examples.TestFrameworkConfiguration
1010
import org.utbot.framework.codegen.ExecutionStatus.SUCCESS
1111
import org.utbot.framework.codegen.model.CodeGenerator
12+
import org.utbot.framework.codegen.model.CodeGeneratorResult
13+
import org.utbot.framework.codegen.model.UtilClassKind
14+
import org.utbot.framework.codegen.model.UtilClassKind.Companion.UT_UTILS_CLASS_NAME
1215
import org.utbot.framework.plugin.api.CodegenLanguage
1316
import org.utbot.framework.plugin.api.ExecutableId
1417
import org.utbot.framework.plugin.api.MockFramework
@@ -18,6 +21,8 @@ import org.utbot.framework.plugin.api.util.UtContext
1821
import org.utbot.framework.plugin.api.util.description
1922
import org.utbot.framework.plugin.api.util.id
2023
import org.utbot.framework.plugin.api.util.withUtContext
24+
import java.io.File
25+
import java.nio.file.Path
2126
import kotlin.reflect.KClass
2227

2328
private val logger = KotlinLogging.logger {}
@@ -74,7 +79,8 @@ class TestCodeGeneratorPipeline(private val testFrameworkConfiguration: TestFram
7479
val codegenLanguage = testFrameworkConfiguration.codegenLanguage
7580
val parametrizedTestSource = testFrameworkConfiguration.parametrizedTestSource
7681

77-
val testClass = callToCodeGenerator(testSets, classUnderTest)
82+
val codeGenerationResult = callToCodeGenerator(testSets, classUnderTest)
83+
val testClass = codeGenerationResult.generatedCode
7884

7985
// actual number of the tests in the generated testClass
8086
val generatedMethodsCount = testClass
@@ -148,17 +154,33 @@ class TestCodeGeneratorPipeline(private val testFrameworkConfiguration: TestFram
148154

149155
val testClassName = classPipeline.retrieveTestClassName("BrokenGeneratedTest")
150156
val generatedTestFile = writeTest(testClass, testClassName, buildDirectory, codegenLanguage)
157+
val generatedUtilClassFile = codeGenerationResult.utilClassKind?.writeUtilClassToFile(buildDirectory, codegenLanguage)
151158

152159
logger.error("Broken test has been written to the file: [$generatedTestFile]")
160+
if (generatedUtilClassFile != null) {
161+
logger.error("Util class for the broken test has been written to the file: [$generatedUtilClassFile]")
162+
}
153163
logger.error("Failed configuration: $testFrameworkConfiguration")
154164

155165
throw it
156166
}
157167

158-
classPipeline.stageContext = copy(data = testClass, stages = stages + information.completeStage())
168+
classPipeline.stageContext = copy(data = codeGenerationResult, stages = stages + information.completeStage())
159169
}
160170
}
161171

172+
private fun UtilClassKind.writeUtilClassToFile(buildDirectory: Path, language: CodegenLanguage): File {
173+
val utilClassFile = File(buildDirectory.toFile(), "$UT_UTILS_CLASS_NAME${language.extension}")
174+
val utilClassText = getUtilClassText(language)
175+
return writeFile(utilClassText, utilClassFile)
176+
}
177+
178+
private data class GeneratedTestClassInfo(
179+
val testClassName: String,
180+
val generatedTestFile: File,
181+
val generatedUtilClassFile: File?
182+
)
183+
162184
@Suppress("UNCHECKED_CAST")
163185
private fun processCompilationStages(classesPipelines: List<ClassPipeline>) {
164186
val information = StageExecutionInformation(Compilation)
@@ -168,24 +190,34 @@ class TestCodeGeneratorPipeline(private val testFrameworkConfiguration: TestFram
168190
val codegenLanguage = testFrameworkConfiguration.codegenLanguage
169191

170192
val testClassesNamesToTestGeneratedTests = classesPipelines.map { classPipeline ->
171-
val testClass = classPipeline.stageContext.data as String
193+
val codeGeneratorResult = classPipeline.stageContext.data as CodeGeneratorResult//String
194+
val testClass = codeGeneratorResult.generatedCode
195+
172196
val testClassName = classPipeline.retrieveTestClassName("GeneratedTest")
173197
val generatedTestFile = writeTest(testClass, testClassName, buildDirectory, codegenLanguage)
198+
val generatedUtilClassFile = codeGeneratorResult.utilClassKind?.writeUtilClassToFile(buildDirectory, codegenLanguage)
174199

175200
logger.info("Test has been written to the file: [$generatedTestFile]")
201+
if (generatedUtilClassFile != null) {
202+
logger.info("Util class for the test has been written to the file: [$generatedUtilClassFile]")
203+
}
176204

177-
testClassName to generatedTestFile
205+
GeneratedTestClassInfo(testClassName, generatedTestFile, generatedUtilClassFile)
178206
}
179207

208+
val sourceFiles = mutableListOf<String>().apply {
209+
this += testClassesNamesToTestGeneratedTests.map { it.generatedTestFile.absolutePath }
210+
this += testClassesNamesToTestGeneratedTests.mapNotNull { it.generatedUtilClassFile?.absolutePath }
211+
}
180212
compileTests(
181213
"$buildDirectory",
182-
testClassesNamesToTestGeneratedTests.map { it.second.absolutePath },
214+
sourceFiles,
183215
codegenLanguage
184216
)
185217

186-
testClassesNamesToTestGeneratedTests.zip(classesPipelines) { testClassNameToTest, classPipeline ->
218+
testClassesNamesToTestGeneratedTests.zip(classesPipelines) { generatedTestClassInfo, classPipeline ->
187219
classPipeline.stageContext = classPipeline.stageContext.copy(
188-
data = CompilationResult("$buildDirectory", testClassNameToTest.first),
220+
data = CompilationResult("$buildDirectory", generatedTestClassInfo.testClassName),
189221
stages = classPipeline.stageContext.stages + information.completeStage()
190222
)
191223
}
@@ -223,7 +255,7 @@ class TestCodeGeneratorPipeline(private val testFrameworkConfiguration: TestFram
223255
private fun callToCodeGenerator(
224256
testSets: List<UtMethodTestSet>,
225257
classUnderTest: KClass<*>
226-
): String {
258+
): CodeGeneratorResult {
227259
val params = mutableMapOf<ExecutableId, List<String>>()
228260

229261
val codeGenerator = with(testFrameworkConfiguration) {
@@ -243,7 +275,7 @@ class TestCodeGeneratorPipeline(private val testFrameworkConfiguration: TestFram
243275
}
244276
val testClassCustomName = "${classUnderTest.java.simpleName}GeneratedTest"
245277

246-
return codeGenerator.generateAsString(testSets, testClassCustomName)
278+
return codeGenerator.generateAsStringWithTestReport(testSets, testClassCustomName)
247279
}
248280

249281
private fun checkPipelinesResults(classesPipelines: List<ClassPipeline>) {

utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/generator/CodeGenerationController.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ import org.utbot.framework.codegen.ParametrizedTestSource
5757
import org.utbot.framework.codegen.RegularImport
5858
import org.utbot.framework.codegen.StaticImport
5959
import org.utbot.framework.codegen.model.CodeGenerator
60-
import org.utbot.framework.codegen.model.CodeGenerationResult
60+
import org.utbot.framework.codegen.model.CodeGeneratorResult
6161
import org.utbot.framework.codegen.model.UtilClassKind
6262
import org.utbot.framework.codegen.model.UtilClassKind.Companion.UT_UTILS_CLASS_NAME
6363
import org.utbot.framework.codegen.model.constructor.tree.TestsGenerationReport
@@ -96,7 +96,7 @@ object CodeGenerationController {
9696
var requiredUtilClassKind: UtilClassKind? = null
9797
var mockFrameworkUsed: Boolean = false
9898

99-
fun onTestClassGenerated(result: CodeGenerationResult) {
99+
fun onTestClassGenerated(result: CodeGeneratorResult) {
100100
requiredUtilClassKind = maxOfNullable(requiredUtilClassKind, result.utilClassKind)
101101
mockFrameworkUsed = maxOf(mockFrameworkUsed, result.mockFrameworkUsed)
102102
}
@@ -615,7 +615,7 @@ object CodeGenerationController {
615615
testClass: PsiClass,
616616
testSets: List<UtMethodTestSet>,
617617
model: GenerateTestsModel,
618-
testsCodeWithTestReport: CodeGenerationResult,
618+
testsCodeWithTestReport: CodeGeneratorResult,
619619
) {
620620
val project = model.project
621621
val generatedTestsCode = testsCodeWithTestReport.generatedCode

0 commit comments

Comments
 (0)