Skip to content

Commit 61c2b42

Browse files
committed
Fix code generator pipeline for cases when util class is generated separately
1 parent 39e77be commit 61c2b42

File tree

4 files changed

+56
-21
lines changed

4 files changed

+56
-21
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/main/kotlin/org/utbot/tests/infrastructure/CompilationAndRunUtils.kt

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ package org.utbot.tests.infrastructure
33
import org.utbot.framework.plugin.api.CodegenLanguage
44
import java.io.File
55
import java.nio.file.Path
6-
import mu.KotlinLogging
76
import org.utbot.common.FileUtil
87
import org.utbot.engine.logger
98
import org.utbot.framework.codegen.Junit5
@@ -15,6 +14,13 @@ data class ClassUnderTest(
1514
val generatedTestFile: File
1615
)
1716

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+
1824
fun writeTest(
1925
testContents: String,
2026
testClassName: String,
@@ -27,13 +33,10 @@ fun writeTest(
2733
File(buildDirectory.toFile(), "${testClassName.substringAfterLast(".")}${generatedLanguage.extension}")
2834
)
2935

30-
val targetDir = classUnderTest.generatedTestFile.parentFile
31-
targetDir.mkdirs()
3236
logger.info {
3337
"File size for ${classUnderTest.testClassSimpleName}: ${FileUtil.byteCountToDisplaySize(testContents.length.toLong())}"
3438
}
35-
classUnderTest.generatedTestFile.writeText(testContents)
36-
return classUnderTest.generatedTestFile
39+
return writeFile(testContents, classUnderTest.generatedTestFile)
3740
}
3841

3942
fun compileTests(

utbot-framework/src/main/kotlin/org/utbot/tests/infrastructure/TestCodeGeneratorPipeline.kt

Lines changed: 41 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ import org.utbot.framework.codegen.ParametrizedTestSource
1010
import org.utbot.framework.codegen.StaticsMocking
1111
import org.utbot.framework.codegen.TestFramework
1212
import org.utbot.framework.codegen.model.CodeGenerator
13+
import org.utbot.framework.codegen.model.CodeGeneratorResult
14+
import org.utbot.framework.codegen.model.UtilClassKind
15+
import org.utbot.framework.codegen.model.UtilClassKind.Companion.UT_UTILS_CLASS_NAME
1316
import org.utbot.framework.plugin.api.CodegenLanguage
1417
import org.utbot.framework.plugin.api.ExecutableId
1518
import org.utbot.framework.plugin.api.MockFramework
@@ -19,6 +22,8 @@ import org.utbot.framework.plugin.api.util.UtContext
1922
import org.utbot.framework.plugin.api.util.description
2023
import org.utbot.framework.plugin.api.util.id
2124
import org.utbot.framework.plugin.api.util.withUtContext
25+
import java.io.File
26+
import java.nio.file.Path
2227
import kotlin.reflect.KClass
2328

2429
private val logger = KotlinLogging.logger {}
@@ -75,7 +80,8 @@ class TestCodeGeneratorPipeline(private val testFrameworkConfiguration: TestFram
7580
val codegenLanguage = testFrameworkConfiguration.codegenLanguage
7681
val parametrizedTestSource = testFrameworkConfiguration.parametrizedTestSource
7782

78-
val testClass = callToCodeGenerator(testSets, classUnderTest)
83+
val codeGenerationResult = callToCodeGenerator(testSets, classUnderTest)
84+
val testClass = codeGenerationResult.generatedCode
7985

8086
// actual number of the tests in the generated testClass
8187
val generatedMethodsCount = testClass
@@ -149,17 +155,33 @@ class TestCodeGeneratorPipeline(private val testFrameworkConfiguration: TestFram
149155

150156
val testClassName = classPipeline.retrieveTestClassName("BrokenGeneratedTest")
151157
val generatedTestFile = writeTest(testClass, testClassName, buildDirectory, codegenLanguage)
158+
val generatedUtilClassFile = codeGenerationResult.utilClassKind?.writeUtilClassToFile(buildDirectory, codegenLanguage)
152159

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

156166
throw it
157167
}
158168

159-
classPipeline.stageContext = copy(data = testClass, stages = stages + information.completeStage())
169+
classPipeline.stageContext = copy(data = codeGenerationResult, stages = stages + information.completeStage())
160170
}
161171
}
162172

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

171193
val testClassesNamesToTestGeneratedTests = classesPipelines.map { classPipeline ->
172-
val testClass = classPipeline.stageContext.data as String
194+
val codeGeneratorResult = classPipeline.stageContext.data as CodeGeneratorResult//String
195+
val testClass = codeGeneratorResult.generatedCode
196+
173197
val testClassName = classPipeline.retrieveTestClassName("GeneratedTest")
174198
val generatedTestFile = writeTest(testClass, testClassName, buildDirectory, codegenLanguage)
199+
val generatedUtilClassFile = codeGeneratorResult.utilClassKind?.writeUtilClassToFile(buildDirectory, codegenLanguage)
175200

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

178-
testClassName to generatedTestFile
206+
GeneratedTestClassInfo(testClassName, generatedTestFile, generatedUtilClassFile)
179207
}
180208

209+
val sourceFiles = mutableListOf<String>().apply {
210+
this += testClassesNamesToTestGeneratedTests.map { it.generatedTestFile.absolutePath }
211+
this += testClassesNamesToTestGeneratedTests.mapNotNull { it.generatedUtilClassFile?.absolutePath }
212+
}
181213
compileTests(
182214
"$buildDirectory",
183-
testClassesNamesToTestGeneratedTests.map { it.second.absolutePath },
215+
sourceFiles,
184216
codegenLanguage
185217
)
186218

187-
testClassesNamesToTestGeneratedTests.zip(classesPipelines) { testClassNameToTest, classPipeline ->
219+
testClassesNamesToTestGeneratedTests.zip(classesPipelines) { generatedTestClassInfo, classPipeline ->
188220
classPipeline.stageContext = classPipeline.stageContext.copy(
189-
data = CompilationResult("$buildDirectory", testClassNameToTest.first),
221+
data = CompilationResult("$buildDirectory", generatedTestClassInfo.testClassName),
190222
stages = classPipeline.stageContext.stages + information.completeStage()
191223
)
192224
}
@@ -224,7 +256,7 @@ class TestCodeGeneratorPipeline(private val testFrameworkConfiguration: TestFram
224256
private fun callToCodeGenerator(
225257
testSets: List<UtMethodTestSet>,
226258
classUnderTest: KClass<*>
227-
): String {
259+
): CodeGeneratorResult {
228260
val params = mutableMapOf<ExecutableId, List<String>>()
229261

230262
val codeGenerator = with(testFrameworkConfiguration) {
@@ -244,7 +276,7 @@ class TestCodeGeneratorPipeline(private val testFrameworkConfiguration: TestFram
244276
}
245277
val testClassCustomName = "${classUnderTest.java.simpleName}GeneratedTest"
246278

247-
return codeGenerator.generateAsString(testSets, testClassCustomName)
279+
return codeGenerator.generateAsStringWithTestReport(testSets, testClassCustomName)
248280
}
249281

250282
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
@@ -58,7 +58,7 @@ import org.utbot.framework.codegen.ParametrizedTestSource
5858
import org.utbot.framework.codegen.RegularImport
5959
import org.utbot.framework.codegen.StaticImport
6060
import org.utbot.framework.codegen.model.CodeGenerator
61-
import org.utbot.framework.codegen.model.CodeGenerationResult
61+
import org.utbot.framework.codegen.model.CodeGeneratorResult
6262
import org.utbot.framework.codegen.model.UtilClassKind
6363
import org.utbot.framework.codegen.model.UtilClassKind.Companion.UT_UTILS_CLASS_NAME
6464
import org.utbot.framework.codegen.model.constructor.tree.TestsGenerationReport
@@ -98,7 +98,7 @@ object CodeGenerationController {
9898
var requiredUtilClassKind: UtilClassKind? = null
9999
var mockFrameworkUsed: Boolean = false
100100

101-
fun onTestClassGenerated(result: CodeGenerationResult) {
101+
fun onTestClassGenerated(result: CodeGeneratorResult) {
102102
requiredUtilClassKind = maxOfNullable(requiredUtilClassKind, result.utilClassKind)
103103
mockFrameworkUsed = maxOf(mockFrameworkUsed, result.mockFrameworkUsed)
104104
}
@@ -623,7 +623,7 @@ object CodeGenerationController {
623623
testClass: PsiClass,
624624
testSets: List<UtMethodTestSet>,
625625
model: GenerateTestsModel,
626-
testsCodeWithTestReport: CodeGenerationResult,
626+
testsCodeWithTestReport: CodeGeneratorResult,
627627
) {
628628
val project = model.project
629629
val generatedTestsCode = testsCodeWithTestReport.generatedCode

0 commit comments

Comments
 (0)