Skip to content

Commit f44dd6f

Browse files
CgSpringVariableConstructor refactoring #2326 (#2416)
--------- Co-authored-by: Egor Kulikov <[email protected]>
1 parent b051634 commit f44dd6f

File tree

4 files changed

+129
-60
lines changed

4 files changed

+129
-60
lines changed

utbot-framework/src/main/kotlin/org/utbot/framework/codegen/tree/CgAbstractSpringTestClassConstructor.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ abstract class CgAbstractSpringTestClassConstructor(context: CgContext):
114114
valueByUtModelWrapper[key] = createdVariable
115115
}
116116

117-
variableConstructor.annotatedModelVariables
117+
variableConstructor.annotatedModelGroups
118118
.getOrPut(annotationClassId) { mutableSetOf() } += listOfUtModels
119119
}
120120

@@ -133,7 +133,7 @@ abstract class CgAbstractSpringTestClassConstructor(context: CgContext):
133133
*/
134134
private fun clearUnwantedVariableModels() {
135135
val trustedListOfModels =
136-
variableConstructor.annotatedModelVariables.values.flatten() + listOf(UtSpringContextModel.wrap())
136+
variableConstructor.annotatedModelGroups.values.flatten() + listOf(UtSpringContextModel.wrap())
137137

138138
valueByUtModelWrapper
139139
.filterNot { it.key in trustedListOfModels }
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
package org.utbot.framework.codegen.tree
2+
3+
import org.utbot.framework.codegen.domain.UtModelWrapper
4+
import org.utbot.framework.codegen.domain.builtin.injectMocksClassId
5+
import org.utbot.framework.codegen.domain.builtin.mockClassId
6+
import org.utbot.framework.codegen.domain.context.CgContext
7+
import org.utbot.framework.codegen.domain.context.CgContextOwner
8+
import org.utbot.framework.codegen.domain.models.CgValue
9+
import org.utbot.framework.codegen.domain.models.CgVariable
10+
import org.utbot.framework.plugin.api.ClassId
11+
import org.utbot.framework.plugin.api.UtAssembleModel
12+
import org.utbot.framework.plugin.api.UtCompositeModel
13+
import org.utbot.framework.plugin.api.UtModel
14+
import org.utbot.framework.plugin.api.isMockModel
15+
import org.utbot.framework.plugin.api.util.SpringModelUtils.autowiredClassId
16+
import org.utbot.framework.plugin.api.util.SpringModelUtils.isAutowiredFromContext
17+
18+
sealed interface CgClassFieldManager : CgContextOwner {
19+
20+
val annotationType: ClassId
21+
22+
fun constructVariableForField(model: UtModel, modelVariable: CgValue): CgValue
23+
}
24+
25+
abstract class CgClassFieldManagerImpl(context: CgContext) :
26+
CgClassFieldManager,
27+
CgContextOwner by context {
28+
29+
val variableConstructor: CgSpringVariableConstructor by lazy {
30+
CgComponents.getVariableConstructorBy(context) as CgSpringVariableConstructor
31+
}
32+
}
33+
34+
class CgInjectingMocksFieldsManager(val context: CgContext) : CgClassFieldManagerImpl(context) {
35+
36+
override val annotationType = injectMocksClassId
37+
38+
override fun constructVariableForField(model: UtModel, modelVariable: CgValue): CgValue {
39+
val modelFields = when (model) {
40+
is UtCompositeModel -> model.fields
41+
is UtAssembleModel -> model.origin?.fields
42+
else -> null
43+
}
44+
45+
modelFields?.forEach { (fieldId, fieldModel) ->
46+
//creating variables for modelVariable fields
47+
val variableForField = variableConstructor.getOrCreateVariable(fieldModel)
48+
49+
// If field model is a mock, it is set in the connected with instance under test automatically via @InjectMocks;
50+
// Otherwise we need to set this field manually.
51+
if (!fieldModel.isMockModel()) {
52+
variableConstructor.setFieldValue(modelVariable, fieldId, variableForField)
53+
}
54+
}
55+
56+
return modelVariable
57+
}
58+
59+
}
60+
61+
class CgMockedFieldsManager(context: CgContext) : CgClassFieldManagerImpl(context) {
62+
63+
override val annotationType = mockClassId
64+
65+
override fun constructVariableForField(model: UtModel, modelVariable: CgValue): CgValue {
66+
if (model.isMockModel()) {
67+
variableConstructor.mockFrameworkManager.createMockForVariable(
68+
model as UtCompositeModel,
69+
modelVariable as CgVariable,
70+
)
71+
}
72+
return modelVariable
73+
}
74+
75+
}
76+
77+
class CgAutowiredFieldsManager(context: CgContext) : CgClassFieldManagerImpl(context) {
78+
79+
override val annotationType = autowiredClassId
80+
81+
override fun constructVariableForField(model: UtModel, modelVariable: CgValue): CgValue {
82+
return when {
83+
model.isAutowiredFromContext() -> {
84+
variableConstructor.constructAssembleForVariable(model as UtAssembleModel)
85+
}
86+
87+
else -> error("Trying to autowire model $model but it is not appropriate")
88+
}
89+
}
90+
}
91+
92+
class ClassFieldManagerFacade(context: CgContext) : CgContextOwner by context {
93+
94+
private val injectingMocksFieldsManager = CgInjectingMocksFieldsManager(context)
95+
private val mockedFieldsManager = CgMockedFieldsManager(context)
96+
private val autowiredFieldsManager = CgAutowiredFieldsManager(context)
97+
98+
fun constructVariableForField(
99+
model: UtModel,
100+
annotatedModelGroups: Map<ClassId, Set<UtModelWrapper>>,
101+
): CgValue? {
102+
val annotationManagers = listOf(injectingMocksFieldsManager, mockedFieldsManager, autowiredFieldsManager)
103+
104+
annotationManagers.forEach { manager ->
105+
val alreadyCreatedVariable = findCgValueByModel(model, annotatedModelGroups[manager.annotationType])
106+
107+
if (alreadyCreatedVariable != null) {
108+
return manager.constructVariableForField(model, alreadyCreatedVariable)
109+
}
110+
}
111+
112+
return null
113+
}
114+
115+
private fun findCgValueByModel(model: UtModel, setOfModels: Set<UtModelWrapper>?): CgValue? {
116+
val key = setOfModels?.find { it == model.wrap() } ?: return null
117+
return valueByUtModelWrapper[key]
118+
}
119+
}
Lines changed: 5 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1,68 +1,23 @@
11
package org.utbot.framework.codegen.tree
22

33
import org.utbot.framework.codegen.domain.UtModelWrapper
4-
import org.utbot.framework.codegen.domain.builtin.injectMocksClassId
5-
import org.utbot.framework.codegen.domain.builtin.mockClassId
64
import org.utbot.framework.codegen.domain.context.CgContext
75
import org.utbot.framework.codegen.domain.models.CgLiteral
86
import org.utbot.framework.codegen.domain.models.CgValue
9-
import org.utbot.framework.codegen.domain.models.CgVariable
107
import org.utbot.framework.plugin.api.ClassId
11-
import org.utbot.framework.plugin.api.UtAssembleModel
12-
import org.utbot.framework.plugin.api.UtCompositeModel
138
import org.utbot.framework.plugin.api.UtModel
149
import org.utbot.framework.plugin.api.UtSpringContextModel
15-
import org.utbot.framework.plugin.api.isMockModel
16-
import org.utbot.framework.plugin.api.util.SpringModelUtils.autowiredClassId
17-
import org.utbot.framework.plugin.api.util.SpringModelUtils.isAutowiredFromContext
1810
import org.utbot.framework.plugin.api.util.stringClassId
1911

2012
class CgSpringVariableConstructor(context: CgContext) : CgVariableConstructor(context) {
21-
val annotatedModelVariables: MutableMap<ClassId, MutableSet<UtModelWrapper>> = mutableMapOf()
13+
val annotatedModelGroups: MutableMap<ClassId, MutableSet<UtModelWrapper>> = mutableMapOf()
2214

23-
override fun getOrCreateVariable(model: UtModel, name: String?): CgValue {
24-
val alreadyCreatedInjectMocks = findCgValueByModel(model, annotatedModelVariables[injectMocksClassId])
25-
if (alreadyCreatedInjectMocks != null) {
26-
val modelFields = when (model) {
27-
is UtCompositeModel -> model.fields
28-
is UtAssembleModel -> model.origin?.fields
29-
else -> null
30-
}
31-
32-
modelFields?.forEach{ (fieldId, fieldModel) ->
33-
val variableForField = getOrCreateVariable(fieldModel)
34-
35-
// If field model is a mock, it is set in the connected with instance under test automatically via @InjectMocks;
36-
// Otherwise we need to set this field manually.
37-
if(!fieldModel.isMockModel()) {
38-
setFieldValue(alreadyCreatedInjectMocks, fieldId, variableForField)
39-
}
40-
}
41-
42-
return alreadyCreatedInjectMocks
43-
}
44-
45-
val alreadyCreatedMock = findCgValueByModel(model, annotatedModelVariables[mockClassId])
46-
if (alreadyCreatedMock != null) {
47-
if (model.isMockModel()) {
48-
mockFrameworkManager.createMockForVariable(
49-
model as UtCompositeModel,
50-
alreadyCreatedMock as CgVariable,
51-
)
52-
}
15+
private val classFieldManager = ClassFieldManagerFacade(context)
5316

54-
return alreadyCreatedMock
55-
}
17+
override fun getOrCreateVariable(model: UtModel, name: String?): CgValue {
18+
val variable = classFieldManager.constructVariableForField(model, annotatedModelGroups)
5619

57-
val alreadyCreatedAutowired = findCgValueByModel(model, annotatedModelVariables[autowiredClassId])
58-
if (alreadyCreatedAutowired != null) {
59-
return when {
60-
model.isAutowiredFromContext() -> {
61-
super.constructAssembleForVariable(model as UtAssembleModel)
62-
}
63-
else -> error("Trying to autowire model $model but it is not appropriate")
64-
}
65-
}
20+
variable?.let { return it }
6621

6722
return when (model) {
6823
is UtSpringContextModel -> createApplicationContextVariable()
@@ -80,9 +35,4 @@ class CgSpringVariableConstructor(context: CgContext) : CgVariableConstructor(co
8035
valueByUtModelWrapper[UtSpringContextModel.wrap()] = it
8136
}
8237
}
83-
84-
private fun findCgValueByModel(model: UtModel, setOfModels: Set<UtModelWrapper>?): CgValue? {
85-
val key = setOfModels?.find { it == model.wrap() } ?: return null
86-
return valueByUtModelWrapper[key]
87-
}
8838
}

utbot-framework/src/main/kotlin/org/utbot/framework/codegen/tree/CgVariableConstructor.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ open class CgVariableConstructor(val context: CgContext) :
6464
CgStatementConstructor by getStatementConstructorBy(context) {
6565

6666
private val nameGenerator = getNameGeneratorBy(context)
67-
protected val mockFrameworkManager = getMockFrameworkManagerBy(context)
67+
val mockFrameworkManager = getMockFrameworkManagerBy(context)
6868

6969
/**
7070
* Take already created CgValue or construct either a new [CgVariable] or new [CgLiteral] for the given model.
@@ -176,7 +176,7 @@ open class CgVariableConstructor(val context: CgContext) :
176176
return obj
177177
}
178178

179-
protected fun setFieldValue(obj: CgValue, fieldId: FieldId, variableForField: CgValue){
179+
fun setFieldValue(obj: CgValue, fieldId: FieldId, variableForField: CgValue){
180180
val field = fieldId.jField
181181
val fieldFromVariableSpecifiedType = obj.type.findFieldByIdOrNull(fieldId)
182182

@@ -219,7 +219,7 @@ open class CgVariableConstructor(val context: CgContext) :
219219
.also { valueByUtModelWrapper[model.wrap()] = it }
220220
}
221221

222-
protected fun constructAssembleForVariable(model: UtAssembleModel): CgValue {
222+
fun constructAssembleForVariable(model: UtAssembleModel): CgValue {
223223
for (statementModel in model.modificationsChain) {
224224
when (statementModel) {
225225
is UtDirectSetFieldModel -> {

0 commit comments

Comments
 (0)