From 1583e43b194335120db740c0755bbe2b27c1c595 Mon Sep 17 00:00:00 2001 From: Egor Kulikov Date: Fri, 10 Feb 2023 11:56:51 +0300 Subject: [PATCH] Refactor CgTestClassConstructor --- .../utbot/framework/codegen/CodeGenerator.kt | 4 +- .../access/CgCallableAccessManager.kt | 4 +- .../services/access/CgFieldStateManager.kt | 4 +- .../framework/MockFrameworkManager.kt | 2 +- .../framework/TestFrameworkManager.kt | 4 +- .../framework/codegen/tree/CgComponents.kt | 55 +++++ .../codegen/tree/CgMethodConstructor.kt | 65 +++--- ...tor.kt => CgSimpleTestClassConstructor.kt} | 189 +++++------------- .../codegen/tree/CgStatementConstructor.kt | 4 +- .../tree/CgTestClassConstructorBase.kt | 58 ++++++ .../codegen/tree/CgVariableConstructor.kt | 8 +- .../tree/JsCgStatementConstructor.kt | 5 +- .../tree/JsCgVariableConstructor.kt | 3 +- .../tree/PythonCgStatementConstructor.kt | 4 +- .../tree/PythonCgTestClassConstructor.kt | 4 +- .../tree/PythonCgVariableConstructor.kt | 4 +- 16 files changed, 220 insertions(+), 197 deletions(-) create mode 100644 utbot-framework/src/main/kotlin/org/utbot/framework/codegen/tree/CgComponents.kt rename utbot-framework/src/main/kotlin/org/utbot/framework/codegen/tree/{CgTestClassConstructor.kt => CgSimpleTestClassConstructor.kt} (60%) create mode 100644 utbot-framework/src/main/kotlin/org/utbot/framework/codegen/tree/CgTestClassConstructorBase.kt diff --git a/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/CodeGenerator.kt b/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/CodeGenerator.kt index 1ac8de600e..ebb662c064 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/CodeGenerator.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/CodeGenerator.kt @@ -12,7 +12,7 @@ import org.utbot.framework.codegen.domain.models.TestClassModel import org.utbot.framework.codegen.domain.context.CgContext import org.utbot.framework.codegen.renderer.CgAbstractRenderer import org.utbot.framework.codegen.reports.TestsGenerationReport -import org.utbot.framework.codegen.tree.CgTestClassConstructor +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.plugin.api.ClassId @@ -73,7 +73,7 @@ open class CodeGenerator( val cgTestSets = testSets.map { CgMethodTestSet(it) }.toList() return withCustomContext(testClassCustomName) { context.withTestClassFileScope { - val astConstructor = CgTestClassConstructor(context) + val astConstructor = CgSimpleTestClassConstructor(context) val renderer = CgAbstractRenderer.makeRenderer(context) val testClassModel = TestClassModel.fromTestSets(classUnderTest, cgTestSets) diff --git a/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/services/access/CgCallableAccessManager.kt b/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/services/access/CgCallableAccessManager.kt index 9507e1e49e..152d11df0a 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/services/access/CgCallableAccessManager.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/services/access/CgCallableAccessManager.kt @@ -26,8 +26,8 @@ import org.utbot.framework.codegen.domain.models.CgThisInstance import org.utbot.framework.codegen.domain.models.CgValue import org.utbot.framework.codegen.domain.models.CgVariable import org.utbot.framework.codegen.services.access.CgCallableAccessManagerImpl.FieldAccessorSuitability.* -import org.utbot.framework.codegen.tree.CgTestClassConstructor.CgComponents.getStatementConstructorBy -import org.utbot.framework.codegen.tree.CgTestClassConstructor.CgComponents.getVariableConstructorBy +import org.utbot.framework.codegen.tree.CgComponents.getStatementConstructorBy +import org.utbot.framework.codegen.tree.CgComponents.getVariableConstructorBy import org.utbot.framework.codegen.tree.getAmbiguousOverloadsOf import org.utbot.framework.codegen.tree.importIfNeeded import org.utbot.framework.codegen.tree.isUtil diff --git a/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/services/access/CgFieldStateManager.kt b/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/services/access/CgFieldStateManager.kt index cb01d9456e..33fea7ed75 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/services/access/CgFieldStateManager.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/services/access/CgFieldStateManager.kt @@ -8,10 +8,10 @@ import org.utbot.framework.codegen.domain.models.CgExpression import org.utbot.framework.codegen.domain.models.CgGetJavaClass import org.utbot.framework.codegen.domain.models.CgValue import org.utbot.framework.codegen.domain.models.CgVariable +import org.utbot.framework.codegen.tree.CgComponents.getCallableAccessManagerBy +import org.utbot.framework.codegen.tree.CgComponents.getStatementConstructorBy import org.utbot.framework.codegen.tree.CgFieldState import org.utbot.framework.codegen.tree.CgStatementConstructor -import org.utbot.framework.codegen.tree.CgTestClassConstructor.CgComponents.getCallableAccessManagerBy -import org.utbot.framework.codegen.tree.CgTestClassConstructor.CgComponents.getStatementConstructorBy import org.utbot.framework.codegen.tree.FieldStateCache import org.utbot.framework.codegen.tree.classCgClassId import org.utbot.framework.codegen.tree.getFieldVariableName diff --git a/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/services/framework/MockFrameworkManager.kt b/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/services/framework/MockFrameworkManager.kt index 87254a9829..f502f12d3e 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/services/framework/MockFrameworkManager.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/services/framework/MockFrameworkManager.kt @@ -39,9 +39,9 @@ import org.utbot.framework.codegen.domain.models.CgValue import org.utbot.framework.codegen.domain.models.CgVariable import org.utbot.framework.codegen.services.access.CgCallableAccessManager import org.utbot.framework.codegen.services.access.CgCallableAccessManagerImpl +import org.utbot.framework.codegen.tree.CgComponents.getVariableConstructorBy import org.utbot.framework.codegen.tree.CgStatementConstructor import org.utbot.framework.codegen.tree.CgStatementConstructorImpl -import org.utbot.framework.codegen.tree.CgTestClassConstructor.CgComponents.getVariableConstructorBy import org.utbot.framework.codegen.tree.CgVariableConstructor import org.utbot.framework.codegen.tree.hasAmbiguousOverloadsOf import org.utbot.framework.codegen.util.isAccessibleFrom diff --git a/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/services/framework/TestFrameworkManager.kt b/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/services/framework/TestFrameworkManager.kt index 6db42e130c..964781e801 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/services/framework/TestFrameworkManager.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/services/framework/TestFrameworkManager.kt @@ -22,8 +22,8 @@ import org.utbot.framework.codegen.domain.models.CgSingleArgAnnotation import org.utbot.framework.codegen.domain.models.CgValue import org.utbot.framework.codegen.domain.models.CgVariable import org.utbot.framework.codegen.services.access.CgCallableAccessManager -import org.utbot.framework.codegen.tree.CgTestClassConstructor.CgComponents.getCallableAccessManagerBy -import org.utbot.framework.codegen.tree.CgTestClassConstructor.CgComponents.getStatementConstructorBy +import org.utbot.framework.codegen.tree.CgComponents.getCallableAccessManagerBy +import org.utbot.framework.codegen.tree.CgComponents.getStatementConstructorBy import org.utbot.framework.codegen.tree.addToListMethodId import org.utbot.framework.codegen.tree.argumentsClassId import org.utbot.framework.codegen.tree.argumentsMethodId diff --git a/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/tree/CgComponents.kt b/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/tree/CgComponents.kt new file mode 100644 index 0000000000..99357aed5a --- /dev/null +++ b/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/tree/CgComponents.kt @@ -0,0 +1,55 @@ +package org.utbot.framework.codegen.tree + +import org.utbot.framework.codegen.domain.context.CgContext +import org.utbot.framework.codegen.services.CgNameGenerator +import org.utbot.framework.codegen.services.access.CgCallableAccessManager +import org.utbot.framework.codegen.services.framework.MockFrameworkManager +import org.utbot.framework.codegen.services.framework.TestFrameworkManager + +object CgComponents { + + /** + * Clears all stored data for current [CgContext]. + * As far as context is created per class under test, + * no related data is required after it's processing. + */ + fun clearContextRelatedStorage() { + nameGenerators.clear() + statementConstructors.clear() + callableAccessManagers.clear() + testFrameworkManagers.clear() + mockFrameworkManagers.clear() + variableConstructors.clear() + methodConstructors.clear() + } + + private val nameGenerators: MutableMap = mutableMapOf() + private val statementConstructors: MutableMap = mutableMapOf() + private val callableAccessManagers: MutableMap = mutableMapOf() + private val testFrameworkManagers: MutableMap = mutableMapOf() + private val mockFrameworkManagers: MutableMap = mutableMapOf() + + private val variableConstructors: MutableMap = mutableMapOf() + private val methodConstructors: MutableMap = mutableMapOf() + + fun getNameGeneratorBy(context: CgContext) = nameGenerators.getOrPut(context) { + context.cgLanguageAssistant.getNameGeneratorBy(context) + } + fun getCallableAccessManagerBy(context: CgContext) = callableAccessManagers.getOrPut(context) { + context.cgLanguageAssistant.getCallableAccessManagerBy(context) + } + fun getStatementConstructorBy(context: CgContext) = statementConstructors.getOrPut(context) { + context.cgLanguageAssistant.getStatementConstructorBy(context) + } + + fun getTestFrameworkManagerBy(context: CgContext) = + testFrameworkManagers.getOrDefault(context, context.cgLanguageAssistant.getLanguageTestFrameworkManager().managerByFramework(context)) + + fun getMockFrameworkManagerBy(context: CgContext) = mockFrameworkManagers.getOrPut(context) { MockFrameworkManager(context) } + fun getVariableConstructorBy(context: CgContext) = variableConstructors.getOrPut(context) { + context.cgLanguageAssistant.getVariableConstructorBy(context) + } + fun getMethodConstructorBy(context: CgContext) = methodConstructors.getOrPut(context) { + context.cgLanguageAssistant.getMethodConstructorBy(context) + } +} \ No newline at end of file diff --git a/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/tree/CgMethodConstructor.kt b/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/tree/CgMethodConstructor.kt index fba77160ec..1d44d53398 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/tree/CgMethodConstructor.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/tree/CgMethodConstructor.kt @@ -1,15 +1,14 @@ package org.utbot.framework.codegen.tree -import org.utbot.common.PathUtil import org.utbot.common.WorkaroundReason import org.utbot.common.isStatic import org.utbot.common.workaround import org.utbot.engine.ArtificialError +import org.utbot.framework.UtSettings import org.utbot.framework.assemble.assemble import org.utbot.framework.codegen.domain.ForceStaticMocking import org.utbot.framework.codegen.domain.ParametrizedTestSource import org.utbot.framework.codegen.domain.RuntimeExceptionTestsBehaviour.PASS -import org.utbot.framework.codegen.domain.models.CgMethodTestSet import org.utbot.framework.codegen.domain.builtin.closeMethodIdOrNull import org.utbot.framework.codegen.domain.builtin.forName import org.utbot.framework.codegen.domain.builtin.getClass @@ -22,8 +21,6 @@ import org.utbot.framework.codegen.domain.models.CgAllocateArray import org.utbot.framework.codegen.domain.models.CgArrayElementAccess import org.utbot.framework.codegen.domain.models.CgClassId import org.utbot.framework.codegen.domain.models.CgDeclaration -import org.utbot.framework.codegen.domain.models.CgDocPreTagStatement -import org.utbot.framework.codegen.domain.models.CgDocRegularStmt import org.utbot.framework.codegen.domain.models.CgDocumentationComment import org.utbot.framework.codegen.domain.models.CgEqualTo import org.utbot.framework.codegen.domain.models.CgErrorTestMethod @@ -34,6 +31,7 @@ import org.utbot.framework.codegen.domain.models.CgGetJavaClass import org.utbot.framework.codegen.domain.models.CgLiteral 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.CgMultilineComment import org.utbot.framework.codegen.domain.models.CgNotNullAssertion import org.utbot.framework.codegen.domain.models.CgParameterDeclaration @@ -53,10 +51,19 @@ import org.utbot.framework.codegen.domain.models.CgValue import org.utbot.framework.codegen.domain.models.CgVariable import org.utbot.framework.codegen.domain.models.convertDocToCg import org.utbot.framework.codegen.domain.models.toStatement +import org.utbot.framework.codegen.services.access.CgCallableAccessManager +import org.utbot.framework.codegen.services.access.CgFieldStateManagerImpl +import org.utbot.framework.codegen.services.framework.TestFrameworkManager +import org.utbot.framework.codegen.tree.CgComponents.getCallableAccessManagerBy +import org.utbot.framework.codegen.tree.CgComponents.getMockFrameworkManagerBy +import org.utbot.framework.codegen.tree.CgComponents.getNameGeneratorBy +import org.utbot.framework.codegen.tree.CgComponents.getStatementConstructorBy +import org.utbot.framework.codegen.tree.CgComponents.getTestFrameworkManagerBy +import org.utbot.framework.codegen.tree.CgComponents.getVariableConstructorBy +import org.utbot.framework.codegen.util.canBeReadFrom import org.utbot.framework.codegen.util.canBeSetFrom import org.utbot.framework.codegen.util.equalTo import org.utbot.framework.codegen.util.inc -import org.utbot.framework.codegen.util.canBeReadFrom import org.utbot.framework.codegen.util.length import org.utbot.framework.codegen.util.lessThan import org.utbot.framework.codegen.util.nullLiteral @@ -67,10 +74,10 @@ import org.utbot.framework.plugin.api.BuiltinClassId import org.utbot.framework.plugin.api.BuiltinMethodId import org.utbot.framework.plugin.api.ClassId import org.utbot.framework.plugin.api.CodegenLanguage -import org.utbot.framework.plugin.api.InstrumentedProcessDeathException import org.utbot.framework.plugin.api.ConstructorId import org.utbot.framework.plugin.api.ExecutableId import org.utbot.framework.plugin.api.FieldId +import org.utbot.framework.plugin.api.InstrumentedProcessDeathException import org.utbot.framework.plugin.api.MethodId import org.utbot.framework.plugin.api.TimeoutException import org.utbot.framework.plugin.api.TypeParameters @@ -83,16 +90,19 @@ import org.utbot.framework.plugin.api.UtDirectSetFieldModel import org.utbot.framework.plugin.api.UtEnumConstantModel import org.utbot.framework.plugin.api.UtExecution import org.utbot.framework.plugin.api.UtExecutionFailure +import org.utbot.framework.plugin.api.UtExecutionResult import org.utbot.framework.plugin.api.UtExecutionSuccess import org.utbot.framework.plugin.api.UtExplicitlyThrownException import org.utbot.framework.plugin.api.UtLambdaModel import org.utbot.framework.plugin.api.UtModel import org.utbot.framework.plugin.api.UtNewInstanceInstrumentation import org.utbot.framework.plugin.api.UtNullModel +import org.utbot.framework.plugin.api.UtOverflowFailure import org.utbot.framework.plugin.api.UtPrimitiveModel import org.utbot.framework.plugin.api.UtReferenceModel import org.utbot.framework.plugin.api.UtSandboxFailure import org.utbot.framework.plugin.api.UtStaticMethodInstrumentation +import org.utbot.framework.plugin.api.UtStreamConsumingFailure import org.utbot.framework.plugin.api.UtSymbolicExecution import org.utbot.framework.plugin.api.UtTimeoutException import org.utbot.framework.plugin.api.UtVoidModel @@ -100,62 +110,49 @@ import org.utbot.framework.plugin.api.isNotNull import org.utbot.framework.plugin.api.isNull import org.utbot.framework.plugin.api.onFailure import org.utbot.framework.plugin.api.onSuccess +import org.utbot.framework.plugin.api.util.allSuperTypes +import org.utbot.framework.plugin.api.util.baseStreamClassId import org.utbot.framework.plugin.api.util.doubleArrayClassId import org.utbot.framework.plugin.api.util.doubleClassId +import org.utbot.framework.plugin.api.util.doubleStreamClassId +import org.utbot.framework.plugin.api.util.doubleStreamToArrayMethodId import org.utbot.framework.plugin.api.util.doubleWrapperClassId import org.utbot.framework.plugin.api.util.executable -import org.utbot.framework.plugin.api.util.jField import org.utbot.framework.plugin.api.util.floatArrayClassId import org.utbot.framework.plugin.api.util.floatClassId import org.utbot.framework.plugin.api.util.floatWrapperClassId import org.utbot.framework.plugin.api.util.hasField import org.utbot.framework.plugin.api.util.id import org.utbot.framework.plugin.api.util.intClassId +import org.utbot.framework.plugin.api.util.intStreamClassId +import org.utbot.framework.plugin.api.util.intStreamToArrayMethodId import org.utbot.framework.plugin.api.util.isArray +import org.utbot.framework.plugin.api.util.isInaccessibleViaReflection import org.utbot.framework.plugin.api.util.isInnerClassEnclosingClassReference import org.utbot.framework.plugin.api.util.isIterableOrMap import org.utbot.framework.plugin.api.util.isPrimitive import org.utbot.framework.plugin.api.util.isPrimitiveArray import org.utbot.framework.plugin.api.util.isPrimitiveWrapper import org.utbot.framework.plugin.api.util.isRefType +import org.utbot.framework.plugin.api.util.isStatic +import org.utbot.framework.plugin.api.util.isSubtypeOf import org.utbot.framework.plugin.api.util.jClass +import org.utbot.framework.plugin.api.util.jField import org.utbot.framework.plugin.api.util.kClass +import org.utbot.framework.plugin.api.util.longStreamClassId +import org.utbot.framework.plugin.api.util.longStreamToArrayMethodId import org.utbot.framework.plugin.api.util.objectArrayClassId import org.utbot.framework.plugin.api.util.objectClassId +import org.utbot.framework.plugin.api.util.streamClassId +import org.utbot.framework.plugin.api.util.streamToArrayMethodId import org.utbot.framework.plugin.api.util.stringClassId import org.utbot.framework.plugin.api.util.voidClassId import org.utbot.framework.plugin.api.util.wrapIfPrimitive -import org.utbot.framework.plugin.api.util.isInaccessibleViaReflection import org.utbot.framework.util.isUnit import org.utbot.summary.SummarySentenceConstants.TAB import java.lang.reflect.InvocationTargetException -import java.security.AccessControlException import java.lang.reflect.ParameterizedType -import org.utbot.framework.UtSettings -import org.utbot.framework.codegen.services.access.CgCallableAccessManager -import org.utbot.framework.codegen.services.access.CgFieldStateManagerImpl -import org.utbot.framework.codegen.services.framework.TestFrameworkManager -import org.utbot.framework.codegen.tree.CgTestClassConstructor.CgComponents.getCallableAccessManagerBy -import org.utbot.framework.codegen.tree.CgTestClassConstructor.CgComponents.getMockFrameworkManagerBy -import org.utbot.framework.codegen.tree.CgTestClassConstructor.CgComponents.getNameGeneratorBy -import org.utbot.framework.codegen.tree.CgTestClassConstructor.CgComponents.getStatementConstructorBy -import org.utbot.framework.codegen.tree.CgTestClassConstructor.CgComponents.getTestFrameworkManagerBy -import org.utbot.framework.codegen.tree.CgTestClassConstructor.CgComponents.getVariableConstructorBy -import org.utbot.framework.plugin.api.UtExecutionResult -import org.utbot.framework.plugin.api.UtOverflowFailure -import org.utbot.framework.plugin.api.UtStreamConsumingFailure -import org.utbot.framework.plugin.api.util.allSuperTypes -import org.utbot.framework.plugin.api.util.baseStreamClassId -import org.utbot.framework.plugin.api.util.doubleStreamClassId -import org.utbot.framework.plugin.api.util.doubleStreamToArrayMethodId -import org.utbot.framework.plugin.api.util.intStreamClassId -import org.utbot.framework.plugin.api.util.intStreamToArrayMethodId -import org.utbot.framework.plugin.api.util.isSubtypeOf -import org.utbot.framework.plugin.api.util.longStreamClassId -import org.utbot.framework.plugin.api.util.longStreamToArrayMethodId -import org.utbot.framework.plugin.api.util.streamClassId -import org.utbot.framework.plugin.api.util.streamToArrayMethodId -import org.utbot.framework.plugin.api.util.isStatic +import java.security.AccessControlException private const val DEEP_EQUALS_MAX_DEPTH = 5 // TODO move it to plugin settings? diff --git a/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/tree/CgTestClassConstructor.kt b/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/tree/CgSimpleTestClassConstructor.kt similarity index 60% rename from utbot-framework/src/main/kotlin/org/utbot/framework/codegen/tree/CgTestClassConstructor.kt rename to utbot-framework/src/main/kotlin/org/utbot/framework/codegen/tree/CgSimpleTestClassConstructor.kt index 09467b3f38..78711d867b 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/tree/CgTestClassConstructor.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/tree/CgSimpleTestClassConstructor.kt @@ -7,10 +7,7 @@ import org.utbot.framework.codegen.domain.ParametrizedTestSource import org.utbot.framework.codegen.domain.TestNg import org.utbot.framework.codegen.domain.builtin.TestClassUtilMethodProvider import org.utbot.framework.codegen.domain.context.CgContext -import org.utbot.framework.codegen.domain.context.CgContextOwner import org.utbot.framework.codegen.domain.models.CgAuxiliaryClass -import org.utbot.framework.codegen.domain.models.CgClass -import org.utbot.framework.codegen.domain.models.CgClassFile import org.utbot.framework.codegen.domain.models.CgMethod import org.utbot.framework.codegen.domain.models.CgMethodTestSet import org.utbot.framework.codegen.domain.models.CgMethodsCluster @@ -26,16 +23,8 @@ import org.utbot.framework.codegen.domain.models.CgUtilMethod import org.utbot.framework.codegen.domain.models.TestClassModel import org.utbot.framework.codegen.renderer.importUtilMethodDependencies import org.utbot.framework.codegen.reports.TestsGenerationReport -import org.utbot.framework.codegen.services.CgNameGenerator -import org.utbot.framework.codegen.services.access.CgCallableAccessManager -import org.utbot.framework.codegen.services.framework.MockFrameworkManager -import org.utbot.framework.codegen.services.framework.TestFrameworkManager -import org.utbot.framework.codegen.tree.CgTestClassConstructor.CgComponents.clearContextRelatedStorage -import org.utbot.framework.codegen.tree.CgTestClassConstructor.CgComponents.getMethodConstructorBy -import org.utbot.framework.codegen.tree.CgTestClassConstructor.CgComponents.getNameGeneratorBy -import org.utbot.framework.codegen.tree.CgTestClassConstructor.CgComponents.getStatementConstructorBy -import org.utbot.framework.codegen.tree.CgTestClassConstructor.CgComponents.getTestFrameworkManagerBy - +import org.utbot.framework.codegen.tree.CgComponents.clearContextRelatedStorage +import org.utbot.framework.codegen.tree.CgComponents.getMethodConstructorBy import org.utbot.framework.plugin.api.ClassId import org.utbot.framework.plugin.api.MethodId import org.utbot.framework.plugin.api.UtExecutionSuccess @@ -45,103 +34,71 @@ import org.utbot.framework.plugin.api.util.description import org.utbot.framework.plugin.api.util.humanReadableName import org.utbot.fuzzer.UtFuzzedExecution -open class CgTestClassConstructor(val context: CgContext) : - CgContextOwner by context, - CgStatementConstructor by getStatementConstructorBy(context) { +/** + * This test class constructor is used for pure Java/Kotlin applications. + */ +open class CgSimpleTestClassConstructor(context: CgContext): CgTestClassConstructorBase(context) { init { clearContextRelatedStorage() } - private val methodConstructor = getMethodConstructorBy(context) - private val nameGenerator = getNameGeneratorBy(context) - private val testFrameworkManager = getTestFrameworkManagerBy(context) + override val methodConstructor = getMethodConstructorBy(context) val testsGenerationReport = TestsGenerationReport() - /** - * Given a testClass model constructs CgTestClass - */ - open fun construct(testClassModel: TestClassModel): CgClassFile { - return buildClassFile { - this.declaredClass = withTestClassScope { constructTestClass(testClassModel) } - imports += context.collectedImports - } - } - - open fun constructTestClass(testClassModel: TestClassModel): CgClass { - return buildClass { - id = currentTestClass - - if (currentTestClass != outerMostTestClass) { - isNested = true - isStatic = testFramework.nestedClassesShouldBeStatic - testFrameworkManager.annotationForNestedClasses?.let { - currentTestClassContext.collectedTestClassAnnotations += it + override fun constructTestClassBody(testClassModel: TestClassModel) = buildClassBody(currentTestClass) { + val notYetConstructedTestSets = testClassModel.methodTestSets.toMutableList() + + for (nestedClass in testClassModel.nestedClasses) { + // It is not possible to run tests for both outer and inner class in JUnit4 at once, + // so we locate all test methods in outer test class for JUnit4. + // see https://stackoverflow.com/questions/69770700/how-to-run-tests-from-outer-class-and-nested-inner-classes-simultaneously-in-jun + // or https://stackoverflow.com/questions/28230277/test-cases-in-inner-class-and-outer-class-with-junit4 + when (testFramework) { + Junit4 -> { + notYetConstructedTestSets += collectTestSetsFromInnerClasses(nestedClass) } - } - - body = buildClassBody(currentTestClass) { - val notYetConstructedTestSets = testClassModel.methodTestSets.toMutableList() - - for (nestedClass in testClassModel.nestedClasses) { - // It is not possible to run tests for both outer and inner class in JUnit4 at once, - // so we locate all test methods in outer test class for JUnit4. - // see https://stackoverflow.com/questions/69770700/how-to-run-tests-from-outer-class-and-nested-inner-classes-simultaneously-in-jun - // or https://stackoverflow.com/questions/28230277/test-cases-in-inner-class-and-outer-class-with-junit4 - when (testFramework) { - Junit4 -> { - notYetConstructedTestSets += collectTestSetsFromInnerClasses(nestedClass) - } - Junit5, - TestNg -> { - nestedClassRegions += CgRealNestedClassesRegion( - "Tests for ${nestedClass.classUnderTest.simpleName}", - listOf(withNestedClassScope(nestedClass) { constructTestClass(nestedClass) }) - ) - } - } - } - - for (testSet in notYetConstructedTestSets) { - updateCurrentExecutable(testSet.executableId) - val currentMethodUnderTestRegions = constructTestSet(testSet) ?: continue - val executableUnderTestCluster = CgMethodsCluster( - "Test suites for executable $currentExecutable", - currentMethodUnderTestRegions + Junit5, + TestNg -> { + nestedClassRegions += CgRealNestedClassesRegion( + "Tests for ${nestedClass.classUnderTest.simpleName}", + listOf(withNestedClassScope(nestedClass) { constructTestClass(nestedClass) }) ) - methodRegions += executableUnderTestCluster } + } + } - val currentTestClassDataProviderMethods = currentTestClassContext.cgDataProviderMethods - if (currentTestClassDataProviderMethods.isNotEmpty()) { - staticDeclarationRegions += - CgStaticsRegion( - "Data provider methods for parametrized tests", - currentTestClassDataProviderMethods, - ) - } + for (testSet in notYetConstructedTestSets) { + updateCurrentExecutable(testSet.executableId) + val currentMethodUnderTestRegions = constructTestSet(testSet) ?: continue + val executableUnderTestCluster = CgMethodsCluster( + "Test suites for executable $currentExecutable", + currentMethodUnderTestRegions + ) + methodRegions += executableUnderTestCluster + } - if (currentTestClass == outerMostTestClass) { - val utilEntities = collectUtilEntities() - // If utilMethodProvider is TestClassUtilMethodProvider, then util entities should be declared - // in the test class. Otherwise, util entities will be located elsewhere (e.g. another class). - if (utilMethodProvider is TestClassUtilMethodProvider && utilEntities.isNotEmpty()) { - staticDeclarationRegions += CgStaticsRegion("Util methods", utilEntities) - } - } - } - // It is important that annotations, superclass and interfaces assignment is run after - // all methods are generated so that all necessary info is already present in the context - with (currentTestClassContext) { - annotations += collectedTestClassAnnotations - superclass = testClassSuperclass - interfaces += collectedTestClassInterfaces + val currentTestClassDataProviderMethods = currentTestClassContext.cgDataProviderMethods + if (currentTestClassDataProviderMethods.isNotEmpty()) { + staticDeclarationRegions += + CgStaticsRegion( + "Data provider methods for parametrized tests", + currentTestClassDataProviderMethods, + ) + } + + if (currentTestClass == outerMostTestClass) { + val utilEntities = collectUtilEntities() + // If utilMethodProvider is TestClassUtilMethodProvider, then util entities should be declared + // in the test class. Otherwise, util entities will be located elsewhere (e.g. another class). + if (utilMethodProvider is TestClassUtilMethodProvider && utilEntities.isNotEmpty()) { + staticDeclarationRegions += CgStaticsRegion("Util methods", utilEntities) } } } - fun constructTestSet(testSet: CgMethodTestSet): List>? { + private fun constructTestSet(testSet: CgMethodTestSet): List>? { val regions = mutableListOf>() if (testSet.executions.any()) { @@ -360,51 +317,5 @@ open class CgTestClassConstructor(val context: CgContext) : protected val CgMethodTestSet.allErrors: Map get() = errors + codeGenerationErrors.getOrDefault(this, mapOf()) - object CgComponents { - /** - * Clears all stored data for current [CgContext]. - * As far as context is created per class under test, - * no related data is required after it's processing. - */ - fun clearContextRelatedStorage() { - nameGenerators.clear() - statementConstructors.clear() - callableAccessManagers.clear() - testFrameworkManagers.clear() - mockFrameworkManagers.clear() - variableConstructors.clear() - methodConstructors.clear() - } - - private val nameGenerators: MutableMap = mutableMapOf() - private val statementConstructors: MutableMap = mutableMapOf() - private val callableAccessManagers: MutableMap = mutableMapOf() - private val testFrameworkManagers: MutableMap = mutableMapOf() - private val mockFrameworkManagers: MutableMap = mutableMapOf() - - private val variableConstructors: MutableMap = mutableMapOf() - private val methodConstructors: MutableMap = mutableMapOf() - - fun getNameGeneratorBy(context: CgContext) = nameGenerators.getOrPut(context) { - context.cgLanguageAssistant.getNameGeneratorBy(context) - } - fun getCallableAccessManagerBy(context: CgContext) = callableAccessManagers.getOrPut(context) { - context.cgLanguageAssistant.getCallableAccessManagerBy(context) - } - fun getStatementConstructorBy(context: CgContext) = statementConstructors.getOrPut(context) { - context.cgLanguageAssistant.getStatementConstructorBy(context) - } - - fun getTestFrameworkManagerBy(context: CgContext) = - testFrameworkManagers.getOrDefault(context, context.cgLanguageAssistant.getLanguageTestFrameworkManager().managerByFramework(context)) - - fun getMockFrameworkManagerBy(context: CgContext) = mockFrameworkManagers.getOrPut(context) { MockFrameworkManager(context) } - fun getVariableConstructorBy(context: CgContext) = variableConstructors.getOrPut(context) { - context.cgLanguageAssistant.getVariableConstructorBy(context) - } - fun getMethodConstructorBy(context: CgContext) = methodConstructors.getOrPut(context) { - context.cgLanguageAssistant.getMethodConstructorBy(context) - } - } } diff --git a/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/tree/CgStatementConstructor.kt b/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/tree/CgStatementConstructor.kt index adb4fba2cb..d118efa8aa 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/tree/CgStatementConstructor.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/tree/CgStatementConstructor.kt @@ -52,8 +52,8 @@ import org.utbot.framework.codegen.domain.models.CgArrayInitializer import org.utbot.framework.codegen.domain.models.CgGetJavaClass import org.utbot.framework.codegen.domain.models.CgIsInstance import org.utbot.framework.codegen.services.access.CgCallableAccessManager -import org.utbot.framework.codegen.tree.CgTestClassConstructor.CgComponents.getCallableAccessManagerBy -import org.utbot.framework.codegen.tree.CgTestClassConstructor.CgComponents.getNameGeneratorBy +import org.utbot.framework.codegen.tree.CgComponents.getCallableAccessManagerBy +import org.utbot.framework.codegen.tree.CgComponents.getNameGeneratorBy import org.utbot.framework.plugin.api.ConstructorId import org.utbot.framework.plugin.api.FieldId import org.utbot.framework.plugin.api.MethodId diff --git a/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/tree/CgTestClassConstructorBase.kt b/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/tree/CgTestClassConstructorBase.kt new file mode 100644 index 0000000000..dcf5d24c7d --- /dev/null +++ b/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/tree/CgTestClassConstructorBase.kt @@ -0,0 +1,58 @@ +package org.utbot.framework.codegen.tree + +import org.utbot.framework.codegen.domain.context.CgContext +import org.utbot.framework.codegen.domain.context.CgContextOwner +import org.utbot.framework.codegen.domain.models.CgClass +import org.utbot.framework.codegen.domain.models.CgClassBody +import org.utbot.framework.codegen.domain.models.CgClassFile +import org.utbot.framework.codegen.domain.models.TestClassModel +import org.utbot.framework.codegen.services.CgNameGenerator +import org.utbot.framework.codegen.services.framework.TestFrameworkManager + +abstract class CgTestClassConstructorBase(val context: CgContext): + CgContextOwner by context, + CgStatementConstructor by CgComponents.getStatementConstructorBy(context){ + + protected abstract val methodConstructor: CgMethodConstructor + protected open val nameGenerator: CgNameGenerator = CgComponents.getNameGeneratorBy(context) + protected open val testFrameworkManager: TestFrameworkManager = CgComponents.getTestFrameworkManagerBy(context) + + /** + * Constructs a file with the test class corresponding to [TestClassModel]. + */ + open fun construct(testClassModel: TestClassModel): CgClassFile { + return buildClassFile { + this.declaredClass = withTestClassScope { constructTestClass(testClassModel) } + imports += context.collectedImports + } + } + + /** + * Constructs [CgClass] corresponding to [TestClassModel]. + */ + open fun constructTestClass(testClassModel: TestClassModel): CgClass { + return buildClass { + id = currentTestClass + + if (currentTestClass != outerMostTestClass) { + isNested = true + isStatic = testFramework.nestedClassesShouldBeStatic + testFrameworkManager.annotationForNestedClasses?.let { + currentTestClassContext.collectedTestClassAnnotations += it + } + } + + body = constructTestClassBody(testClassModel) + + // It is important that annotations, superclass and interfaces assignment is run after + // all methods are generated so that all necessary info is already present in the context + with (currentTestClassContext) { + annotations += collectedTestClassAnnotations + superclass = testClassSuperclass + interfaces += collectedTestClassInterfaces + } + } + } + + abstract fun constructTestClassBody(testClassModel: TestClassModel): CgClassBody +} \ No newline at end of file diff --git a/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/tree/CgVariableConstructor.kt b/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/tree/CgVariableConstructor.kt index 2bfca7cce6..d174bb7da8 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/tree/CgVariableConstructor.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/tree/CgVariableConstructor.kt @@ -20,10 +20,10 @@ import org.utbot.framework.codegen.domain.models.CgStaticFieldAccess import org.utbot.framework.codegen.domain.models.CgValue import org.utbot.framework.codegen.domain.models.CgVariable import org.utbot.framework.codegen.services.access.CgCallableAccessManager -import org.utbot.framework.codegen.tree.CgTestClassConstructor.CgComponents.getCallableAccessManagerBy -import org.utbot.framework.codegen.tree.CgTestClassConstructor.CgComponents.getMockFrameworkManagerBy -import org.utbot.framework.codegen.tree.CgTestClassConstructor.CgComponents.getNameGeneratorBy -import org.utbot.framework.codegen.tree.CgTestClassConstructor.CgComponents.getStatementConstructorBy +import org.utbot.framework.codegen.tree.CgComponents.getCallableAccessManagerBy +import org.utbot.framework.codegen.tree.CgComponents.getMockFrameworkManagerBy +import org.utbot.framework.codegen.tree.CgComponents.getNameGeneratorBy +import org.utbot.framework.codegen.tree.CgComponents.getStatementConstructorBy import org.utbot.framework.codegen.util.at import org.utbot.framework.codegen.util.canBeSetFrom import org.utbot.framework.codegen.util.fieldThatIsGotWith diff --git a/utbot-js/src/main/kotlin/framework/codegen/model/constructor/tree/JsCgStatementConstructor.kt b/utbot-js/src/main/kotlin/framework/codegen/model/constructor/tree/JsCgStatementConstructor.kt index e132a1bb60..4b8482e10f 100644 --- a/utbot-js/src/main/kotlin/framework/codegen/model/constructor/tree/JsCgStatementConstructor.kt +++ b/utbot-js/src/main/kotlin/framework/codegen/model/constructor/tree/JsCgStatementConstructor.kt @@ -26,6 +26,7 @@ import org.utbot.framework.codegen.domain.models.CgThrowStatement import org.utbot.framework.codegen.domain.models.CgTryCatch import org.utbot.framework.codegen.domain.models.CgVariable import org.utbot.framework.codegen.services.access.CgCallableAccessManager +import org.utbot.framework.codegen.tree.CgComponents import org.utbot.framework.codegen.tree.CgForEachLoopBuilder import org.utbot.framework.codegen.tree.CgForLoopBuilder import org.utbot.framework.codegen.tree.CgStatementConstructor @@ -47,9 +48,9 @@ import org.utbot.framework.plugin.api.UtModel class JsCgStatementConstructor(context: CgContext) : CgStatementConstructor, CgContextOwner by context, - CgCallableAccessManager by CgTestClassConstructor.CgComponents.getCallableAccessManagerBy(context) { + CgCallableAccessManager by CgComponents.getCallableAccessManagerBy(context) { - private val nameGenerator = CgTestClassConstructor.CgComponents.getNameGeneratorBy(context) + private val nameGenerator = CgComponents.getNameGeneratorBy(context) override fun newVar( baseType: ClassId, diff --git a/utbot-js/src/main/kotlin/framework/codegen/model/constructor/tree/JsCgVariableConstructor.kt b/utbot-js/src/main/kotlin/framework/codegen/model/constructor/tree/JsCgVariableConstructor.kt index 17e6cec972..bab82320d9 100644 --- a/utbot-js/src/main/kotlin/framework/codegen/model/constructor/tree/JsCgVariableConstructor.kt +++ b/utbot-js/src/main/kotlin/framework/codegen/model/constructor/tree/JsCgVariableConstructor.kt @@ -9,13 +9,14 @@ import framework.api.js.JsPrimitiveModel import org.utbot.framework.codegen.domain.context.CgContext import org.utbot.framework.codegen.domain.models.CgLiteral import org.utbot.framework.codegen.domain.models.CgValue +import org.utbot.framework.codegen.tree.Cgcomponents import org.utbot.framework.codegen.tree.CgTestClassConstructor import org.utbot.framework.codegen.tree.CgVariableConstructor import org.utbot.framework.codegen.util.nullLiteral class JsCgVariableConstructor(ctx: CgContext) : CgVariableConstructor(ctx) { - private val nameGenerator = CgTestClassConstructor.CgComponents.getNameGeneratorBy(ctx) + private val nameGenerator = CgComponents.getNameGeneratorBy(ctx) override fun getOrCreateVariable(model: UtModel, name: String?): CgValue { val baseName = name ?: nameGenerator.nameFrom(model.classId) diff --git a/utbot-python/src/main/kotlin/org/utbot/python/framework/codegen/model/constructor/tree/PythonCgStatementConstructor.kt b/utbot-python/src/main/kotlin/org/utbot/python/framework/codegen/model/constructor/tree/PythonCgStatementConstructor.kt index dc6d583114..6f3f6fcde3 100644 --- a/utbot-python/src/main/kotlin/org/utbot/python/framework/codegen/model/constructor/tree/PythonCgStatementConstructor.kt +++ b/utbot-python/src/main/kotlin/org/utbot/python/framework/codegen/model/constructor/tree/PythonCgStatementConstructor.kt @@ -28,8 +28,6 @@ import org.utbot.framework.codegen.services.access.CgCallableAccessManager import org.utbot.framework.codegen.tree.CgForEachLoopBuilder import org.utbot.framework.codegen.tree.CgForLoopBuilder import org.utbot.framework.codegen.tree.CgStatementConstructor -import org.utbot.framework.codegen.tree.CgTestClassConstructor.CgComponents.getCallableAccessManagerBy -import org.utbot.framework.codegen.tree.CgTestClassConstructor.CgComponents.getNameGeneratorBy import org.utbot.framework.codegen.tree.ExpressionWithType import org.utbot.framework.codegen.tree.buildAssignment import org.utbot.framework.codegen.tree.buildCgForEachLoop @@ -46,6 +44,8 @@ import org.utbot.framework.plugin.api.ExecutableId import org.utbot.framework.plugin.api.FieldId import org.utbot.framework.plugin.api.UtModel import org.utbot.framework.plugin.api.util.objectClassId +import org.utbot.python.framework.codegen.PythonCgLanguageAssistant.getCallableAccessManagerBy +import org.utbot.python.framework.codegen.PythonCgLanguageAssistant.getNameGeneratorBy import org.utbot.python.framework.codegen.model.constructor.util.plus import java.util.* diff --git a/utbot-python/src/main/kotlin/org/utbot/python/framework/codegen/model/constructor/tree/PythonCgTestClassConstructor.kt b/utbot-python/src/main/kotlin/org/utbot/python/framework/codegen/model/constructor/tree/PythonCgTestClassConstructor.kt index e73e003cb4..593f64613f 100644 --- a/utbot-python/src/main/kotlin/org/utbot/python/framework/codegen/model/constructor/tree/PythonCgTestClassConstructor.kt +++ b/utbot-python/src/main/kotlin/org/utbot/python/framework/codegen/model/constructor/tree/PythonCgTestClassConstructor.kt @@ -3,10 +3,10 @@ package org.utbot.python.framework.codegen.model.constructor.tree import org.utbot.framework.codegen.domain.models.TestClassModel import org.utbot.framework.codegen.domain.context.CgContext import org.utbot.framework.codegen.domain.models.CgClassFile -import org.utbot.framework.codegen.tree.CgTestClassConstructor +import org.utbot.framework.codegen.tree.CgSimpleTestClassConstructor import org.utbot.framework.codegen.tree.buildClassFile -internal class PythonCgTestClassConstructor(context: CgContext) : CgTestClassConstructor(context) { +internal class PythonCgTestClassConstructor(context: CgContext) : CgSimpleTestClassConstructor(context) { override fun construct(testClassModel: TestClassModel): CgClassFile { return buildClassFile { this.declaredClass = withTestClassScope { diff --git a/utbot-python/src/main/kotlin/org/utbot/python/framework/codegen/model/constructor/tree/PythonCgVariableConstructor.kt b/utbot-python/src/main/kotlin/org/utbot/python/framework/codegen/model/constructor/tree/PythonCgVariableConstructor.kt index 21d4072c86..34af29be22 100644 --- a/utbot-python/src/main/kotlin/org/utbot/python/framework/codegen/model/constructor/tree/PythonCgVariableConstructor.kt +++ b/utbot-python/src/main/kotlin/org/utbot/python/framework/codegen/model/constructor/tree/PythonCgVariableConstructor.kt @@ -5,7 +5,7 @@ import org.utbot.framework.codegen.domain.models.CgConstructorCall import org.utbot.framework.codegen.domain.models.CgLiteral import org.utbot.framework.codegen.domain.models.CgValue import org.utbot.framework.codegen.domain.models.CgVariable -import org.utbot.framework.codegen.tree.CgTestClassConstructor +import org.utbot.framework.codegen.tree.CgComponents import org.utbot.framework.codegen.tree.CgVariableConstructor import org.utbot.framework.plugin.api.ConstructorId import org.utbot.framework.plugin.api.UtModel @@ -13,7 +13,7 @@ import org.utbot.python.framework.api.python.* import org.utbot.python.framework.codegen.model.tree.* class PythonCgVariableConstructor(context_: CgContext) : CgVariableConstructor(context_) { - private val nameGenerator = CgTestClassConstructor.CgComponents.getNameGeneratorBy(context) + private val nameGenerator = CgComponents.getNameGeneratorBy(context) override fun getOrCreateVariable(model: UtModel, name: String?): CgValue { val baseName = name ?: nameGenerator.nameFrom(model.classId)