1
+ package org.utbot.fuzzer.objects
2
+
3
+ import org.utbot.framework.plugin.api.ClassId
4
+ import org.utbot.framework.plugin.api.ExecutableId
5
+ import org.utbot.framework.plugin.api.MethodId
6
+ import org.utbot.framework.plugin.api.UtAssembleModel
7
+ import org.utbot.framework.plugin.api.UtCompositeModel
8
+ import org.utbot.framework.plugin.api.UtDirectSetFieldModel
9
+ import org.utbot.framework.plugin.api.UtExecutableCallModel
10
+ import org.utbot.framework.plugin.api.UtModel
11
+ import org.utbot.framework.plugin.api.UtStatementModel
12
+
13
+ /* *
14
+ * Implements [MethodId] but also can supply a mock for this execution.
15
+ *
16
+ * Simplest example: setter and getter,
17
+ * when this methodId is a setter, getter can be used for a mock to supply correct value.
18
+ */
19
+ internal class FuzzerMockableMethodId (
20
+ classId : ClassId ,
21
+ name : String ,
22
+ returnType : ClassId ,
23
+ parameters : List <ClassId >,
24
+ val mock : () -> Map <ExecutableId , List <UtModel >> = { emptyMap() },
25
+ ) : MethodId(classId, name, returnType, parameters) {
26
+
27
+ constructor (copyOf: MethodId , mock: () -> Map <ExecutableId , List <UtModel >> = { emptyMap() }) : this (
28
+ copyOf.classId, copyOf.name, copyOf.returnType, copyOf.parameters, mock
29
+ )
30
+
31
+ }
32
+
33
+ internal fun MethodId.toFuzzerMockable (block : suspend SequenceScope <Pair <MethodId , List <UtModel >>>.() -> Unit ): FuzzerMockableMethodId {
34
+ return FuzzerMockableMethodId (this ) {
35
+ sequence { block() }.toMap()
36
+ }
37
+ }
38
+
39
+ internal fun replaceWithMock (assembleModel : UtModel , shouldMock : (ClassId ) -> Boolean ): UtModel = when {
40
+ assembleModel !is UtAssembleModel -> assembleModel
41
+ shouldMock(assembleModel.classId) -> createMockModelFromFuzzerMockable(assembleModel, shouldMock)
42
+ else -> updateInnerModels(assembleModel, shouldMock)
43
+ }
44
+
45
+ private fun createMockModelFromFuzzerMockable (model : UtAssembleModel , shouldMock : (ClassId ) -> Boolean ): UtCompositeModel {
46
+ val mock = UtCompositeModel (model.id, model.classId, true )
47
+ for (mutator in model.modificationsChain) {
48
+ if (mutator is UtDirectSetFieldModel ) {
49
+ mock.fields[mutator.fieldId] = replaceWithMock(mutator.fieldModel, shouldMock)
50
+ }
51
+ if (mutator is UtExecutableCallModel && mutator.executable is FuzzerMockableMethodId ) {
52
+ (mutator.executable as FuzzerMockableMethodId ).mock().forEach { (executionId, models) ->
53
+ mock.mocks[executionId] = models.map { p -> replaceWithMock(p, shouldMock) }
54
+ }
55
+ }
56
+ }
57
+ return mock
58
+ }
59
+
60
+ private fun updateInnerModels (model : UtAssembleModel , shouldMock : (ClassId ) -> Boolean ): UtAssembleModel {
61
+ val models = model.modificationsChain.map { call ->
62
+ var mockedStatementModel: UtStatementModel ? = null
63
+ when (call) {
64
+ is UtDirectSetFieldModel -> {
65
+ val mock = replaceWithMock(call.fieldModel, shouldMock)
66
+ if (mock != call.fieldModel) {
67
+ mockedStatementModel = UtDirectSetFieldModel (call.instance, call.fieldId, mock)
68
+ }
69
+ }
70
+ is UtExecutableCallModel -> {
71
+ val params = call.params.map { m -> replaceWithMock(m, shouldMock) }
72
+ if (params != call.params) {
73
+ mockedStatementModel = UtExecutableCallModel (call.instance, call.executable, params)
74
+ }
75
+ }
76
+ }
77
+ mockedStatementModel ? : call
78
+ }
79
+ return with (model) {
80
+ UtAssembleModel (id, classId, modelName, instantiationCall, origin) { models }
81
+ }
82
+ }
0 commit comments