Skip to content

Commit d464a34

Browse files
Merge branch 'main' into alisevych/ui_tests_correction
2 parents a62a11b + abb6268 commit d464a34

File tree

17 files changed

+323
-93
lines changed

17 files changed

+323
-93
lines changed

gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ commonsIoVersion=2.8.0
6060
kotlinLoggingVersion=1.8.3
6161
ktorVersion=1.4.1
6262
cliktVersion=3.2.0
63-
guavaVersion=30.0-jre
63+
guavaVersion=32.1.2-jre
6464
apacheCommonsExecVersion=1.2
6565
apacheCommonsTextVersion=1.9
6666
rgxgenVersion=1.3

utbot-framework-api/src/main/kotlin/org/utbot/framework/plugin/api/util/IdUtil.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,11 @@ val streamToArrayMethodId = methodId(streamClassId, "toArray", objectArrayClassI
324324

325325
val dateClassId = java.util.Date::class.id
326326

327+
fun getArrayClassIdByElementClassId(elementClassId: ClassId): ClassId{
328+
val elementClass = utContext.classLoader.loadClass(elementClassId.name)
329+
return java.lang.reflect.Array.newInstance(elementClass,0)::class.java.id
330+
}
331+
327332
@Suppress("RemoveRedundantQualifierName")
328333
val primitiveToId: Map<Class<*>, ClassId> = mapOf(
329334
java.lang.Void.TYPE to voidClassId,

utbot-framework-api/src/main/kotlin/org/utbot/framework/plugin/api/util/SpringModelUtils.kt

Lines changed: 132 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,9 @@ object SpringModelUtils {
126126
private val pathVariableClassId = ClassId("org.springframework.web.bind.annotation.PathVariable")
127127
private val requestHeaderClassId = ClassId("org.springframework.web.bind.annotation.RequestHeader")
128128
private val cookieValueClassId = ClassId("org.springframework.web.bind.annotation.CookieValue")
129+
private val requestAttributesClassId = ClassId("org.springframework.web.bind.annotation.RequestAttribute")
130+
private val sessionAttributesClassId = ClassId("org.springframework.web.bind.annotation.SessionAttribute")
131+
private val modelAttributesClassId = ClassId("org.springframework.web.bind.annotation.ModelAttribute")
129132
private val requestBodyClassId = ClassId("org.springframework.web.bind.annotation.RequestBody")
130133
private val requestParamClassId = ClassId("org.springframework.web.bind.annotation.RequestParam")
131134
private val uriComponentsBuilderClassId = ClassId("org.springframework.web.util.UriComponentsBuilder")
@@ -151,6 +154,55 @@ object SpringModelUtils {
151154
private val objectMapperClassId = ClassId("com.fasterxml.jackson.databind.ObjectMapper")
152155
private val cookieClassId = ClassId("javax.servlet.http.Cookie")
153156

157+
private val requestAttributesMethodId = MethodId(
158+
classId = mockHttpServletRequestBuilderClassId,
159+
name = "requestAttr",
160+
returnType = mockHttpServletRequestBuilderClassId,
161+
parameters = listOf(stringClassId, objectClassId)
162+
)
163+
164+
private val sessionAttributesMethodId = MethodId(
165+
classId = mockHttpServletRequestBuilderClassId,
166+
name = "sessionAttr",
167+
returnType = mockHttpServletRequestBuilderClassId,
168+
parameters = listOf(stringClassId, objectClassId)
169+
)
170+
171+
private val modelAttributesMethodId = MethodId(
172+
classId = mockHttpServletRequestBuilderClassId,
173+
name = "flashAttr",
174+
returnType = mockHttpServletRequestBuilderClassId,
175+
parameters = listOf(stringClassId, objectClassId)
176+
)
177+
178+
private val mockHttpServletHeadersMethodId = MethodId(
179+
classId = mockHttpServletRequestBuilderClassId,
180+
name = "headers",
181+
returnType = mockHttpServletRequestBuilderClassId,
182+
parameters = listOf(httpHeaderClassId)
183+
)
184+
185+
private val mockHttpServletCookieMethodId = MethodId(
186+
classId = mockHttpServletRequestBuilderClassId,
187+
name = "cookie",
188+
returnType = mockHttpServletRequestBuilderClassId,
189+
parameters = listOf(getArrayClassIdByElementClassId(cookieClassId))
190+
)
191+
192+
private val mockHttpServletContentTypeMethodId = MethodId(
193+
classId = mockHttpServletRequestBuilderClassId,
194+
name = "contentType",
195+
returnType = mockHttpServletRequestBuilderClassId,
196+
parameters = listOf(mediaTypeClassId)
197+
)
198+
199+
private val mockHttpServletContentMethodId = MethodId(
200+
classId = mockHttpServletRequestBuilderClassId,
201+
name = "content",
202+
returnType = mockHttpServletRequestBuilderClassId,
203+
parameters = listOf(stringClassId)
204+
)
205+
154206
val mockMvcPerformMethodId = MethodId(
155207
classId = mockMvcClassId,
156208
name = "perform",
@@ -299,7 +351,7 @@ object SpringModelUtils {
299351

300352
val requestParamsModel = createRequestParamsModel(methodId, arguments, idGenerator)
301353

302-
val urlTemplateModel = createUrlTemplateModel(pathVariablesModel, requestParamsModel, requestPath, idGenerator)
354+
val urlTemplateModel = createUrlTemplateModel(requestPath, pathVariablesModel, requestParamsModel, idGenerator)
303355

304356
var requestBuilderModel = UtAssembleModel(
305357
id = idGenerator(),
@@ -322,22 +374,89 @@ object SpringModelUtils {
322374
)
323375

324376
val headersContentModel = createHeadersContentModel(methodId, arguments, idGenerator)
325-
326377
requestBuilderModel = addHeadersToRequestBuilderModel(headersContentModel, requestBuilderModel, idGenerator)
327378

328-
val cookieClass = utContext.classLoader.loadClass(cookieClassId.name)
329-
val cookieArrayClassId = java.lang.reflect.Array.newInstance(cookieClass,0)::class.java.id
330-
val cookieValuesModel = createCookieValuesModel(cookieArrayClassId, methodId, arguments, idGenerator)
379+
val cookieValuesModel = createCookieValuesModel(methodId, arguments, idGenerator)
380+
requestBuilderModel =
381+
addCookiesToRequestBuilderModel(cookieValuesModel, requestBuilderModel, idGenerator)
382+
383+
val requestAttributes = collectArgumentsWithAnnotationModels(methodId, requestAttributesClassId, arguments)
384+
requestBuilderModel =
385+
addRequestAttributesToRequestModelBuilder(requestAttributes, requestBuilderModel, idGenerator)
386+
387+
val sessionAttributes = collectArgumentsWithAnnotationModels(methodId, sessionAttributesClassId, arguments)
388+
requestBuilderModel =
389+
addSessionAttributesToRequestModelBuilder(sessionAttributes, requestBuilderModel, idGenerator)
331390

391+
val modelAttributes = collectArgumentsWithAnnotationModels(methodId, modelAttributesClassId, arguments)
332392
requestBuilderModel =
333-
addCookiesToRequestBuilderModel(cookieValuesModel, cookieArrayClassId, requestBuilderModel, idGenerator)
393+
addModelAttributesToRequestModelBuilder(modelAttributes, requestBuilderModel, idGenerator)
334394

335395
return addContentToRequestBuilderModel(methodId, arguments, requestBuilderModel, idGenerator)
336396
}
337397

398+
private fun addRequestAttributesToRequestModelBuilder(
399+
requestAttributes: Map<String, UtModel>,
400+
requestBuilderModel: UtAssembleModel,
401+
idGenerator: () -> Int
402+
): UtAssembleModel = addAttributesToRequestBuilderModel(
403+
requestAttributes,
404+
requestAttributesMethodId,
405+
requestBuilderModel,
406+
idGenerator
407+
)
408+
409+
410+
private fun addSessionAttributesToRequestModelBuilder(
411+
sessionAttributes: Map<String, UtModel>,
412+
requestBuilderModel: UtAssembleModel,
413+
idGenerator: () -> Int
414+
): UtAssembleModel = addAttributesToRequestBuilderModel(
415+
sessionAttributes,
416+
sessionAttributesMethodId,
417+
requestBuilderModel,
418+
idGenerator
419+
)
420+
421+
private fun addModelAttributesToRequestModelBuilder(
422+
modelAttributes: Map<String, UtModel>,
423+
requestBuilderModel: UtAssembleModel,
424+
idGenerator: () -> Int
425+
): UtAssembleModel = addAttributesToRequestBuilderModel(
426+
modelAttributes,
427+
modelAttributesMethodId,
428+
requestBuilderModel,
429+
idGenerator
430+
)
431+
432+
433+
private fun addAttributesToRequestBuilderModel(
434+
attributes: Map<String, UtModel>,
435+
addAttributesMethodId: MethodId,
436+
requestBuilderModel: UtAssembleModel,
437+
idGenerator: () -> Int
438+
): UtAssembleModel{
439+
@Suppress("NAME_SHADOWING")
440+
var requestBuilderModel = requestBuilderModel
441+
442+
attributes.forEach { (name, model) ->
443+
requestBuilderModel = UtAssembleModel(
444+
id = idGenerator(),
445+
classId = mockHttpServletRequestBuilderClassId,
446+
modelName = "requestBuilder",
447+
instantiationCall = UtExecutableCallModel(
448+
instance = requestBuilderModel,
449+
executable = addAttributesMethodId,
450+
params = listOf(UtPrimitiveModel(name), model)
451+
)
452+
)
453+
}
454+
455+
return requestBuilderModel
456+
}
457+
338458
private fun addCookiesToRequestBuilderModel(
339459
cookieValuesModel: UtArrayModel,
340-
cookieArrayClassId: ClassId,
341460
requestBuilderModel: UtAssembleModel,
342461
idGenerator: () -> Int
343462
): UtAssembleModel {
@@ -351,12 +470,7 @@ object SpringModelUtils {
351470
modelName = "requestBuilder",
352471
instantiationCall = UtExecutableCallModel(
353472
instance = requestBuilderModel,
354-
executable = MethodId(
355-
classId = mockHttpServletRequestBuilderClassId,
356-
name = "cookie",
357-
returnType = mockHttpServletRequestBuilderClassId,
358-
parameters = listOf(cookieArrayClassId)
359-
),
473+
executable = mockHttpServletCookieMethodId,
360474
params = listOf(cookieValuesModel)
361475
)
362476
)
@@ -407,12 +521,7 @@ object SpringModelUtils {
407521
modelName = "requestBuilder",
408522
instantiationCall = UtExecutableCallModel(
409523
instance = requestBuilderModel,
410-
executable = MethodId(
411-
classId = mockHttpServletRequestBuilderClassId,
412-
name = "headers",
413-
returnType = mockHttpServletRequestBuilderClassId,
414-
parameters = listOf(httpHeaderClassId)
415-
),
524+
executable = mockHttpServletHeadersMethodId,
416525
params = listOf(headers)
417526
)
418527
)
@@ -454,12 +563,7 @@ object SpringModelUtils {
454563
modelName = "requestBuilder",
455564
instantiationCall = UtExecutableCallModel(
456565
instance = requestBuilderModel,
457-
executable = MethodId(
458-
classId = mockHttpServletRequestBuilderClassId,
459-
name = "contentType",
460-
returnType = mockHttpServletRequestBuilderClassId,
461-
parameters = listOf(mediaTypeClassId)
462-
),
566+
executable = mockHttpServletContentTypeMethodId,
463567
params = listOf(
464568
mediaTypeModel
465569
)
@@ -491,12 +595,7 @@ object SpringModelUtils {
491595
modelName = "requestBuilder",
492596
instantiationCall = UtExecutableCallModel(
493597
instance = requestBuilderModel,
494-
executable = MethodId(
495-
classId = mockHttpServletRequestBuilderClassId,
496-
name = "content",
497-
returnType = mockHttpServletRequestBuilderClassId,
498-
parameters = listOf(stringClassId)
499-
),
598+
executable = mockHttpServletContentMethodId,
500599
params = listOf(content)
501600
)
502601
)
@@ -505,7 +604,6 @@ object SpringModelUtils {
505604
}
506605

507606
private fun createCookieValuesModel(
508-
cookieArrayClassId: ClassId,
509607
methodId: MethodId,
510608
arguments: List<UtModel>,
511609
idGenerator: () -> Int,
@@ -530,7 +628,7 @@ object SpringModelUtils {
530628

531629
return UtArrayModel(
532630
id = idGenerator(),
533-
classId = cookieArrayClassId,
631+
classId = getArrayClassIdByElementClassId(cookieClassId),
534632
length = cookieValues.size,
535633
constModel = UtNullModel(cookieClassId),
536634
stores = indexedCookieValues,
@@ -687,9 +785,9 @@ object SpringModelUtils {
687785
}
688786

689787
private fun createUrlTemplateModel(
788+
requestPath: String,
690789
pathVariablesModel: UtAssembleModel,
691790
requestParamModel: List<Pair<UtPrimitiveModel, UtAssembleModel>>,
692-
requestPath: String,
693791
idGenerator: () -> Int
694792
): UtModel {
695793
val requestPathModel = UtPrimitiveModel(requestPath)

utbot-framework/build.gradle

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ plugins {
44

55
configurations {
66
fetchSpringAnalyzerJar
7+
fetchSpringCommonsJar
78
fetchInstrumentationJar
89
}
910

@@ -51,6 +52,7 @@ dependencies {
5152
implementation project(':utbot-spring-commons-api')
5253
implementation project(':utbot-spring-analyzer')
5354
fetchSpringAnalyzerJar project(path: ':utbot-spring-analyzer', configuration: 'springAnalyzerJar')
55+
fetchSpringCommonsJar project(path: ':utbot-spring-commons', configuration: 'springCommonsJar')
5456
}
5557

5658
processResources {
@@ -61,4 +63,8 @@ processResources {
6163
from(configurations.fetchSpringAnalyzerJar) {
6264
into "lib"
6365
}
66+
67+
from(configurations.fetchSpringCommonsJar) {
68+
into "lib"
69+
}
6470
}

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,11 @@ import org.utbot.framework.codegen.tree.CgComponents.getStatementConstructorBy
6464
import org.utbot.framework.codegen.tree.CgComponents.getTestFrameworkManagerBy
6565
import org.utbot.framework.codegen.tree.CgComponents.getVariableConstructorBy
6666
import org.utbot.framework.codegen.util.canBeReadFrom
67+
import org.utbot.framework.codegen.util.canBeReadViaGetterFrom
6768
import org.utbot.framework.codegen.util.canBeSetFrom
6869
import org.utbot.framework.codegen.util.equalTo
6970
import org.utbot.framework.codegen.util.escapeControlChars
71+
import org.utbot.framework.codegen.util.getter
7072
import org.utbot.framework.codegen.util.inc
7173
import org.utbot.framework.codegen.util.length
7274
import org.utbot.framework.codegen.util.lessThan
@@ -1154,6 +1156,10 @@ open class CgMethodConstructor(val context: CgContext) : CgContextOwner by conte
11541156
// and is accessible from current package
11551157
if (variable.type.hasField(this) && canBeReadFrom(context, variable.type)) {
11561158
if (jField.isStatic) CgStaticFieldAccess(this) else CgFieldAccess(variable, this)
1159+
} else if (context.codegenLanguage == CodegenLanguage.JAVA &&
1160+
!jField.isStatic && canBeReadViaGetterFrom(context)
1161+
) {
1162+
CgMethodCall(variable, getter, emptyList())
11571163
} else {
11581164
utilsClassId[getFieldValue](variable, this.declaringClass.name, this.name)
11591165
}

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,15 @@ import org.utbot.framework.codegen.tree.CgComponents.getNameGeneratorBy
1414
import org.utbot.framework.codegen.tree.CgComponents.getStatementConstructorBy
1515
import org.utbot.framework.codegen.util.at
1616
import org.utbot.framework.codegen.util.canBeSetFrom
17+
import org.utbot.framework.codegen.util.canBeSetViaSetterFrom
1718
import org.utbot.framework.codegen.util.fieldThatIsGotWith
1819
import org.utbot.framework.codegen.util.fieldThatIsSetWith
1920
import org.utbot.framework.codegen.util.inc
2021
import org.utbot.framework.codegen.util.isAccessibleFrom
2122
import org.utbot.framework.codegen.util.lessThan
2223
import org.utbot.framework.codegen.util.nullLiteral
2324
import org.utbot.framework.codegen.util.resolve
25+
import org.utbot.framework.codegen.util.setter
2426
import org.utbot.framework.plugin.api.BuiltinClassId
2527
import org.utbot.framework.plugin.api.ClassId
2628
import org.utbot.framework.plugin.api.FieldId
@@ -209,6 +211,10 @@ open class CgVariableConstructor(val context: CgContext) :
209211
// TODO: check if it is correct to use declaringClass of a field here
210212
val fieldAccess = if (field.isStatic) CgStaticFieldAccess(fieldId) else CgFieldAccess(obj, fieldId)
211213
fieldAccess `=` valueForField
214+
} else if (context.codegenLanguage == CodegenLanguage.JAVA &&
215+
!field.isStatic && fieldId.canBeSetViaSetterFrom(context)
216+
) {
217+
+CgMethodCall(obj, fieldId.setter, listOf(valueForField))
212218
} else {
213219
// composite models must not have info about static fields, hence only non-static fields are set here
214220
+utilsClassId[setField](obj, fieldId.declaringClass.name, fieldId.name, valueForField)

utbot-framework/src/main/kotlin/org/utbot/framework/codegen/util/FieldIdUtil.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ fun FieldId.isAccessibleFrom(packageName: String, callerClassId: ClassId): Boole
3636
return isClassAccessible && isAccessibleFromPackageByModifiers
3737
}
3838

39-
private fun FieldId.canBeReadViaGetterFrom(context: CgContext): Boolean =
39+
internal fun FieldId.canBeReadViaGetterFrom(context: CgContext): Boolean =
4040
declaringClass.allMethods.contains(getter) && getter.isAccessibleFrom(context.testClassPackageName)
4141

4242
/**
@@ -52,7 +52,7 @@ internal fun FieldId.canBeReadFrom(context: CgContext, callerClassId: ClassId):
5252
return isAccessibleFrom(context.testClassPackageName, callerClassId)
5353
}
5454

55-
private fun FieldId.canBeSetViaSetterFrom(context: CgContext): Boolean =
55+
internal fun FieldId.canBeSetViaSetterFrom(context: CgContext): Boolean =
5656
declaringClass.allMethods.contains(setter) && setter.isAccessibleFrom(context.testClassPackageName)
5757

5858
/**

0 commit comments

Comments
 (0)