diff --git a/docs/UnitTestBotDecomposition.md b/docs/UnitTestBotDecomposition.md index f3f2c552be..ac118e9036 100644 --- a/docs/UnitTestBotDecomposition.md +++ b/docs/UnitTestBotDecomposition.md @@ -59,7 +59,9 @@ We use an outdated approach with the [Soot](https://github.com/soot-oss/soot) fr The current domain of code generation is specific for generating tests, though it could be reused for other purposes. Currently, the engine can be used to generate tests for different test frameworks. One can use the code generator to generate test templates inside the IntelliJ-based IDEs. Entry and exit point: -`org.utbot.framework.codegen.CodeGenerator#generateAsStringWithTestReport` +`org.utbot.framework.codegen.generator.CodeGenerator#generateAsStringWithTestReport` + +Note that for Spring projects `SpringCodeGenerator` is used. It supports both unit and integration tests generation. ## SARIF report visualizer diff --git a/utbot-cli/src/main/kotlin/org/utbot/cli/GenerateTestsAbstractCommand.kt b/utbot-cli/src/main/kotlin/org/utbot/cli/GenerateTestsAbstractCommand.kt index 8bf70f17bf..0dbf64819b 100644 --- a/utbot-cli/src/main/kotlin/org/utbot/cli/GenerateTestsAbstractCommand.kt +++ b/utbot-cli/src/main/kotlin/org/utbot/cli/GenerateTestsAbstractCommand.kt @@ -16,13 +16,13 @@ import org.utbot.common.PathUtil.toURL import org.utbot.common.toPath import org.utbot.engine.Mocker import org.utbot.framework.UtSettings -import org.utbot.framework.codegen.CodeGenerator import org.utbot.framework.codegen.domain.ForceStaticMocking import org.utbot.framework.codegen.domain.MockitoStaticMocking import org.utbot.framework.codegen.domain.NoStaticMocking import org.utbot.framework.codegen.domain.ProjectType import org.utbot.framework.codegen.domain.StaticsMocking import org.utbot.framework.codegen.domain.testFrameworkByName +import org.utbot.framework.codegen.generator.CodeGenerator import org.utbot.framework.codegen.services.language.CgLanguageAssistant import org.utbot.framework.plugin.api.ClassId import org.utbot.framework.plugin.api.CodegenLanguage diff --git a/utbot-framework-api/src/main/kotlin/org/utbot/framework/plugin/api/Api.kt b/utbot-framework-api/src/main/kotlin/org/utbot/framework/plugin/api/Api.kt index b5454a18c3..eb837766d6 100644 --- a/utbot-framework-api/src/main/kotlin/org/utbot/framework/plugin/api/Api.kt +++ b/utbot-framework-api/src/main/kotlin/org/utbot/framework/plugin/api/Api.kt @@ -1341,7 +1341,7 @@ class SpringApplicationContext( ): Boolean = field.fieldId in classUnderTest.allDeclaredFieldIds && field.declaringClass.id !in springInjectedClasses } -enum class SpringTestType( +enum class SpringTestsType( override val id: String, override val displayName: String, override val description: String, @@ -1363,7 +1363,7 @@ enum class SpringTestType( companion object : CodeGenerationSettingBox { override val defaultItem = UNIT_TESTS - override val allItems: List = values().toList() + override val allItems: List = values().toList() } } diff --git a/utbot-framework/src/main/kotlin/org/utbot/external/api/UtBotJavaApi.kt b/utbot-framework/src/main/kotlin/org/utbot/external/api/UtBotJavaApi.kt index 23f7195a20..1036f927ac 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/external/api/UtBotJavaApi.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/external/api/UtBotJavaApi.kt @@ -3,13 +3,13 @@ package org.utbot.external.api import org.utbot.common.FileUtil import org.utbot.common.nameOfPackage import org.utbot.framework.UtSettings -import org.utbot.framework.codegen.CodeGenerator import org.utbot.framework.codegen.domain.ForceStaticMocking import org.utbot.framework.codegen.domain.Junit5 import org.utbot.framework.codegen.domain.NoStaticMocking import org.utbot.framework.codegen.domain.ProjectType import org.utbot.framework.codegen.domain.StaticsMocking import org.utbot.framework.codegen.domain.TestFramework +import org.utbot.framework.codegen.generator.CodeGenerator import org.utbot.framework.codegen.services.language.CgLanguageAssistant import org.utbot.instrumentation.instrumentation.execution.UtConcreteExecutionData import org.utbot.instrumentation.instrumentation.execution.UtConcreteExecutionResult diff --git a/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/domain/builtin/SpringBuiltins.kt b/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/domain/builtin/SpringBuiltins.kt new file mode 100644 index 0000000000..aa2bcbced7 --- /dev/null +++ b/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/domain/builtin/SpringBuiltins.kt @@ -0,0 +1,8 @@ +package org.utbot.framework.codegen.domain.builtin + +import org.utbot.framework.plugin.api.BuiltinClassId + +internal val autowiredClassId = BuiltinClassId( + canonicalName = "org.springframework.beans.factory.annotation", + simpleName = "Autowired", +) \ No newline at end of file diff --git a/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/domain/models/TestClassModel.kt b/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/domain/models/TestClassModel.kt index adc2cb074d..893c7e1946 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/domain/models/TestClassModel.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/domain/models/TestClassModel.kt @@ -1,6 +1,6 @@ package org.utbot.framework.codegen.domain.models -import org.utbot.framework.codegen.domain.UtModelWrapper +import org.utbot.framework.codegen.domain.models.builders.TypedModelWrappers import org.utbot.framework.plugin.api.ClassId /** @@ -30,7 +30,7 @@ class SpringTestClassModel( classUnderTest: ClassId, methodTestSets: List, nestedClasses: List, - val injectedMockModels: Map> = mapOf(), - val mockedModels: Map> = mapOf(), + val thisInstanceModels: TypedModelWrappers = mapOf(), + val thisInstanceDependentMocks: TypedModelWrappers = mapOf(), ): TestClassModel(classUnderTest, methodTestSets, nestedClasses) diff --git a/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/domain/models/builders/SpringTestClassModelBuilder.kt b/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/domain/models/builders/SpringTestClassModelBuilder.kt index 2178ecab5e..13e0ec01c5 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/domain/models/builders/SpringTestClassModelBuilder.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/domain/models/builders/SpringTestClassModelBuilder.kt @@ -19,23 +19,25 @@ import org.utbot.framework.plugin.api.UtPrimitiveModel import org.utbot.framework.plugin.api.UtVoidModel import org.utbot.framework.plugin.api.isMockModel +typealias TypedModelWrappers = Map> + class SpringTestClassModelBuilder(val context: CgContext): TestClassModelBuilder() { override fun createTestClassModel(classUnderTest: ClassId, testSets: List): SpringTestClassModel { val baseModel = SimpleTestClassModelBuilder(context).createTestClassModel(classUnderTest, testSets) - val (injectedModels, mockedModels) = collectInjectedAndMockedModels(testSets) + val (thisInstanceModels, dependentMockModels) = collectThisInstanceAndDependentModels(testSets) return SpringTestClassModel( classUnderTest = baseModel.classUnderTest, methodTestSets = baseModel.methodTestSets, nestedClasses = baseModel.nestedClasses, - injectedMockModels = injectedModels, - mockedModels = mockedModels + thisInstanceModels = thisInstanceModels, + thisInstanceDependentMocks = dependentMockModels ) } - private fun collectInjectedAndMockedModels(testSets: List): Pair>, Map>> { - val thisInstances = mutableSetOf() + private fun collectThisInstanceAndDependentModels(testSets: List): Pair { + val thisInstanceModels = mutableSetOf() val thisInstancesDependentModels = mutableSetOf() with(context) { @@ -46,7 +48,7 @@ class SpringTestClassModelBuilder(val context: CgContext): TestClassModelBuilder setOf(execution.stateBefore.thisInstance, execution.stateAfter.thisInstance) .filterNotNull() .forEach { model -> - thisInstances += model.wrap() + thisInstanceModels += model.wrap() thisInstancesDependentModels += collectByThisInstanceModel(model) } } @@ -58,10 +60,10 @@ class SpringTestClassModelBuilder(val context: CgContext): TestClassModelBuilder val dependentMockModels = thisInstancesDependentModels .filterTo(mutableSetOf()) { cgModel -> - cgModel.model.isMockModel() && cgModel !in thisInstances + cgModel.model.isMockModel() && cgModel !in thisInstanceModels } - return thisInstances.groupByClassId() to dependentMockModels.groupByClassId() + return thisInstanceModels.groupByClassId() to dependentMockModels.groupByClassId() } private fun collectByThisInstanceModel(model: UtModel): Set { @@ -71,7 +73,7 @@ class SpringTestClassModelBuilder(val context: CgContext): TestClassModelBuilder return dependentModels } - private fun Set.groupByClassId(): Map> { + private fun Set.groupByClassId(): TypedModelWrappers { val classModels = mutableMapOf>() for (modelGroup in this.groupBy { it.model.classId }) { diff --git a/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/CodeGenerator.kt b/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/generator/AbstractCodeGenerator.kt similarity index 59% rename from utbot-framework/src/main/kotlin/org/utbot/framework/codegen/CodeGenerator.kt rename to utbot-framework/src/main/kotlin/org/utbot/framework/codegen/generator/AbstractCodeGenerator.kt index 72cbd385a5..dca05eed0e 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/CodeGenerator.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/generator/AbstractCodeGenerator.kt @@ -1,25 +1,18 @@ -package org.utbot.framework.codegen +package org.utbot.framework.codegen.generator import mu.KotlinLogging import org.utbot.framework.codegen.domain.ForceStaticMocking import org.utbot.framework.codegen.domain.HangingTestsTimeout import org.utbot.framework.codegen.domain.ParametrizedTestSource import org.utbot.framework.codegen.domain.ProjectType -import org.utbot.framework.codegen.domain.ProjectType.* import org.utbot.framework.codegen.domain.RuntimeExceptionTestsBehaviour import org.utbot.framework.codegen.domain.StaticsMocking import org.utbot.framework.codegen.domain.TestFramework -import org.utbot.framework.codegen.domain.models.CgMethodTestSet import org.utbot.framework.codegen.domain.context.CgContext import org.utbot.framework.codegen.domain.models.CgClassFile -import org.utbot.framework.codegen.domain.models.builders.SimpleTestClassModelBuilder -import org.utbot.framework.codegen.domain.models.builders.SpringTestClassModelBuilder +import org.utbot.framework.codegen.domain.models.CgMethodTestSet import org.utbot.framework.codegen.renderer.CgAbstractRenderer -import org.utbot.framework.codegen.reports.TestsGenerationReport -import org.utbot.framework.codegen.tree.CgSimpleTestClassConstructor -import org.utbot.framework.codegen.tree.ututils.UtilClassKind import org.utbot.framework.codegen.services.language.CgLanguageAssistant -import org.utbot.framework.codegen.tree.CgSpringTestClassConstructor import org.utbot.framework.plugin.api.ClassId import org.utbot.framework.plugin.api.CodegenLanguage import org.utbot.framework.plugin.api.ExecutableId @@ -28,9 +21,9 @@ import org.utbot.framework.plugin.api.UtMethodTestSet import java.time.LocalDateTime import java.time.format.DateTimeFormatter -open class CodeGenerator( - val classUnderTest: ClassId, - val projectType: ProjectType, +abstract class AbstractCodeGenerator( + classUnderTest: ClassId, + projectType: ProjectType, paramNames: MutableMap> = mutableMapOf(), generateUtilClassFile: Boolean = false, testFramework: TestFramework = TestFramework.defaultItem, @@ -46,8 +39,7 @@ open class CodeGenerator( enableTestsTimeout: Boolean = true, testClassPackageName: String = classUnderTest.packageName, ) { - - private val logger = KotlinLogging.logger {} + protected val logger = KotlinLogging.logger {} open var context: CgContext = CgContext( classUnderTest = classUnderTest, @@ -80,49 +72,14 @@ open class CodeGenerator( val cgTestSets = testSets.map { CgMethodTestSet(it) }.toList() return withCustomContext(testClassCustomName) { context.withTestClassFileScope { - when (context.projectType) { - Spring -> generateForSpringClass(cgTestSets) - else -> generateForSimpleClass(cgTestSets) - } + generate(cgTestSets) } } } - private fun generateForSimpleClass(testSets: List): CodeGeneratorResult { - val astConstructor = CgSimpleTestClassConstructor(context) - val testClassModel = SimpleTestClassModelBuilder(context).createTestClassModel(classUnderTest, testSets) - - logger.info { "Code generation phase started at ${now()}" } - val testClassFile = astConstructor.construct(testClassModel) - logger.info { "Code generation phase finished at ${now()}" } - - val generatedCode = renderToString(testClassFile) - - return CodeGeneratorResult( - generatedCode = generatedCode, - utilClassKind = UtilClassKind.fromCgContextOrNull(context), - testsGenerationReport = astConstructor.testsGenerationReport - ) - } - - private fun generateForSpringClass(testSets: List): CodeGeneratorResult { - val astConstructor = CgSpringTestClassConstructor(context) - val testClassModel = SpringTestClassModelBuilder(context).createTestClassModel(classUnderTest, testSets) - - logger.info { "Code generation phase started at ${now()}" } - val testClassFile = astConstructor.construct(testClassModel) - logger.info { "Code generation phase finished at ${now()}" } + protected abstract fun generate(testSets: List): CodeGeneratorResult - val generatedCode = renderToString(testClassFile) - - return CodeGeneratorResult( - generatedCode = generatedCode, - utilClassKind = UtilClassKind.fromCgContextOrNull(context), - testsGenerationReport = astConstructor.testsGenerationReport - ) - } - - private fun renderToString(testClassFile: CgClassFile): String { + protected fun renderToString(testClassFile: CgClassFile): String { logger.info { "Rendering phase started at ${now()}" } val renderer = CgAbstractRenderer.makeRenderer(context) testClassFile.accept(renderer) @@ -131,7 +88,7 @@ open class CodeGenerator( return renderer.toString() } - private fun now() = LocalDateTime.now().format(DateTimeFormatter.ofPattern("HH:mm:ss.SSS")) + protected fun now(): String = LocalDateTime.now().format(DateTimeFormatter.ofPattern("HH:mm:ss.SSS")) /** * Wrapper function that configures context as needed for utbot-online: @@ -147,17 +104,4 @@ open class CodeGenerator( context = prevContext } } -} - -/** - * @property generatedCode the source code of the test class - * @property testsGenerationReport some info about test generation process - * @property utilClassKind the kind of util class if it is required, otherwise - null - */ -data class CodeGeneratorResult( - val generatedCode: String, - val testsGenerationReport: TestsGenerationReport, - // null if no util class needed, e.g. when we are generating utils directly into test class - val utilClassKind: UtilClassKind? = null, -) - +} \ No newline at end of file diff --git a/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/generator/CodeGenerator.kt b/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/generator/CodeGenerator.kt new file mode 100644 index 0000000000..8b4b75f70c --- /dev/null +++ b/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/generator/CodeGenerator.kt @@ -0,0 +1,73 @@ +package org.utbot.framework.codegen.generator + +import org.utbot.framework.codegen.domain.ForceStaticMocking +import org.utbot.framework.codegen.domain.HangingTestsTimeout +import org.utbot.framework.codegen.domain.ParametrizedTestSource +import org.utbot.framework.codegen.domain.ProjectType +import org.utbot.framework.codegen.domain.RuntimeExceptionTestsBehaviour +import org.utbot.framework.codegen.domain.StaticsMocking +import org.utbot.framework.codegen.domain.TestFramework +import org.utbot.framework.codegen.domain.models.CgMethodTestSet +import org.utbot.framework.codegen.domain.models.builders.SimpleTestClassModelBuilder +import org.utbot.framework.codegen.services.language.CgLanguageAssistant +import org.utbot.framework.codegen.tree.CgSimpleTestClassConstructor +import org.utbot.framework.codegen.tree.ututils.UtilClassKind +import org.utbot.framework.plugin.api.ClassId +import org.utbot.framework.plugin.api.CodegenLanguage +import org.utbot.framework.plugin.api.ExecutableId +import org.utbot.framework.plugin.api.MockFramework + +open class CodeGenerator( + val classUnderTest: ClassId, + val projectType: ProjectType, + paramNames: MutableMap> = mutableMapOf(), + generateUtilClassFile: Boolean = false, + testFramework: TestFramework = TestFramework.defaultItem, + mockFramework: MockFramework = MockFramework.defaultItem, + staticsMocking: StaticsMocking = StaticsMocking.defaultItem, + forceStaticMocking: ForceStaticMocking = ForceStaticMocking.defaultItem, + generateWarningsForStaticMocking: Boolean = true, + codegenLanguage: CodegenLanguage = CodegenLanguage.defaultItem, + cgLanguageAssistant: CgLanguageAssistant = CgLanguageAssistant.getByCodegenLanguage(codegenLanguage), + parameterizedTestSource: ParametrizedTestSource = ParametrizedTestSource.defaultItem, + runtimeExceptionTestsBehaviour: RuntimeExceptionTestsBehaviour = RuntimeExceptionTestsBehaviour.defaultItem, + hangingTestsTimeout: HangingTestsTimeout = HangingTestsTimeout(), + enableTestsTimeout: Boolean = true, + testClassPackageName: String = classUnderTest.packageName, +): AbstractCodeGenerator( + classUnderTest, + projectType, + paramNames, + generateUtilClassFile, + testFramework, + mockFramework, + staticsMocking, + forceStaticMocking, + generateWarningsForStaticMocking, + codegenLanguage, + cgLanguageAssistant, + parameterizedTestSource, + runtimeExceptionTestsBehaviour, + hangingTestsTimeout, + enableTestsTimeout, + testClassPackageName, +) { + + override fun generate(testSets: List): CodeGeneratorResult { + val testClassModel = SimpleTestClassModelBuilder(context).createTestClassModel(classUnderTest, testSets) + + logger.info { "Code generation phase started at ${now()}" } + val astConstructor = CgSimpleTestClassConstructor(context) + val testClassFile = astConstructor.construct(testClassModel) + logger.info { "Code generation phase finished at ${now()}" } + + val generatedCode = renderToString(testClassFile) + + return CodeGeneratorResult( + generatedCode = generatedCode, + utilClassKind = UtilClassKind.fromCgContextOrNull(context), + testsGenerationReport = astConstructor.testsGenerationReport, + ) + } +} + diff --git a/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/generator/CodeGeneratorResult.kt b/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/generator/CodeGeneratorResult.kt new file mode 100644 index 0000000000..67db5a0bee --- /dev/null +++ b/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/generator/CodeGeneratorResult.kt @@ -0,0 +1,16 @@ +package org.utbot.framework.codegen.generator + +import org.utbot.framework.codegen.reports.TestsGenerationReport +import org.utbot.framework.codegen.tree.ututils.UtilClassKind + +/** + * @property generatedCode the source code of the test class + * @property testsGenerationReport some info about test generation process + * @property utilClassKind the kind of util class if it is required, otherwise - null + */ +data class CodeGeneratorResult( + val generatedCode: String, + val testsGenerationReport: TestsGenerationReport, + // null if no util class needed, e.g. when we are generating utils directly into test class + val utilClassKind: UtilClassKind? = null, +) \ No newline at end of file diff --git a/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/generator/SpringCodeGenerator.kt b/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/generator/SpringCodeGenerator.kt new file mode 100644 index 0000000000..fca9b79b19 --- /dev/null +++ b/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/generator/SpringCodeGenerator.kt @@ -0,0 +1,77 @@ +package org.utbot.framework.codegen.generator + +import org.utbot.framework.codegen.domain.ForceStaticMocking +import org.utbot.framework.codegen.domain.HangingTestsTimeout +import org.utbot.framework.codegen.domain.ParametrizedTestSource +import org.utbot.framework.codegen.domain.ProjectType +import org.utbot.framework.codegen.domain.RuntimeExceptionTestsBehaviour +import org.utbot.framework.codegen.domain.StaticsMocking +import org.utbot.framework.codegen.domain.TestFramework +import org.utbot.framework.codegen.domain.models.CgMethodTestSet +import org.utbot.framework.codegen.domain.models.builders.SpringTestClassModelBuilder +import org.utbot.framework.codegen.services.language.CgLanguageAssistant +import org.utbot.framework.codegen.tree.CgSpringIntegrationTestClassConstructor +import org.utbot.framework.codegen.tree.CgSpringUnitTestClassConstructor +import org.utbot.framework.codegen.tree.ututils.UtilClassKind +import org.utbot.framework.plugin.api.ClassId +import org.utbot.framework.plugin.api.CodegenLanguage +import org.utbot.framework.plugin.api.ExecutableId +import org.utbot.framework.plugin.api.MockFramework +import org.utbot.framework.plugin.api.SpringTestsType + +class SpringCodeGenerator( + private val springTestsType: SpringTestsType = SpringTestsType.defaultItem, + val classUnderTest: ClassId, + val projectType: ProjectType, + paramNames: MutableMap> = mutableMapOf(), + generateUtilClassFile: Boolean = false, + testFramework: TestFramework = TestFramework.defaultItem, + mockFramework: MockFramework = MockFramework.defaultItem, + staticsMocking: StaticsMocking = StaticsMocking.defaultItem, + forceStaticMocking: ForceStaticMocking = ForceStaticMocking.defaultItem, + generateWarningsForStaticMocking: Boolean = true, + codegenLanguage: CodegenLanguage = CodegenLanguage.defaultItem, + cgLanguageAssistant: CgLanguageAssistant = CgLanguageAssistant.getByCodegenLanguage(codegenLanguage), + parameterizedTestSource: ParametrizedTestSource = ParametrizedTestSource.defaultItem, + runtimeExceptionTestsBehaviour: RuntimeExceptionTestsBehaviour = RuntimeExceptionTestsBehaviour.defaultItem, + hangingTestsTimeout: HangingTestsTimeout = HangingTestsTimeout(), + enableTestsTimeout: Boolean = true, + testClassPackageName: String = classUnderTest.packageName, +) : AbstractCodeGenerator( + classUnderTest, + projectType, + paramNames, + generateUtilClassFile, + testFramework, + mockFramework, + staticsMocking, + forceStaticMocking, + generateWarningsForStaticMocking, + codegenLanguage, + cgLanguageAssistant, + parameterizedTestSource, + runtimeExceptionTestsBehaviour, + hangingTestsTimeout, + enableTestsTimeout, + testClassPackageName, +) { + override fun generate(testSets: List): CodeGeneratorResult { + val testClassModel = SpringTestClassModelBuilder(context).createTestClassModel(classUnderTest, testSets) + + logger.info { "Code generation phase started at ${now()}" } + val astConstructor = when (springTestsType) { + SpringTestsType.UNIT_TESTS -> CgSpringUnitTestClassConstructor(context) + SpringTestsType.INTEGRATION_TESTS -> CgSpringIntegrationTestClassConstructor(context) + } + val testClassFile = astConstructor.construct(testClassModel) + logger.info { "Code generation phase finished at ${now()}" } + + val generatedCode = renderToString(testClassFile) + + return CodeGeneratorResult( + generatedCode = generatedCode, + utilClassKind = UtilClassKind.fromCgContextOrNull(context), + testsGenerationReport = astConstructor.testsGenerationReport, + ) + } +} \ No newline at end of file diff --git a/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/tree/CgSpringTestClassConstructor.kt b/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/tree/CgAbstractSpringTestClassConstructor.kt similarity index 58% rename from utbot-framework/src/main/kotlin/org/utbot/framework/codegen/tree/CgSpringTestClassConstructor.kt rename to utbot-framework/src/main/kotlin/org/utbot/framework/codegen/tree/CgAbstractSpringTestClassConstructor.kt index 58381d8fc3..142898c1f6 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/tree/CgSpringTestClassConstructor.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/tree/CgAbstractSpringTestClassConstructor.kt @@ -1,55 +1,42 @@ package org.utbot.framework.codegen.tree -import org.utbot.framework.codegen.domain.UtModelWrapper import org.utbot.framework.codegen.domain.builtin.TestClassUtilMethodProvider -import org.utbot.framework.codegen.domain.builtin.closeMethodId import org.utbot.framework.codegen.domain.builtin.injectMocksClassId import org.utbot.framework.codegen.domain.builtin.mockClassId -import org.utbot.framework.codegen.domain.builtin.openMocksMethodId import org.utbot.framework.codegen.domain.context.CgContext -import org.utbot.framework.codegen.domain.models.CgAssignment import org.utbot.framework.codegen.domain.models.CgClassBody import org.utbot.framework.codegen.domain.models.CgDeclaration import org.utbot.framework.codegen.domain.models.CgFieldDeclaration import org.utbot.framework.codegen.domain.models.CgFrameworkUtilMethod import org.utbot.framework.codegen.domain.models.CgMethod -import org.utbot.framework.codegen.domain.models.CgMethodCall import org.utbot.framework.codegen.domain.models.CgMethodTestSet import org.utbot.framework.codegen.domain.models.CgMethodsCluster import org.utbot.framework.codegen.domain.models.CgRegion -import org.utbot.framework.codegen.domain.models.CgSimpleRegion -import org.utbot.framework.codegen.domain.models.CgStatementExecutableCall +import org.utbot.framework.codegen.domain.models.CgStatement import org.utbot.framework.codegen.domain.models.CgStaticsRegion import org.utbot.framework.codegen.domain.models.CgVariable import org.utbot.framework.codegen.domain.models.SpringTestClassModel +import org.utbot.framework.codegen.domain.models.builders.TypedModelWrappers import org.utbot.framework.plugin.api.ClassId -import org.utbot.framework.plugin.api.UtCompositeModel import org.utbot.framework.plugin.api.util.id -import org.utbot.framework.plugin.api.util.objectClassId +import java.lang.Exception -class CgSpringTestClassConstructor(context: CgContext): CgAbstractTestClassConstructor(context) { +abstract class CgAbstractSpringTestClassConstructor(context: CgContext): + CgAbstractTestClassConstructor(context) { - private val variableConstructor: CgSpringVariableConstructor = + protected val variableConstructor: CgSpringVariableConstructor = CgComponents.getVariableConstructorBy(context) as CgSpringVariableConstructor - private val statementConstructor: CgStatementConstructor = CgComponents.getStatementConstructorBy(context) + protected val statementConstructor: CgStatementConstructor = CgComponents.getStatementConstructorBy(context) override fun constructTestClassBody(testClassModel: SpringTestClassModel): CgClassBody { return buildClassBody(currentTestClass) { // TODO: support inner classes here - val mockedFields = constructClassFields(testClassModel.mockedModels, mockClassId) + fields += constructClassFields(testClassModel) + clearUnwantedVariableModels() - if (mockedFields.isNotEmpty()) { - fields += constructClassFields(testClassModel.injectedMockModels, injectMocksClassId) - fields += mockedFields - - clearUnwantedVariableModels() - - val (closeableField, closeableMethods) = constructMockitoCloseables() - fields += closeableField - methodRegions += closeableMethods - } + methodRegions += constructAdditionalMethods() for ((testSetIndex, testSet) in testClassModel.methodTestSets.withIndex()) { updateCurrentExecutable(testSet.executableId) @@ -92,10 +79,14 @@ class CgSpringTestClassConstructor(context: CgContext): CgAbstractTestClassConst return if (regions.any()) regions else null } - private fun constructClassFields( - groupedModelsByClassId: Map>, + abstract fun constructClassFields(testClassModel: SpringTestClassModel): List + + abstract fun constructAdditionalMethods(): CgMethodsCluster + + protected fun constructFieldsWithAnnotation( + groupedModelsByClassId: TypedModelWrappers, annotationClassId: ClassId - ): MutableList { + ): List { require(annotationClassId == injectMocksClassId || annotationClassId == mockClassId) { error("Unexpected annotation classId -- $annotationClassId") } @@ -134,7 +125,7 @@ class CgSpringTestClassConstructor(context: CgContext): CgAbstractTestClassConst * related side effects and just creating a variable definition, * but it will take very long time to do it now. */ - private fun clearUnwantedVariableModels() { + protected fun clearUnwantedVariableModels() { val whiteListOfModels = listOf( variableConstructor.mockedModelsVariables, @@ -146,57 +137,17 @@ class CgSpringTestClassConstructor(context: CgContext): CgAbstractTestClassConst .forEach { valueByUtModelWrapper.remove(it.key) } } - private fun constructMockitoCloseables(): Pair { - val mockitoCloseableVarName = "mockitoCloseable" - val mockitoCloseableVarType = java.lang.AutoCloseable::class.id - - val mockitoCloseableModel = UtCompositeModel( - id = null, - classId = mockitoCloseableVarType, - isMock = false, - ) - - val mockitoCloseableVariable = - variableConstructor.getOrCreateVariable(mockitoCloseableModel, mockitoCloseableVarName) - val mockitoCloseableDeclaration = CgDeclaration(mockitoCloseableVarType, mockitoCloseableVarName, initializer = null) - val mockitoCloseableFieldDeclaration = CgFieldDeclaration(ownerClassId = currentTestClass, mockitoCloseableDeclaration) - - importIfNeeded(openMocksMethodId) - - val openMocksCall = CgMethodCall( - caller = null, - executableId = openMocksMethodId, - //TODO: this is a hack of this - arguments = listOf(CgVariable("this", objectClassId)) - ) - - val closeCall = CgMethodCall( - caller = mockitoCloseableVariable, - executableId = closeMethodId, - arguments = emptyList(), - ) - - val openMocksStatement = CgAssignment(mockitoCloseableVariable, openMocksCall) - val beforeMethod = CgFrameworkUtilMethod( - name = "setUp", - statements = listOf(openMocksStatement), - exceptions = emptySet(), - annotations = listOf(statementConstructor.annotation(context.testFramework.beforeMethodId)), - ) - - val closeStatement = CgStatementExecutableCall(closeCall) - val afterMethod = CgFrameworkUtilMethod( - name = "tearDown", - statements = listOf(closeStatement), - exceptions = setOf(java.lang.Exception::class.id), - annotations = listOf(statementConstructor.annotation(context.testFramework.afterMethodId)), - ) - - val methodCluster = CgMethodsCluster( - header = null, - listOf(CgSimpleRegion(header = null, listOf(beforeMethod, afterMethod))) - ) - - return mockitoCloseableFieldDeclaration to methodCluster - } -} + protected fun constructBeforeMethod(statements: List) = CgFrameworkUtilMethod( + name = "setUp", + statements = statements, + exceptions = emptySet(), + annotations = listOf(statementConstructor.annotation(context.testFramework.beforeMethodId)), + ) + + protected fun constructAfterMethod(statements: List) = CgFrameworkUtilMethod( + name = "tearDown", + statements = statements, + exceptions = setOf(Exception::class.id), + annotations = listOf(statementConstructor.annotation(context.testFramework.afterMethodId)), + ) +} \ No newline at end of file diff --git a/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/tree/CgSpringIntegrationTestClassConstructor.kt b/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/tree/CgSpringIntegrationTestClassConstructor.kt new file mode 100644 index 0000000000..1a19342d68 --- /dev/null +++ b/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/tree/CgSpringIntegrationTestClassConstructor.kt @@ -0,0 +1,19 @@ +package org.utbot.framework.codegen.tree + +import org.utbot.framework.codegen.domain.builtin.autowiredClassId +import org.utbot.framework.codegen.domain.context.CgContext +import org.utbot.framework.codegen.domain.models.CgFieldDeclaration +import org.utbot.framework.codegen.domain.models.CgMethodsCluster +import org.utbot.framework.codegen.domain.models.SpringTestClassModel + +class CgSpringIntegrationTestClassConstructor(context: CgContext) : CgAbstractSpringTestClassConstructor(context) { + + override fun constructClassFields(testClassModel: SpringTestClassModel): List { + return constructFieldsWithAnnotation(testClassModel.thisInstanceModels, autowiredClassId) + } + + override fun constructAdditionalMethods() = CgMethodsCluster( + header = null, + content = emptyList(), + ) +} \ No newline at end of file diff --git a/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/tree/CgSpringUnitTestClassConstructor.kt b/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/tree/CgSpringUnitTestClassConstructor.kt new file mode 100644 index 0000000000..a0fd564098 --- /dev/null +++ b/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/tree/CgSpringUnitTestClassConstructor.kt @@ -0,0 +1,88 @@ +package org.utbot.framework.codegen.tree + +import org.utbot.framework.codegen.domain.builtin.closeMethodId +import org.utbot.framework.codegen.domain.builtin.injectMocksClassId +import org.utbot.framework.codegen.domain.builtin.mockClassId +import org.utbot.framework.codegen.domain.builtin.openMocksMethodId +import org.utbot.framework.codegen.domain.context.CgContext +import org.utbot.framework.codegen.domain.models.CgAssignment +import org.utbot.framework.codegen.domain.models.CgDeclaration +import org.utbot.framework.codegen.domain.models.CgFieldDeclaration +import org.utbot.framework.codegen.domain.models.CgMethodCall +import org.utbot.framework.codegen.domain.models.CgMethodsCluster +import org.utbot.framework.codegen.domain.models.CgSimpleRegion +import org.utbot.framework.codegen.domain.models.CgStatementExecutableCall +import org.utbot.framework.codegen.domain.models.CgValue +import org.utbot.framework.codegen.domain.models.CgVariable +import org.utbot.framework.codegen.domain.models.SpringTestClassModel +import org.utbot.framework.plugin.api.UtCompositeModel +import org.utbot.framework.plugin.api.util.id +import org.utbot.framework.plugin.api.util.objectClassId + +class CgSpringUnitTestClassConstructor(context: CgContext) : CgAbstractSpringTestClassConstructor(context) { + + private lateinit var mockitoCloseableVariable: CgValue + + override fun constructClassFields(testClassModel: SpringTestClassModel): List { + val fields = mutableListOf() + val mockedFields = constructFieldsWithAnnotation(testClassModel.thisInstanceDependentMocks, mockClassId) + + if (mockedFields.isNotEmpty()) { + fields += constructFieldsWithAnnotation(testClassModel.thisInstanceModels, injectMocksClassId) + fields += mockedFields + + fields += constructMockitoCloseables() + } + + return fields + } + + override fun constructAdditionalMethods(): CgMethodsCluster { + importIfNeeded(openMocksMethodId) + + val openMocksCall = CgMethodCall( + caller = null, + executableId = openMocksMethodId, + //TODO: this is a hack of this + arguments = listOf(CgVariable("this", objectClassId)) + ) + + val closeCall = CgMethodCall( + caller = mockitoCloseableVariable, + executableId = closeMethodId, + arguments = emptyList(), + ) + + val openMocksStatement = CgAssignment(mockitoCloseableVariable, openMocksCall) + val closeStatement = CgStatementExecutableCall(closeCall) + + return CgMethodsCluster( + header = null, + listOf( + CgSimpleRegion( + header = null, + listOf( + constructBeforeMethod(listOf(openMocksStatement)), + constructAfterMethod(listOf(closeStatement)), + ) + ) + ) + ) + } + + private fun constructMockitoCloseables(): CgFieldDeclaration { + val mockitoCloseableVarName = "mockitoCloseable" + val mockitoCloseableVarType = java.lang.AutoCloseable::class.id + + val mockitoCloseableModel = UtCompositeModel( + id = null, + classId = mockitoCloseableVarType, + isMock = false, + ) + + mockitoCloseableVariable = + variableConstructor.getOrCreateVariable(mockitoCloseableModel, mockitoCloseableVarName) + val mockitoCloseableDeclaration = CgDeclaration(mockitoCloseableVarType, mockitoCloseableVarName, initializer = null) + return CgFieldDeclaration(ownerClassId = currentTestClass, mockitoCloseableDeclaration) + } +} \ No newline at end of file diff --git a/utbot-framework/src/main/kotlin/org/utbot/framework/plugin/sarif/GenerateTestsAndSarifReportFacade.kt b/utbot-framework/src/main/kotlin/org/utbot/framework/plugin/sarif/GenerateTestsAndSarifReportFacade.kt index 46d3b94036..ac50a76489 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/framework/plugin/sarif/GenerateTestsAndSarifReportFacade.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/framework/plugin/sarif/GenerateTestsAndSarifReportFacade.kt @@ -1,8 +1,8 @@ package org.utbot.framework.plugin.sarif -import org.utbot.framework.codegen.CodeGenerator import org.utbot.framework.codegen.domain.ForceStaticMocking import org.utbot.framework.codegen.domain.NoStaticMocking +import org.utbot.framework.codegen.generator.CodeGenerator import org.utbot.framework.codegen.services.language.CgLanguageAssistant import org.utbot.framework.plugin.api.TestCaseGenerator import org.utbot.framework.plugin.api.UtMethodTestSet diff --git a/utbot-framework/src/main/kotlin/org/utbot/framework/process/EngineProcessMain.kt b/utbot-framework/src/main/kotlin/org/utbot/framework/process/EngineProcessMain.kt index 237cde8df2..9d72c31721 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/framework/process/EngineProcessMain.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/framework/process/EngineProcessMain.kt @@ -5,7 +5,7 @@ import kotlinx.coroutines.runBlocking import mu.KotlinLogging import org.utbot.analytics.AnalyticsConfigureUtil import org.utbot.common.* -import org.utbot.framework.codegen.* +import org.utbot.framework.codegen.domain.ForceStaticMocking import org.utbot.framework.codegen.domain.HangingTestsTimeout import org.utbot.framework.codegen.domain.MockitoStaticMocking import org.utbot.framework.codegen.domain.NoStaticMocking @@ -13,6 +13,9 @@ import org.utbot.framework.codegen.domain.ParametrizedTestSource import org.utbot.framework.codegen.domain.ProjectType import org.utbot.framework.codegen.domain.RuntimeExceptionTestsBehaviour import org.utbot.framework.codegen.domain.testFrameworkByName +import org.utbot.framework.codegen.generator.AbstractCodeGenerator +import org.utbot.framework.codegen.generator.CodeGenerator +import org.utbot.framework.codegen.generator.SpringCodeGenerator import org.utbot.framework.codegen.reports.TestsGenerationReport import org.utbot.framework.codegen.services.language.CgLanguageAssistant import org.utbot.framework.plugin.api.* @@ -115,62 +118,41 @@ private fun EngineProcessModel.setup(kryoHelper: KryoHelper, watchdog: IdleWatch } watchdog.measureTimeForActiveCall(generate, "Generating tests") { params -> val methods: List = kryoHelper.readObject(params.methods) - logger.debug().measureTime({ "starting generation for ${methods.size} methods, starting with ${methods.first()}" }) { - val generateFlow = when (testGenerator.applicationContext) { - is SpringApplicationContext -> defaultSpringFlow(params) - is ApplicationContext -> testFlow { - generationTimeout = params.generationTimeout - isSymbolicEngineEnabled = params.isSymbolicEngineEnabled - isFuzzingEnabled = params.isFuzzingEnabled - fuzzingValue = params.fuzzingValue + logger.debug() + .measureTime({ "starting generation for ${methods.size} methods, starting with ${methods.first()}" }) { + val generateFlow = when (testGenerator.applicationContext) { + is SpringApplicationContext -> defaultSpringFlow(params) + is ApplicationContext -> testFlow { + generationTimeout = params.generationTimeout + isSymbolicEngineEnabled = params.isSymbolicEngineEnabled + isFuzzingEnabled = params.isFuzzingEnabled + fuzzingValue = params.fuzzingValue + } + + else -> error("Unknown application context ${testGenerator.applicationContext}") } - else -> error("Unknown application context ${testGenerator.applicationContext}") - } - val result = testGenerator.generate( - methods, - MockStrategyApi.valueOf(params.mockStrategy), - kryoHelper.readObject(params.chosenClassesToMockAlways), - params.timeout, - generate = generateFlow, - ) - .summarizeAll(Paths.get(params.searchDirectory), null) - .filterNot { it.executions.isEmpty() && it.errors.isEmpty() } + val result = testGenerator.generate( + methods, + MockStrategyApi.valueOf(params.mockStrategy), + kryoHelper.readObject(params.chosenClassesToMockAlways), + params.timeout, + generate = generateFlow, + ) + .summarizeAll(Paths.get(params.searchDirectory), null) + .filterNot { it.executions.isEmpty() && it.errors.isEmpty() } - val id = ++idCounter + val id = ++idCounter - testSets[id] = result - GenerateResult(result.size, id) - } + testSets[id] = result + GenerateResult(result.size, id) + } } watchdog.measureTimeForActiveCall(render, "Rendering tests") { params -> - val testFramework = testFrameworkByName(params.testFramework) - val staticMocking = if (params.staticsMocking.startsWith("No")) { - NoStaticMocking - } else { - MockitoStaticMocking - } - val classId: ClassId = kryoHelper.readObject(params.classUnderTest) - val testSetsId: Long = params.testSetsId - val codeGenerator = CodeGenerator( - classUnderTest = classId, - projectType = ProjectType.valueOf(params.projectType), - generateUtilClassFile = params.generateUtilClassFile, - paramNames = kryoHelper.readObject(params.paramNames), - testFramework = testFramework, - mockFramework = MockFramework.valueOf(params.mockFramework), - codegenLanguage = CodegenLanguage.valueOf(params.codegenLanguage), - cgLanguageAssistant = CgLanguageAssistant.getByCodegenLanguage(CodegenLanguage.valueOf(params.codegenLanguage)), - parameterizedTestSource = ParametrizedTestSource.valueOf(params.parameterizedTestSource), - staticsMocking = staticMocking, - forceStaticMocking = kryoHelper.readObject(params.forceStaticMocking), - generateWarningsForStaticMocking = params.generateWarningsForStaticMocking, - runtimeExceptionTestsBehaviour = RuntimeExceptionTestsBehaviour.valueOf(params.runtimeExceptionTestsBehaviour), - hangingTestsTimeout = HangingTestsTimeout(params.hangingTestsTimeout), - enableTestsTimeout = params.enableTestsTimeout, - testClassPackageName = params.testClassPackageName - ) - codeGenerator.generateAsStringWithTestReport(testSets[testSetsId]!!).let { + val projectType = ProjectType.valueOf(params.projectType) + val codeGenerator = projectType.createCodeGenerator(kryoHelper, params) + + codeGenerator.generateAsStringWithTestReport(testSets[params.testSetsId]!!).let { testGenerationReports.add(it.testsGenerationReport) RenderResult(it.generatedCode, it.utilClassKind?.javaClass?.simpleName) } @@ -212,7 +194,11 @@ private fun EngineProcessModel.setup(kryoHelper: KryoHelper, watchdog: IdleWatch val testPackageName: String? = params.testPackageName var hasWarnings = false val reports = testGenerationReports - if (reports.isEmpty()) return@measureTimeForActiveCall GenerateTestReportResult("No tests were generated", null, true) + if (reports.isEmpty()) return@measureTimeForActiveCall GenerateTestReportResult( + "No tests were generated", + null, + true + ) val isMultiPackage = params.isMultiPackage val (notifyMessage, statistics) = if (reports.size == 1) { val report = reports.first() @@ -301,4 +287,58 @@ private fun destinationWarningMessage(testPackageName: String?, classUnderTestPa } else { null } +} + +private fun ProjectType.createCodeGenerator(kryoHelper: KryoHelper, params: RenderParams): AbstractCodeGenerator { + with(params) { + val classUnderTest: ClassId = kryoHelper.readObject(classUnderTest) + val paramNames: MutableMap> = kryoHelper.readObject(paramNames) + val testFramework = testFrameworkByName(testFramework) + val staticMocking = if (staticsMocking.startsWith("No")) NoStaticMocking else MockitoStaticMocking + val forceStaticMocking: ForceStaticMocking = kryoHelper.readObject(forceStaticMocking) + + return when (this@createCodeGenerator) { + ProjectType.PureJvm -> CodeGenerator( + classUnderTest = classUnderTest, + projectType = ProjectType.valueOf(projectType), + generateUtilClassFile = generateUtilClassFile, + paramNames = paramNames, + testFramework = testFramework, + mockFramework = MockFramework.valueOf(mockFramework), + codegenLanguage = CodegenLanguage.valueOf(codegenLanguage), + cgLanguageAssistant = CgLanguageAssistant.getByCodegenLanguage(CodegenLanguage.valueOf(codegenLanguage)), + parameterizedTestSource = ParametrizedTestSource.valueOf(parameterizedTestSource), + staticsMocking = staticMocking, + forceStaticMocking = forceStaticMocking, + generateWarningsForStaticMocking = generateWarningsForStaticMocking, + runtimeExceptionTestsBehaviour = RuntimeExceptionTestsBehaviour.valueOf(runtimeExceptionTestsBehaviour), + hangingTestsTimeout = HangingTestsTimeout(hangingTestsTimeout), + enableTestsTimeout = enableTestsTimeout, + testClassPackageName = testClassPackageName, + ) + + ProjectType.Spring -> SpringCodeGenerator( + springTestsType = SpringTestsType.valueOf(springTestsType), + classUnderTest = classUnderTest, + projectType = ProjectType.valueOf(projectType), + generateUtilClassFile = generateUtilClassFile, + paramNames = paramNames, + testFramework = testFramework, + mockFramework = MockFramework.valueOf(mockFramework), + codegenLanguage = CodegenLanguage.valueOf(codegenLanguage), + cgLanguageAssistant = CgLanguageAssistant.getByCodegenLanguage(CodegenLanguage.valueOf(codegenLanguage)), + parameterizedTestSource = ParametrizedTestSource.valueOf(parameterizedTestSource), + staticsMocking = staticMocking, + forceStaticMocking = forceStaticMocking, + generateWarningsForStaticMocking = generateWarningsForStaticMocking, + runtimeExceptionTestsBehaviour = RuntimeExceptionTestsBehaviour.valueOf(runtimeExceptionTestsBehaviour), + hangingTestsTimeout = HangingTestsTimeout(hangingTestsTimeout), + enableTestsTimeout = enableTestsTimeout, + testClassPackageName = testClassPackageName, + ) + + ProjectType.Python -> error("Python code generator can not be created in Engine process") + ProjectType.JavaScript -> error("JavaScript code generator can not be created in Engine process") + } + } } \ No newline at end of file diff --git a/utbot-framework/src/main/kotlin/org/utbot/framework/process/generated/EngineProcessModel.Generated.kt b/utbot-framework/src/main/kotlin/org/utbot/framework/process/generated/EngineProcessModel.Generated.kt index 90230bad15..fa5bd123c0 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/framework/process/generated/EngineProcessModel.Generated.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/framework/process/generated/EngineProcessModel.Generated.kt @@ -75,7 +75,7 @@ class EngineProcessModel private constructor( } - const val serializationHash = 3987813751020865118L + const val serializationHash = 2605460374173973135L } override val serializersOwner: ISerializersOwner get() = EngineProcessModel @@ -182,7 +182,7 @@ val IProtocol.engineProcessModel get() = getOrCreateExtension(EngineProcessModel /** - * #### Generated from [EngineProcessModel.kt:131] + * #### Generated from [EngineProcessModel.kt:132] */ data class BeanAdditionalData ( val factoryMethodName: String, @@ -251,7 +251,7 @@ data class BeanAdditionalData ( /** - * #### Generated from [EngineProcessModel.kt:136] + * #### Generated from [EngineProcessModel.kt:137] */ data class BeanDefinitionData ( val beanName: String, @@ -320,7 +320,7 @@ data class BeanDefinitionData ( /** - * #### Generated from [EngineProcessModel.kt:105] + * #### Generated from [EngineProcessModel.kt:106] */ data class FindMethodParamNamesArguments ( val classId: ByteArray, @@ -383,7 +383,7 @@ data class FindMethodParamNamesArguments ( /** - * #### Generated from [EngineProcessModel.kt:109] + * #### Generated from [EngineProcessModel.kt:110] */ data class FindMethodParamNamesResult ( val paramNames: ByteArray @@ -440,7 +440,7 @@ data class FindMethodParamNamesResult ( /** - * #### Generated from [EngineProcessModel.kt:98] + * #### Generated from [EngineProcessModel.kt:99] */ data class FindMethodsInClassMatchingSelectedArguments ( val classId: ByteArray, @@ -503,7 +503,7 @@ data class FindMethodsInClassMatchingSelectedArguments ( /** - * #### Generated from [EngineProcessModel.kt:102] + * #### Generated from [EngineProcessModel.kt:103] */ data class FindMethodsInClassMatchingSelectedResult ( val executableIds: ByteArray @@ -728,7 +728,7 @@ data class GenerateResult ( /** - * #### Generated from [EngineProcessModel.kt:117] + * #### Generated from [EngineProcessModel.kt:118] */ data class GenerateTestReportArgs ( val eventLogMessage: String?, @@ -821,7 +821,7 @@ data class GenerateTestReportArgs ( /** - * #### Generated from [EngineProcessModel.kt:126] + * #### Generated from [EngineProcessModel.kt:127] */ data class GenerateTestReportResult ( val notifyMessage: String, @@ -890,7 +890,7 @@ data class GenerateTestReportResult ( /** - * #### Generated from [EngineProcessModel.kt:87] + * #### Generated from [EngineProcessModel.kt:88] */ data class GetSpringBeanDefinitions ( val classpath: Array, @@ -1028,7 +1028,7 @@ data class JdkInfo ( /** - * #### Generated from [EngineProcessModel.kt:93] + * #### Generated from [EngineProcessModel.kt:94] */ data class MethodDescription ( val name: String, @@ -1100,6 +1100,7 @@ data class MethodDescription ( * #### Generated from [EngineProcessModel.kt:62] */ data class RenderParams ( + val springTestsType: String, val testSetsId: Long, val classUnderTest: ByteArray, val projectType: String, @@ -1124,6 +1125,7 @@ data class RenderParams ( @Suppress("UNCHECKED_CAST") override fun read(ctx: SerializationCtx, buffer: AbstractBuffer): RenderParams { + val springTestsType = buffer.readString() val testSetsId = buffer.readLong() val classUnderTest = buffer.readByteArray() val projectType = buffer.readString() @@ -1140,10 +1142,11 @@ data class RenderParams ( val hangingTestsTimeout = buffer.readLong() val enableTestsTimeout = buffer.readBool() val testClassPackageName = buffer.readString() - return RenderParams(testSetsId, classUnderTest, projectType, paramNames, generateUtilClassFile, testFramework, mockFramework, codegenLanguage, parameterizedTestSource, staticsMocking, forceStaticMocking, generateWarningsForStaticMocking, runtimeExceptionTestsBehaviour, hangingTestsTimeout, enableTestsTimeout, testClassPackageName) + return RenderParams(springTestsType, testSetsId, classUnderTest, projectType, paramNames, generateUtilClassFile, testFramework, mockFramework, codegenLanguage, parameterizedTestSource, staticsMocking, forceStaticMocking, generateWarningsForStaticMocking, runtimeExceptionTestsBehaviour, hangingTestsTimeout, enableTestsTimeout, testClassPackageName) } override fun write(ctx: SerializationCtx, buffer: AbstractBuffer, value: RenderParams) { + buffer.writeString(value.springTestsType) buffer.writeLong(value.testSetsId) buffer.writeByteArray(value.classUnderTest) buffer.writeString(value.projectType) @@ -1175,6 +1178,7 @@ data class RenderParams ( other as RenderParams + if (springTestsType != other.springTestsType) return false if (testSetsId != other.testSetsId) return false if (!(classUnderTest contentEquals other.classUnderTest)) return false if (projectType != other.projectType) return false @@ -1197,6 +1201,7 @@ data class RenderParams ( //hash code trait override fun hashCode(): Int { var __r = 0 + __r = __r*31 + springTestsType.hashCode() __r = __r*31 + testSetsId.hashCode() __r = __r*31 + classUnderTest.contentHashCode() __r = __r*31 + projectType.hashCode() @@ -1219,6 +1224,7 @@ data class RenderParams ( override fun print(printer: PrettyPrinter) { printer.println("RenderParams (") printer.indent { + print("springTestsType = "); springTestsType.print(printer); println() print("testSetsId = "); testSetsId.print(printer); println() print("classUnderTest = "); classUnderTest.print(printer); println() print("projectType = "); projectType.print(printer); println() @@ -1244,7 +1250,7 @@ data class RenderParams ( /** - * #### Generated from [EngineProcessModel.kt:80] + * #### Generated from [EngineProcessModel.kt:81] */ data class RenderResult ( val generatedCode: String, @@ -1307,7 +1313,7 @@ data class RenderResult ( /** - * #### Generated from [EngineProcessModel.kt:84] + * #### Generated from [EngineProcessModel.kt:85] */ data class SetupContextParams ( val classpathForUrlsClassloader: List @@ -1364,7 +1370,7 @@ data class SetupContextParams ( /** - * #### Generated from [EngineProcessModel.kt:141] + * #### Generated from [EngineProcessModel.kt:142] */ data class SpringAnalyzerResult ( val beanDefinitions: Array @@ -1502,7 +1508,7 @@ data class TestGeneratorParams ( /** - * #### Generated from [EngineProcessModel.kt:112] + * #### Generated from [EngineProcessModel.kt:113] */ data class WriteSarifReportArguments ( val testSetsId: Long, diff --git a/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/generator/CodeGenerationController.kt b/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/generator/CodeGenerationController.kt index 0a02f02cde..f35c1ae026 100644 --- a/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/generator/CodeGenerationController.kt +++ b/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/generator/CodeGenerationController.kt @@ -684,6 +684,7 @@ object CodeGenerationController { return@run } proc.render( + model.springTestsType, testSetsId, classUnderTest, model.projectType, diff --git a/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/models/GenerateTestsModel.kt b/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/models/GenerateTestsModel.kt index 85091ccca8..d9299e1dec 100644 --- a/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/models/GenerateTestsModel.kt +++ b/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/models/GenerateTestsModel.kt @@ -21,7 +21,7 @@ import org.utbot.framework.SummariesGenerationType import org.utbot.framework.UtSettings import org.utbot.framework.codegen.domain.TypeReplacementApproach import org.utbot.framework.plugin.api.JavaDocCommentStyle -import org.utbot.framework.plugin.api.SpringTestType +import org.utbot.framework.plugin.api.SpringTestsType import org.utbot.framework.util.ConflictTriggers import org.utbot.intellij.plugin.settings.Settings @@ -44,6 +44,8 @@ class GenerateTestsModel( override var sourceRootHistory = project.service().sourceRootHistory override var codegenLanguage = project.service().codegenLanguage + lateinit var springTestsType: SpringTestsType + lateinit var testFramework: TestFramework lateinit var mockStrategy: MockStrategyApi lateinit var mockFramework: MockFramework @@ -54,7 +56,6 @@ class GenerateTestsModel( var runInspectionAfterTestGeneration: Boolean = true lateinit var forceStaticMocking: ForceStaticMocking lateinit var chosenClassesToMockAlways: Set - lateinit var springTestType: SpringTestType lateinit var commentStyle: JavaDocCommentStyle lateinit var typeReplacementApproach: TypeReplacementApproach diff --git a/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/process/EngineProcess.kt b/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/process/EngineProcess.kt index c82a1eb807..182bcf57f6 100644 --- a/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/process/EngineProcess.kt +++ b/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/process/EngineProcess.kt @@ -274,6 +274,7 @@ class EngineProcess private constructor(val project: Project, private val classN } fun render( + springTestsType: SpringTestsType, testSetsId: Long, classUnderTest: ClassId, projectType: ProjectType, @@ -293,6 +294,7 @@ class EngineProcess private constructor(val project: Project, private val classN ): Pair { assertReadAccessNotAllowed() val params = RenderParams( + springTestsType.name, testSetsId, kryoHelper.writeObject(classUnderTest), projectType.toString(), diff --git a/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/settings/Settings.kt b/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/settings/Settings.kt index eb82652768..a47dab6c7d 100644 --- a/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/settings/Settings.kt +++ b/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/settings/Settings.kt @@ -23,7 +23,7 @@ private fun fromGenerateTestsModel(model: GenerateTestsModel): Settings.State { forceStaticMocking = model.forceStaticMocking, parametrizedTestSource = model.parametrizedTestSource, classesToMockAlways = model.chosenClassesToMockAlways.mapTo(mutableSetOf()) { it.name }.toTypedArray(), - springTestType = model.springTestType, + springTestsType = model.springTestsType, fuzzingValue = model.fuzzingValue, runGeneratedTestsWithCoverage = model.runGeneratedTestsWithCoverage, commentStyle = model.commentStyle, diff --git a/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/ui/GenerateTestsDialogWindow.kt b/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/ui/GenerateTestsDialogWindow.kt index f3b5a7c925..070e099c44 100644 --- a/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/ui/GenerateTestsDialogWindow.kt +++ b/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/ui/GenerateTestsDialogWindow.kt @@ -96,8 +96,8 @@ import org.utbot.framework.plugin.api.CodegenLanguage import org.utbot.framework.plugin.api.MockFramework import org.utbot.framework.plugin.api.MockFramework.MOCKITO import org.utbot.framework.plugin.api.MockStrategyApi -import org.utbot.framework.plugin.api.SpringTestType -import org.utbot.framework.plugin.api.SpringTestType.* +import org.utbot.framework.plugin.api.SpringTestsType +import org.utbot.framework.plugin.api.SpringTestsType.* import org.utbot.framework.plugin.api.TreatOverflowAsError import org.utbot.framework.plugin.api.utils.MOCKITO_EXTENSIONS_FILE_CONTENT import org.utbot.framework.plugin.api.utils.MOCKITO_EXTENSIONS_FOLDER @@ -203,7 +203,7 @@ class GenerateTestsDialogWindow(val model: GenerateTestsModel) : DialogWrapper(m private val mockStrategies = createComboBox(MockStrategyApi.values()) private val staticsMocking = JCheckBox("Mock static methods") - private val sprintTestType = createComboBox(SpringTestType.values()) + private val springTestsType = createComboBox(SpringTestsType.values()) private val springConfig = createComboBoxWithSeparatorsForSpringConfigs(shortenConfigurationNames()) private val profileNames = JBTextField(23).apply { emptyText.text = DEFAULT_SPRING_PROFILE_NAME } @@ -421,7 +421,7 @@ class GenerateTestsDialogWindow(val model: GenerateTestsModel) : DialogWrapper(m ) } row("Tests type:") { - cell(sprintTestType) + cell(springTestsType) contextHelp( "Unit tests do not initialize ApplicationContext
" + "and do not autowire beans, while integration tests do." @@ -706,7 +706,7 @@ class GenerateTestsDialogWindow(val model: GenerateTestsModel) : DialogWrapper(m } } model.profileNames = profileNames.text.let { it.ifEmpty { DEFAULT_SPRING_PROFILE_NAME } } - model.springTestType = sprintTestType.item + model.springTestsType = springTestsType.item val settings = model.project.service() with(settings) { @@ -857,7 +857,7 @@ class GenerateTestsDialogWindow(val model: GenerateTestsModel) : DialogWrapper(m ?: if (settings.testFramework != Junit4) settings.testFramework else TestFramework.parametrizedDefaultItem } - sprintTestType.item = if (isSpringConfigSelected()) settings.springTestType else SpringTestType.defaultItem + springTestsType.item = if (isSpringConfigSelected()) settings.springTestsType else SpringTestsType.defaultItem updateTestFrameworksList(settings.parametrizedTestSource) updateParametrizationEnabled() @@ -917,7 +917,7 @@ class GenerateTestsDialogWindow(val model: GenerateTestsModel) : DialogWrapper(m } private fun configureSpringTestFrameworkIfRequired() { - if (sprintTestType.item == INTEGRATION_TESTS) { + if (springTestsType.item == INTEGRATION_TESTS) { val framework = when { SpringBoot.isInstalled -> SpringBoot @@ -1145,7 +1145,7 @@ class GenerateTestsDialogWindow(val model: GenerateTestsModel) : DialogWrapper(m mockStrategies.isEnabled = false updateMockStrategyListForConfigGuidedTypeReplacements() - sprintTestType.isEnabled = !isXmlSpringConfigUsed() + springTestsType.isEnabled = !isXmlSpringConfigUsed() profileNames.isEnabled = true } else { mockStrategies.item = when (model.projectType) { @@ -1155,8 +1155,8 @@ class GenerateTestsDialogWindow(val model: GenerateTestsModel) : DialogWrapper(m mockStrategies.isEnabled = true updateMockStrategyList() - sprintTestType.isEnabled = false - sprintTestType.item = SpringTestType.defaultItem + springTestsType.isEnabled = false + springTestsType.item = SpringTestsType.defaultItem profileNames.isEnabled = false profileNames.text = "" @@ -1240,9 +1240,9 @@ class GenerateTestsDialogWindow(val model: GenerateTestsModel) : DialogWrapper(m // We check for > 1 because there is already extra-dummy NO_SPRING_CONFIGURATION_OPTION option springConfig.isEnabled = model.projectType == ProjectType.Spring && springConfig.itemCount > 1 - sprintTestType.renderer = object : ColoredListCellRenderer() { + springTestsType.renderer = object : ColoredListCellRenderer() { override fun customizeCellRenderer( - list: JList, value: SpringTestType, + list: JList, value: SpringTestsType, index: Int, selected: Boolean, hasFocus: Boolean ) { this.append(value.displayName, SimpleTextAttributes.REGULAR_ATTRIBUTES) diff --git a/utbot-js/src/main/kotlin/codegen/JsCodeGenerator.kt b/utbot-js/src/main/kotlin/codegen/JsCodeGenerator.kt index 099ca3ccb6..a4ba25f609 100644 --- a/utbot-js/src/main/kotlin/codegen/JsCodeGenerator.kt +++ b/utbot-js/src/main/kotlin/codegen/JsCodeGenerator.kt @@ -4,7 +4,6 @@ import framework.api.js.JsClassId import framework.codegen.JsCgLanguageAssistant import framework.codegen.JsImport import framework.codegen.Mocha -import org.utbot.framework.codegen.CodeGeneratorResult import org.utbot.framework.codegen.domain.ForceStaticMocking import org.utbot.framework.codegen.domain.HangingTestsTimeout import org.utbot.framework.codegen.domain.ParametrizedTestSource @@ -16,6 +15,7 @@ import org.utbot.framework.codegen.domain.context.CgContext import org.utbot.framework.codegen.domain.models.CgClassFile import org.utbot.framework.codegen.domain.models.CgMethodTestSet import org.utbot.framework.codegen.domain.models.SimpleTestClassModel +import org.utbot.framework.codegen.generator.CodeGenerator import org.utbot.framework.codegen.renderer.CgAbstractRenderer import org.utbot.framework.codegen.tree.CgSimpleTestClassConstructor import org.utbot.framework.plugin.api.CodegenLanguage diff --git a/utbot-junit-contest/src/main/kotlin/org/utbot/contest/Contest.kt b/utbot-junit-contest/src/main/kotlin/org/utbot/contest/Contest.kt index cae9c46d62..8d317ed4f2 100644 --- a/utbot-junit-contest/src/main/kotlin/org/utbot/contest/Contest.kt +++ b/utbot-junit-contest/src/main/kotlin/org/utbot/contest/Contest.kt @@ -13,7 +13,6 @@ import org.utbot.framework.UtSettings import org.utbot.framework.codegen.domain.ForceStaticMocking import org.utbot.framework.codegen.domain.StaticsMocking import org.utbot.framework.codegen.domain.junitByVersion -import org.utbot.framework.codegen.CodeGenerator import org.utbot.framework.plugin.api.util.UtContext import org.utbot.framework.plugin.api.util.executableId import org.utbot.framework.plugin.api.util.id @@ -53,6 +52,7 @@ import kotlinx.coroutines.runBlocking import kotlinx.coroutines.withTimeoutOrNull import org.utbot.framework.SummariesGenerationType import org.utbot.framework.codegen.domain.ProjectType +import org.utbot.framework.codegen.generator.CodeGenerator import org.utbot.framework.codegen.services.language.CgLanguageAssistant import org.utbot.framework.minimization.minimizeExecutions import org.utbot.framework.plugin.api.* diff --git a/utbot-python/src/main/kotlin/org/utbot/python/framework/codegen/model/PythonCodeGenerator.kt b/utbot-python/src/main/kotlin/org/utbot/python/framework/codegen/model/PythonCodeGenerator.kt index 519234c3fb..fc809207a0 100644 --- a/utbot-python/src/main/kotlin/org/utbot/python/framework/codegen/model/PythonCodeGenerator.kt +++ b/utbot-python/src/main/kotlin/org/utbot/python/framework/codegen/model/PythonCodeGenerator.kt @@ -1,7 +1,6 @@ package org.utbot.python.framework.codegen.model -import org.utbot.framework.codegen.CodeGenerator -import org.utbot.framework.codegen.CodeGeneratorResult +import org.utbot.framework.codegen.generator.CodeGeneratorResult import org.utbot.framework.codegen.domain.ForceStaticMocking import org.utbot.framework.codegen.domain.HangingTestsTimeout import org.utbot.framework.codegen.domain.ParametrizedTestSource @@ -14,6 +13,7 @@ import org.utbot.framework.codegen.domain.models.CgLiteral import org.utbot.framework.codegen.domain.models.CgMethodTestSet import org.utbot.framework.codegen.domain.models.CgVariable import org.utbot.framework.codegen.domain.models.SimpleTestClassModel +import org.utbot.framework.codegen.generator.CodeGenerator import org.utbot.framework.codegen.renderer.CgAbstractRenderer import org.utbot.framework.codegen.renderer.CgPrinterImpl import org.utbot.framework.codegen.renderer.CgRendererContext diff --git a/utbot-rd/src/main/rdgen/org/utbot/rd/models/EngineProcessModel.kt b/utbot-rd/src/main/rdgen/org/utbot/rd/models/EngineProcessModel.kt index 4490fa30a2..f1a52584db 100644 --- a/utbot-rd/src/main/rdgen/org/utbot/rd/models/EngineProcessModel.kt +++ b/utbot-rd/src/main/rdgen/org/utbot/rd/models/EngineProcessModel.kt @@ -60,6 +60,7 @@ object EngineProcessModel : Ext(EngineProcessRoot) { field("testSetsId", PredefinedType.long) } val renderParams = structdef { + field("springTestsType", PredefinedType.string) field("testSetsId", PredefinedType.long) field("classUnderTest", array(PredefinedType.byte)) field("projectType", PredefinedType.string) diff --git a/utbot-testing/src/main/kotlin/org/utbot/testing/TestCodeGeneratorPipeline.kt b/utbot-testing/src/main/kotlin/org/utbot/testing/TestCodeGeneratorPipeline.kt index a62a80e4cf..ec239a977b 100644 --- a/utbot-testing/src/main/kotlin/org/utbot/testing/TestCodeGeneratorPipeline.kt +++ b/utbot-testing/src/main/kotlin/org/utbot/testing/TestCodeGeneratorPipeline.kt @@ -5,13 +5,13 @@ import org.junit.jupiter.api.Assertions.assertTrue import org.utbot.common.FileUtil import org.utbot.common.measureTime import org.utbot.common.info -import org.utbot.framework.codegen.CodeGenerator -import org.utbot.framework.codegen.CodeGeneratorResult +import org.utbot.framework.codegen.generator.CodeGeneratorResult import org.utbot.framework.codegen.domain.ForceStaticMocking import org.utbot.framework.codegen.domain.ParametrizedTestSource import org.utbot.framework.codegen.domain.ProjectType import org.utbot.framework.codegen.domain.StaticsMocking import org.utbot.framework.codegen.domain.TestFramework +import org.utbot.framework.codegen.generator.CodeGenerator import org.utbot.framework.codegen.services.language.CgLanguageAssistant import org.utbot.framework.codegen.tree.ututils.UtilClassKind import org.utbot.framework.codegen.tree.ututils.UtilClassKind.Companion.UT_UTILS_INSTANCE_NAME diff --git a/utbot-ui-commons/src/main/kotlin/org/utbot/intellij/plugin/settings/CommonSettings.kt b/utbot-ui-commons/src/main/kotlin/org/utbot/intellij/plugin/settings/CommonSettings.kt index e93162556e..3b33253091 100644 --- a/utbot-ui-commons/src/main/kotlin/org/utbot/intellij/plugin/settings/CommonSettings.kt +++ b/utbot-ui-commons/src/main/kotlin/org/utbot/intellij/plugin/settings/CommonSettings.kt @@ -36,7 +36,7 @@ import java.util.concurrent.CompletableFuture import kotlin.reflect.KClass import org.utbot.common.isWindows import org.utbot.framework.SummariesGenerationType -import org.utbot.framework.plugin.api.SpringTestType +import org.utbot.framework.plugin.api.SpringTestsType import org.utbot.framework.plugin.api.isSummarizationCompatible @State( @@ -61,7 +61,7 @@ class Settings(val project: Project) : PersistentStateComponent var treatOverflowAsError: TreatOverflowAsError = TreatOverflowAsError.defaultItem, var parametrizedTestSource: ParametrizedTestSource = ParametrizedTestSource.defaultItem, var classesToMockAlways: Array = Mocker.defaultSuperClassesToMockAlwaysNames.toTypedArray(), - var springTestType: SpringTestType = SpringTestType.defaultItem, + var springTestsType: SpringTestsType = SpringTestsType.defaultItem, var fuzzingValue: Double = 0.05, var runGeneratedTestsWithCoverage: Boolean = false, var commentStyle: JavaDocCommentStyle = JavaDocCommentStyle.defaultItem, @@ -89,7 +89,7 @@ class Settings(val project: Project) : PersistentStateComponent if (treatOverflowAsError != other.treatOverflowAsError) return false if (parametrizedTestSource != other.parametrizedTestSource) return false if (!classesToMockAlways.contentEquals(other.classesToMockAlways)) return false - if (springTestType != other.springTestType) return false + if (springTestsType != other.springTestsType) return false if (fuzzingValue != other.fuzzingValue) return false if (runGeneratedTestsWithCoverage != other.runGeneratedTestsWithCoverage) return false if (commentStyle != other.commentStyle) return false @@ -112,7 +112,7 @@ class Settings(val project: Project) : PersistentStateComponent result = 31 * result + treatOverflowAsError.hashCode() result = 31 * result + parametrizedTestSource.hashCode() result = 31 * result + classesToMockAlways.contentHashCode() - result = 31 * result + springTestType.hashCode() + result = 31 * result + springTestsType.hashCode() result = 31 * result + fuzzingValue.hashCode() result = 31 * result + if (runGeneratedTestsWithCoverage) 1 else 0 result = 31 * result + summariesGenerationType.hashCode() @@ -159,7 +159,7 @@ class Settings(val project: Project) : PersistentStateComponent val classesToMockAlways: Set get() = state.classesToMockAlways.toSet() - val springTestType: SpringTestType get() = state.springTestType + val springTestsType: SpringTestsType get() = state.springTestsType val javaDocCommentStyle: JavaDocCommentStyle get() = state.commentStyle