From 570b50eff0088770e7af937a88a10e9c538dec45 Mon Sep 17 00:00:00 2001 From: Kirill Shishin Date: Thu, 17 Aug 2023 01:14:47 +0300 Subject: [PATCH 1/2] Add support for attributes annotations --- .../plugin/api/util/SpringModelUtils.kt | 102 +++++++++++++++++- 1 file changed, 98 insertions(+), 4 deletions(-) diff --git a/utbot-framework-api/src/main/kotlin/org/utbot/framework/plugin/api/util/SpringModelUtils.kt b/utbot-framework-api/src/main/kotlin/org/utbot/framework/plugin/api/util/SpringModelUtils.kt index e59aebe155..32911a9792 100644 --- a/utbot-framework-api/src/main/kotlin/org/utbot/framework/plugin/api/util/SpringModelUtils.kt +++ b/utbot-framework-api/src/main/kotlin/org/utbot/framework/plugin/api/util/SpringModelUtils.kt @@ -126,6 +126,9 @@ object SpringModelUtils { private val pathVariableClassId = ClassId("org.springframework.web.bind.annotation.PathVariable") private val requestHeaderClassId = ClassId("org.springframework.web.bind.annotation.RequestHeader") private val cookieValueClassId = ClassId("org.springframework.web.bind.annotation.CookieValue") + private val requestAttributesClassId = ClassId("org.springframework.web.bind.annotation.RequestAttribute") + private val sessionAttributesClassId = ClassId("org.springframework.web.bind.annotation.SessionAttribute") + private val modelAttributesClassId = ClassId("org.springframework.web.bind.annotation.ModelAttribute") private val requestBodyClassId = ClassId("org.springframework.web.bind.annotation.RequestBody") private val requestParamClassId = ClassId("org.springframework.web.bind.annotation.RequestParam") private val uriComponentsBuilderClassId = ClassId("org.springframework.web.util.UriComponentsBuilder") @@ -151,6 +154,27 @@ object SpringModelUtils { private val objectMapperClassId = ClassId("com.fasterxml.jackson.databind.ObjectMapper") private val cookieClassId = ClassId("javax.servlet.http.Cookie") + private val requestAttributesMethodId = MethodId( + classId = mockHttpServletRequestBuilderClassId, + name = "requestAttr", + returnType = mockHttpServletRequestBuilderClassId, + parameters = listOf(stringClassId, objectClassId) + ) + + private val sessionAttributesMethodId = MethodId( + classId = mockHttpServletRequestBuilderClassId, + name = "sessionAttr", + returnType = mockHttpServletRequestBuilderClassId, + parameters = listOf(stringClassId, objectClassId) + ) + + private val modelAttributesMethodId = MethodId( + classId = mockHttpServletRequestBuilderClassId, + name = "flashAttr", + returnType = mockHttpServletRequestBuilderClassId, + parameters = listOf(stringClassId, objectClassId) + ) + val mockMvcPerformMethodId = MethodId( classId = mockMvcClassId, name = "perform", @@ -299,7 +323,7 @@ object SpringModelUtils { val requestParamsModel = createRequestParamsModel(methodId, arguments, idGenerator) - val urlTemplateModel = createUrlTemplateModel(pathVariablesModel, requestParamsModel, requestPath, idGenerator) + val urlTemplateModel = createUrlTemplateModel(requestPath, pathVariablesModel, requestParamsModel, idGenerator) var requestBuilderModel = UtAssembleModel( id = idGenerator(), @@ -322,19 +346,89 @@ object SpringModelUtils { ) val headersContentModel = createHeadersContentModel(methodId, arguments, idGenerator) - requestBuilderModel = addHeadersToRequestBuilderModel(headersContentModel, requestBuilderModel, idGenerator) val cookieClass = utContext.classLoader.loadClass(cookieClassId.name) val cookieArrayClassId = java.lang.reflect.Array.newInstance(cookieClass,0)::class.java.id val cookieValuesModel = createCookieValuesModel(cookieArrayClassId, methodId, arguments, idGenerator) - requestBuilderModel = addCookiesToRequestBuilderModel(cookieValuesModel, cookieArrayClassId, requestBuilderModel, idGenerator) + val requestAttributes = collectArgumentsWithAnnotationModels(methodId, requestAttributesClassId, arguments) + requestBuilderModel = + addRequestAttributesToRequestModelBuilder(requestAttributes, requestBuilderModel, idGenerator) + + val sessionAttributes = collectArgumentsWithAnnotationModels(methodId, sessionAttributesClassId, arguments) + requestBuilderModel = + addSessionAttributesToRequestModelBuilder(sessionAttributes, requestBuilderModel, idGenerator) + + val modelAttributes = collectArgumentsWithAnnotationModels(methodId, modelAttributesClassId, arguments) + requestBuilderModel = + addModelAttributesToRequestModelBuilder(modelAttributes, requestBuilderModel, idGenerator) + return addContentToRequestBuilderModel(methodId, arguments, requestBuilderModel, idGenerator) } + private fun addRequestAttributesToRequestModelBuilder( + requestAttributes: Map, + requestBuilderModel: UtAssembleModel, + idGenerator: () -> Int + ): UtAssembleModel = addAttributesModelToRequestBuilderModel( + requestAttributes, + requestAttributesMethodId, + requestBuilderModel, + idGenerator + ) + + + private fun addSessionAttributesToRequestModelBuilder( + requestAttributes: Map, + requestBuilderModel: UtAssembleModel, + idGenerator: () -> Int + ): UtAssembleModel = addAttributesModelToRequestBuilderModel( + requestAttributes, + sessionAttributesMethodId, + requestBuilderModel, + idGenerator + ) + + private fun addModelAttributesToRequestModelBuilder( + requestAttributes: Map, + requestBuilderModel: UtAssembleModel, + idGenerator: () -> Int + ): UtAssembleModel = addAttributesModelToRequestBuilderModel( + requestAttributes, + modelAttributesMethodId, + requestBuilderModel, + idGenerator + ) + + + private fun addAttributesModelToRequestBuilderModel( + attributes: Map, + addAttributesMethodId: MethodId, + requestBuilderModel: UtAssembleModel, + idGenerator: () -> Int + ): UtAssembleModel{ + @Suppress("NAME_SHADOWING") + var requestBuilderModel = requestBuilderModel + + attributes.forEach { (name, model) -> + requestBuilderModel = UtAssembleModel( + id = idGenerator(), + classId = mockHttpServletRequestBuilderClassId, + modelName = "requestBuilder", + instantiationCall = UtExecutableCallModel( + instance = requestBuilderModel, + executable = addAttributesMethodId, + params = listOf(UtPrimitiveModel(name), model) + ) + ) + } + + return requestBuilderModel + } + private fun addCookiesToRequestBuilderModel( cookieValuesModel: UtArrayModel, cookieArrayClassId: ClassId, @@ -687,9 +781,9 @@ object SpringModelUtils { } private fun createUrlTemplateModel( + requestPath: String, pathVariablesModel: UtAssembleModel, requestParamModel: List>, - requestPath: String, idGenerator: () -> Int ): UtModel { val requestPathModel = UtPrimitiveModel(requestPath) From e618f02ff73dd5937aae233a7b5c6b0162da6deb Mon Sep 17 00:00:00 2001 From: Kirill Shishin Date: Thu, 17 Aug 2023 13:08:26 +0300 Subject: [PATCH 2/2] Add `methodId`s for `mockHttpServletRequestBuilder` --- .../utbot/framework/plugin/api/util/IdUtil.kt | 5 ++ .../plugin/api/util/SpringModelUtils.kt | 82 ++++++++++--------- 2 files changed, 48 insertions(+), 39 deletions(-) diff --git a/utbot-framework-api/src/main/kotlin/org/utbot/framework/plugin/api/util/IdUtil.kt b/utbot-framework-api/src/main/kotlin/org/utbot/framework/plugin/api/util/IdUtil.kt index 17b2aeed54..b4e6ed66de 100644 --- a/utbot-framework-api/src/main/kotlin/org/utbot/framework/plugin/api/util/IdUtil.kt +++ b/utbot-framework-api/src/main/kotlin/org/utbot/framework/plugin/api/util/IdUtil.kt @@ -322,6 +322,11 @@ val streamToArrayMethodId = methodId(streamClassId, "toArray", objectArrayClassI val dateClassId = java.util.Date::class.id +fun getArrayClassIdByElementClassId(elementClassId: ClassId): ClassId{ + val elementClass = utContext.classLoader.loadClass(elementClassId.name) + return java.lang.reflect.Array.newInstance(elementClass,0)::class.java.id +} + @Suppress("RemoveRedundantQualifierName") val primitiveToId: Map, ClassId> = mapOf( java.lang.Void.TYPE to voidClassId, diff --git a/utbot-framework-api/src/main/kotlin/org/utbot/framework/plugin/api/util/SpringModelUtils.kt b/utbot-framework-api/src/main/kotlin/org/utbot/framework/plugin/api/util/SpringModelUtils.kt index 32911a9792..daf71ffa1a 100644 --- a/utbot-framework-api/src/main/kotlin/org/utbot/framework/plugin/api/util/SpringModelUtils.kt +++ b/utbot-framework-api/src/main/kotlin/org/utbot/framework/plugin/api/util/SpringModelUtils.kt @@ -175,6 +175,34 @@ object SpringModelUtils { parameters = listOf(stringClassId, objectClassId) ) + private val mockHttpServletHeadersMethodId = MethodId( + classId = mockHttpServletRequestBuilderClassId, + name = "headers", + returnType = mockHttpServletRequestBuilderClassId, + parameters = listOf(httpHeaderClassId) + ) + + private val mockHttpServletCookieMethodId = MethodId( + classId = mockHttpServletRequestBuilderClassId, + name = "cookie", + returnType = mockHttpServletRequestBuilderClassId, + parameters = listOf(getArrayClassIdByElementClassId(cookieClassId)) + ) + + private val mockHttpServletContentTypeMethodId = MethodId( + classId = mockHttpServletRequestBuilderClassId, + name = "contentType", + returnType = mockHttpServletRequestBuilderClassId, + parameters = listOf(mediaTypeClassId) + ) + + private val mockHttpServletContentMethodId = MethodId( + classId = mockHttpServletRequestBuilderClassId, + name = "content", + returnType = mockHttpServletRequestBuilderClassId, + parameters = listOf(stringClassId) + ) + val mockMvcPerformMethodId = MethodId( classId = mockMvcClassId, name = "perform", @@ -348,11 +376,9 @@ object SpringModelUtils { val headersContentModel = createHeadersContentModel(methodId, arguments, idGenerator) requestBuilderModel = addHeadersToRequestBuilderModel(headersContentModel, requestBuilderModel, idGenerator) - val cookieClass = utContext.classLoader.loadClass(cookieClassId.name) - val cookieArrayClassId = java.lang.reflect.Array.newInstance(cookieClass,0)::class.java.id - val cookieValuesModel = createCookieValuesModel(cookieArrayClassId, methodId, arguments, idGenerator) + val cookieValuesModel = createCookieValuesModel(methodId, arguments, idGenerator) requestBuilderModel = - addCookiesToRequestBuilderModel(cookieValuesModel, cookieArrayClassId, requestBuilderModel, idGenerator) + addCookiesToRequestBuilderModel(cookieValuesModel, requestBuilderModel, idGenerator) val requestAttributes = collectArgumentsWithAnnotationModels(methodId, requestAttributesClassId, arguments) requestBuilderModel = @@ -373,7 +399,7 @@ object SpringModelUtils { requestAttributes: Map, requestBuilderModel: UtAssembleModel, idGenerator: () -> Int - ): UtAssembleModel = addAttributesModelToRequestBuilderModel( + ): UtAssembleModel = addAttributesToRequestBuilderModel( requestAttributes, requestAttributesMethodId, requestBuilderModel, @@ -382,29 +408,29 @@ object SpringModelUtils { private fun addSessionAttributesToRequestModelBuilder( - requestAttributes: Map, + sessionAttributes: Map, requestBuilderModel: UtAssembleModel, idGenerator: () -> Int - ): UtAssembleModel = addAttributesModelToRequestBuilderModel( - requestAttributes, + ): UtAssembleModel = addAttributesToRequestBuilderModel( + sessionAttributes, sessionAttributesMethodId, requestBuilderModel, idGenerator ) private fun addModelAttributesToRequestModelBuilder( - requestAttributes: Map, + modelAttributes: Map, requestBuilderModel: UtAssembleModel, idGenerator: () -> Int - ): UtAssembleModel = addAttributesModelToRequestBuilderModel( - requestAttributes, + ): UtAssembleModel = addAttributesToRequestBuilderModel( + modelAttributes, modelAttributesMethodId, requestBuilderModel, idGenerator ) - private fun addAttributesModelToRequestBuilderModel( + private fun addAttributesToRequestBuilderModel( attributes: Map, addAttributesMethodId: MethodId, requestBuilderModel: UtAssembleModel, @@ -431,7 +457,6 @@ object SpringModelUtils { private fun addCookiesToRequestBuilderModel( cookieValuesModel: UtArrayModel, - cookieArrayClassId: ClassId, requestBuilderModel: UtAssembleModel, idGenerator: () -> Int ): UtAssembleModel { @@ -445,12 +470,7 @@ object SpringModelUtils { modelName = "requestBuilder", instantiationCall = UtExecutableCallModel( instance = requestBuilderModel, - executable = MethodId( - classId = mockHttpServletRequestBuilderClassId, - name = "cookie", - returnType = mockHttpServletRequestBuilderClassId, - parameters = listOf(cookieArrayClassId) - ), + executable = mockHttpServletCookieMethodId, params = listOf(cookieValuesModel) ) ) @@ -501,12 +521,7 @@ object SpringModelUtils { modelName = "requestBuilder", instantiationCall = UtExecutableCallModel( instance = requestBuilderModel, - executable = MethodId( - classId = mockHttpServletRequestBuilderClassId, - name = "headers", - returnType = mockHttpServletRequestBuilderClassId, - parameters = listOf(httpHeaderClassId) - ), + executable = mockHttpServletHeadersMethodId, params = listOf(headers) ) ) @@ -548,12 +563,7 @@ object SpringModelUtils { modelName = "requestBuilder", instantiationCall = UtExecutableCallModel( instance = requestBuilderModel, - executable = MethodId( - classId = mockHttpServletRequestBuilderClassId, - name = "contentType", - returnType = mockHttpServletRequestBuilderClassId, - parameters = listOf(mediaTypeClassId) - ), + executable = mockHttpServletContentTypeMethodId, params = listOf( mediaTypeModel ) @@ -585,12 +595,7 @@ object SpringModelUtils { modelName = "requestBuilder", instantiationCall = UtExecutableCallModel( instance = requestBuilderModel, - executable = MethodId( - classId = mockHttpServletRequestBuilderClassId, - name = "content", - returnType = mockHttpServletRequestBuilderClassId, - parameters = listOf(stringClassId) - ), + executable = mockHttpServletContentMethodId, params = listOf(content) ) ) @@ -599,7 +604,6 @@ object SpringModelUtils { } private fun createCookieValuesModel( - cookieArrayClassId: ClassId, methodId: MethodId, arguments: List, idGenerator: () -> Int, @@ -624,7 +628,7 @@ object SpringModelUtils { return UtArrayModel( id = idGenerator(), - classId = cookieArrayClassId, + classId = getArrayClassIdByElementClassId(cookieClassId), length = cookieValues.size, constModel = UtNullModel(cookieClassId), stores = indexedCookieValues,