1
1
package org.utbot.instrumentation.instrumentation.execution.constructors
2
2
3
- import java.lang.reflect.Modifier
4
- import java.util.IdentityHashMap
5
- import kotlin.reflect.KClass
6
3
import org.mockito.Mockito
7
4
import org.mockito.stubbing.Answer
8
5
import org.objectweb.asm.Type
9
6
import org.utbot.common.Reflection
10
7
import org.utbot.common.invokeCatching
11
- import org.utbot.framework.plugin.api.util.constructor.CapturedArgument
12
- import org.utbot.framework.plugin.api.util.constructor.constructLambda
13
- import org.utbot.framework.plugin.api.util.constructor.constructStaticLambda
14
- import org.utbot.instrumentation.instrumentation.execution.mock.InstanceMockController
15
- import org.utbot.instrumentation.instrumentation.execution.mock.InstrumentationContext
16
- import org.utbot.instrumentation.instrumentation.execution.mock.MethodMockController
17
- import org.utbot.instrumentation.instrumentation.execution.mock.MockController
18
8
import org.utbot.framework.plugin.api.ClassId
19
9
import org.utbot.framework.plugin.api.ConstructorId
20
10
import org.utbot.framework.plugin.api.ExecutableId
21
11
import org.utbot.framework.plugin.api.FieldId
22
- import org.utbot.framework.plugin.api.FieldMockTarget
23
12
import org.utbot.framework.plugin.api.MethodId
24
- import org.utbot.framework.plugin.api.MockId
25
- import org.utbot.framework.plugin.api.MockInfo
26
- import org.utbot.framework.plugin.api.MockTarget
27
- import org.utbot.framework.plugin.api.ObjectMockTarget
28
- import org.utbot.framework.plugin.api.ParameterMockTarget
29
13
import org.utbot.framework.plugin.api.UtArrayModel
30
14
import org.utbot.framework.plugin.api.UtAssembleModel
31
15
import org.utbot.framework.plugin.api.UtClassRefModel
@@ -35,24 +19,32 @@ import org.utbot.framework.plugin.api.UtDirectSetFieldModel
35
19
import org.utbot.framework.plugin.api.UtEnumConstantModel
36
20
import org.utbot.framework.plugin.api.UtExecutableCallModel
37
21
import org.utbot.framework.plugin.api.UtLambdaModel
38
- import org.utbot.framework.plugin.api.UtMockValue
39
22
import org.utbot.framework.plugin.api.UtModel
40
23
import org.utbot.framework.plugin.api.UtNewInstanceInstrumentation
41
24
import org.utbot.framework.plugin.api.UtNullModel
42
25
import org.utbot.framework.plugin.api.UtPrimitiveModel
43
26
import org.utbot.framework.plugin.api.UtReferenceModel
44
27
import org.utbot.framework.plugin.api.UtStaticMethodInstrumentation
45
28
import org.utbot.framework.plugin.api.UtVoidModel
46
- import org.utbot.framework.plugin.api.isMockModel
29
+ import org.utbot.framework.plugin.api.util.anyInstance
47
30
import org.utbot.framework.plugin.api.util.constructor
31
+ import org.utbot.framework.plugin.api.util.constructor.CapturedArgument
32
+ import org.utbot.framework.plugin.api.util.constructor.constructLambda
33
+ import org.utbot.framework.plugin.api.util.constructor.constructStaticLambda
48
34
import org.utbot.framework.plugin.api.util.executableId
49
35
import org.utbot.framework.plugin.api.util.isStatic
50
36
import org.utbot.framework.plugin.api.util.jClass
51
37
import org.utbot.framework.plugin.api.util.jField
52
38
import org.utbot.framework.plugin.api.util.method
53
39
import org.utbot.framework.plugin.api.util.utContext
54
- import org.utbot.framework.plugin.api.util.anyInstance
40
+ import org.utbot.instrumentation.instrumentation.execution.mock.InstanceMockController
41
+ import org.utbot.instrumentation.instrumentation.execution.mock.InstrumentationContext
42
+ import org.utbot.instrumentation.instrumentation.execution.mock.MethodMockController
43
+ import org.utbot.instrumentation.instrumentation.execution.mock.MockController
55
44
import org.utbot.instrumentation.process.runSandbox
45
+ import java.lang.reflect.Modifier
46
+ import java.util.*
47
+ import kotlin.reflect.KClass
56
48
57
49
/* *
58
50
* Constructs values (including mocks) from models.
@@ -82,39 +74,17 @@ class MockValueConstructor(
82
74
83
75
// TODO: JIRA:1379 -- replace UtReferenceModel with Int
84
76
private val constructedObjects = HashMap <UtReferenceModel , Any >()
85
- private val mockInfo = mutableListOf<MockInfo >()
86
- private var mockTarget: MockTarget ? = null
87
- private var mockCounter = 0
88
77
89
78
/* *
90
79
* Controllers contain info about mocked methods and have to be closed to restore initial state.
91
80
*/
92
81
private val controllers = mutableListOf<MockController >()
93
82
94
- /* *
95
- * Sets mock context (possible mock target) before block execution and restores previous one after block execution.
96
- */
97
- private inline fun <T > withMockTarget (target : MockTarget ? , block : () -> T ): T {
98
- val old = mockTarget
99
- try {
100
- mockTarget = target
101
- return block()
102
- } finally {
103
- mockTarget = old
104
- }
105
- }
106
-
107
83
fun constructMethodParameters (models : List <UtModel >): List <UtConcreteValue <* >> =
108
- models.mapIndexed { index, model ->
109
- val target = mockTarget(model) { ParameterMockTarget (model.classId.name, index) }
110
- construct(model, target)
111
- }
84
+ models.mapIndexed { _, model -> construct(model) }
112
85
113
86
fun constructStatics (staticsBefore : Map <FieldId , UtModel >): Map <FieldId , UtConcreteValue <* >> =
114
- staticsBefore.mapValues { (field, model) -> // TODO: refactor this
115
- val target = FieldMockTarget (model.classId.name, field.declaringClass.name, owner = null , field.name)
116
- construct(model, target)
117
- }
87
+ staticsBefore.mapValues { (_, model) -> construct(model) }
118
88
119
89
/* *
120
90
* Main construction method.
@@ -124,7 +94,7 @@ class MockValueConstructor(
124
94
*
125
95
* Takes mock creation context (possible mock target) to create mock if required.
126
96
*/
127
- private fun construct (model : UtModel , target : MockTarget ? ): UtConcreteValue <* > = withMockTarget(target) {
97
+ private fun construct (model : UtModel ): UtConcreteValue <* > =
128
98
when (model) {
129
99
is UtNullModel -> UtConcreteValue (null , model.classId.jClass)
130
100
is UtPrimitiveModel -> UtConcreteValue (model.value, model.classId.jClass)
@@ -138,7 +108,6 @@ class MockValueConstructor(
138
108
// PythonModel, JsUtModel may be here
139
109
else -> throw UnsupportedOperationException ()
140
110
}
141
- }
142
111
143
112
/* *
144
113
* Constructs an Enum<*> instance by model, uses reference-equality cache.
@@ -157,22 +126,6 @@ class MockValueConstructor(
157
126
private fun constructObject (model : UtCompositeModel ): Any {
158
127
constructedObjects[model]?.let { return it }
159
128
160
- this .mockTarget?.let { mockTarget ->
161
- model.mocks.forEach { (methodId, models) ->
162
- mockInfo + = MockInfo (mockTarget, methodId, models.map { model ->
163
- if (model.isMockModel()) {
164
- val mockId = MockId (" mock${++ mockCounter} " )
165
- // Call to "construct" method still required to collect mock interaction
166
- construct(model, ObjectMockTarget (model.classId.name, mockId))
167
- UtMockValue (mockId, model.classId.name)
168
- } else {
169
- construct(model, target = null )
170
- }
171
- })
172
- }
173
- }
174
-
175
-
176
129
val javaClass = javaClass(model.classId)
177
130
178
131
val classInstance = if (! model.isMock) {
@@ -181,9 +134,18 @@ class MockValueConstructor(
181
134
constructedObjects[model] = notMockInstance
182
135
notMockInstance
183
136
} else {
184
- val mockInstance = generateMockitoMock(javaClass, model.mocks)
137
+ val concreteValues = model.mocks.mapValues { mutableListOf<Any ?>() }
138
+ val mockInstance = generateMockitoMock(javaClass, concreteValues)
185
139
186
140
constructedObjects[model] = mockInstance
141
+
142
+ concreteValues.forEach { (executableId, valuesList) ->
143
+ val mockModels = model.mocks.getValue(executableId)
144
+ // If model is unit, then null should be returned (this model has to be already constructed).
145
+ val constructedValues = mockModels.map { model -> construct(model).value.takeIf { it != Unit } }
146
+ valuesList.addAll(constructedValues)
147
+ }
148
+
187
149
mockInstance
188
150
}
189
151
@@ -194,10 +156,7 @@ class MockValueConstructor(
194
156
195
157
check(Reflection .isModifiersAccessible())
196
158
197
- val target = mockTarget(fieldModel) {
198
- FieldMockTarget (fieldModel.classId.name, model.classId.name, UtConcreteValue (classInstance), fieldId.name)
199
- }
200
- val value = construct(fieldModel, target).value
159
+ val value = construct(fieldModel).value
201
160
val instance = if (Modifier .isStatic(declaredField.modifiers)) null else classInstance
202
161
declaredField.set(instance, value)
203
162
declaredField.isAccessible = accessible
@@ -206,16 +165,8 @@ class MockValueConstructor(
206
165
return classInstance
207
166
}
208
167
209
- private fun generateMockitoAnswer (methodToValues : Map <in ExecutableId , List <UtModel >>): Answer <* > {
210
- val pointers = methodToValues.mapValues { (_, _) -> 0 }.toMutableMap()
211
- val concreteValues = methodToValues.mapValues { (_, models) ->
212
- models.map { model ->
213
- val mockId = MockId (" mock${++ mockCounter} " )
214
- val target = mockTarget(model) { ObjectMockTarget (model.classId.name, mockId) }
215
- construct(model, target).value.takeIf { it != Unit } // if it is unit, then null should be returned
216
- // This model has to be already constructed, so it is OK to pass null as a target
217
- }
218
- }
168
+ private fun generateMockitoAnswer (concreteValues : Map <ExecutableId , List <Any ?>>): Answer <* > {
169
+ val pointers = concreteValues.mapValues { (_, _) -> 0 }.toMutableMap()
219
170
return Answer { invocation ->
220
171
with (invocation.method) {
221
172
pointers[executableId].let { pointer ->
@@ -232,8 +183,9 @@ class MockValueConstructor(
232
183
}
233
184
}
234
185
235
- private fun generateMockitoMock (clazz : Class <* >, mocks : Map <ExecutableId , List <UtModel >>): Any {
236
- return Mockito .mock(clazz, generateMockitoAnswer(mocks))
186
+ private fun generateMockitoMock (clazz : Class <* >, concreteValues : Map <ExecutableId , List <Any ?>>): Any {
187
+ val answer = generateMockitoAnswer(concreteValues)
188
+ return Mockito .mock(clazz, answer)
237
189
}
238
190
239
191
private fun computeConcreteValuesForMethods (
@@ -341,7 +293,7 @@ class MockValueConstructor(
341
293
constructedObjects[model] = instance
342
294
for (i in instance.indices) {
343
295
val elementModel = stores[i] ? : constModel
344
- val value = construct(elementModel, null ).value
296
+ val value = construct(elementModel).value
345
297
try {
346
298
java.lang.reflect.Array .set(instance, i, value)
347
299
} catch (iae: IllegalArgumentException ) {
@@ -435,7 +387,6 @@ class MockValueConstructor(
435
387
val instanceModel = directSetterModel.instance
436
388
val instance = value(instanceModel)
437
389
438
- val instanceClassId = instanceModel.classId
439
390
val fieldModel = directSetterModel.fieldModel
440
391
441
392
val field = directSetterModel.fieldId.jField
@@ -445,18 +396,8 @@ class MockValueConstructor(
445
396
// set field accessible to support protected or package-private direct setters
446
397
field.isAccessible = true
447
398
448
- // prepare mockTarget for field if it is a mock
449
- val mockTarget = mockTarget(fieldModel) {
450
- FieldMockTarget (
451
- fieldModel.classId.name,
452
- instanceClassId.name,
453
- UtConcreteValue (javaClass(instanceClassId).anyInstance),
454
- field.name
455
- )
456
- }
457
-
458
399
// construct and set the value
459
- val fieldValue = construct(fieldModel, mockTarget ).value
400
+ val fieldValue = construct(fieldModel).value
460
401
field.set(instance, fieldValue)
461
402
} finally {
462
403
// restore accessibility property of the field
@@ -467,14 +408,10 @@ class MockValueConstructor(
467
408
/* *
468
409
* Constructs value from [UtModel].
469
410
*/
470
- private fun value (model : UtModel ) = construct(model, null ).value
411
+ private fun value (model : UtModel ) = construct(model).value
471
412
472
413
private fun mockAndGet (model : UtModel ): Any? {
473
- val target = mockTarget(model) { // won't be called if model is not mockModel
474
- val mockId = MockId (" mock${++ mockCounter} " )
475
- ObjectMockTarget (model.classId.name, mockId)
476
- }
477
- return construct(model, target).value
414
+ return construct(model).value
478
415
}
479
416
480
417
private fun MethodId.call (args : List <Any ?>, instance : Any? ): Any? =
@@ -535,10 +472,4 @@ class MockValueConstructor(
535
472
fun resetMockedMethods () {
536
473
controllers.forEach { it.close() }
537
474
}
538
- }
539
-
540
- /* *
541
- * Creates mock target using init lambda if model represents mock or null otherwise.
542
- */
543
- private fun mockTarget (model : UtModel , init : () -> MockTarget ): MockTarget ? =
544
- if (model.isMockModel()) init () else null
475
+ }
0 commit comments