Skip to content

Commit

Permalink
Address comments in #2447
Browse files Browse the repository at this point in the history
  • Loading branch information
IlyaMuravjov committed Jul 31, 2023
1 parent 06a2ebd commit e5dd7c1
Show file tree
Hide file tree
Showing 25 changed files with 134 additions and 105 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -576,9 +576,20 @@ data class UtArrayModel(
override fun hashCode(): Int = id
}

interface UtModelWithOrigin {
val origin: UtCompositeModel?
}
/**
* Wrapper of [origin] model, that can be handled in a different
* way in some situations (e.g. during value construction).
*/
sealed class UtModelWithCompositeOrigin(
id: Int?,
classId: ClassId,
modelName: String = id.toString(),
open val origin: UtCompositeModel?,
) : UtReferenceModel(
id = id,
classId = classId,
modelName = modelName
)

/**
* Model for complex objects with assemble instructions.
Expand All @@ -595,7 +606,7 @@ data class UtAssembleModel private constructor(
val instantiationCall: UtStatementCallModel,
val modificationsChain: List<UtStatementModel>,
override val origin: UtCompositeModel?
) : UtReferenceModel(id, classId, modelName), UtModelWithOrigin {
) : UtModelWithCompositeOrigin(id, classId, modelName, origin) {

/**
* Creates a new [UtAssembleModel].
Expand Down Expand Up @@ -737,11 +748,11 @@ class UtLambdaModel(
* Common parent of all framework-specific models (e.g. Spring-specific models)
*/
abstract class UtCustomModel(
override val origin: UtCompositeModel? = null,
id: Int?,
classId: ClassId,
modelName: String = id.toString()
) : UtReferenceModel(id, classId, modelName), UtModelWithOrigin
modelName: String = id.toString(),
override val origin: UtCompositeModel? = null,
) : UtModelWithCompositeOrigin(id, classId, modelName, origin)

object UtSpringContextModel : UtCustomModel(
id = null,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ object SpringModelUtils {
private val mockMvcRequestBuildersClassId = ClassId("org.springframework.test.web.servlet.request.MockMvcRequestBuilders")
private val requestBuilderClassId = ClassId("org.springframework.test.web.servlet.RequestBuilder")
val resultActionsClassId = ClassId("org.springframework.test.web.servlet.ResultActions")
private val mockMvcClassId = ClassId("org.springframework.test.web.servlet.MockMvc")
val mockMvcClassId = ClassId("org.springframework.test.web.servlet.MockMvc")
private val mvcResultClassId = ClassId("org.springframework.test.web.servlet.MvcResult")
private val resultHandlerClassId = ClassId("org.springframework.test.web.servlet.ResultHandler")
val mockMvcResultHandlersClassId = ClassId("org.springframework.test.web.servlet.result.MockMvcResultHandlers")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import org.utbot.framework.plugin.api.ClassId
import org.utbot.framework.plugin.api.UtAssembleModel
import org.utbot.framework.plugin.api.UtCompositeModel
import org.utbot.framework.plugin.api.UtModel
import org.utbot.framework.plugin.api.UtModelWithOrigin
import org.utbot.framework.plugin.api.UtModelWithCompositeOrigin
import org.utbot.framework.plugin.api.isMockModel
import org.utbot.framework.plugin.api.util.SpringModelUtils.autowiredClassId
import org.utbot.framework.plugin.api.util.SpringModelUtils.isAutowiredFromContext
Expand Down Expand Up @@ -48,7 +48,7 @@ class CgInjectingMocksFieldsManager(val context: CgContext) : CgClassFieldManage
override fun constructVariableForField(model: UtModel, modelVariable: CgValue): CgValue {
val modelFields = when (model) {
is UtCompositeModel -> model.fields
is UtModelWithOrigin -> model.origin?.fields
is UtModelWithCompositeOrigin -> model.origin?.fields
else -> null
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ import org.utbot.framework.plugin.api.UtExecutionSuccess
import org.utbot.framework.plugin.api.UtExplicitlyThrownException
import org.utbot.framework.plugin.api.UtLambdaModel
import org.utbot.framework.plugin.api.UtModel
import org.utbot.framework.plugin.api.UtModelWithOrigin
import org.utbot.framework.plugin.api.UtModelWithCompositeOrigin
import org.utbot.framework.plugin.api.UtNewInstanceInstrumentation
import org.utbot.framework.plugin.api.UtNullModel
import org.utbot.framework.plugin.api.UtOverflowFailure
Expand Down Expand Up @@ -1069,7 +1069,7 @@ open class CgMethodConstructor(val context: CgContext) : CgContextOwner by conte
when (model) {
is UtCompositeModel -> collectExecutionsResultFieldsRecursively(model, 0)

is UtModelWithOrigin -> model.origin?.let {
is UtModelWithCompositeOrigin -> model.origin?.let {
collectExecutionsResultFieldsRecursively(it, 0)
}

Expand Down Expand Up @@ -1109,7 +1109,7 @@ open class CgMethodConstructor(val context: CgContext) : CgContextOwner by conte
when (fieldModel) {
is UtCompositeModel -> collectExecutionsResultFieldsRecursively(fieldModel, depth + 1)

is UtModelWithOrigin -> fieldModel.origin?.let {
is UtModelWithCompositeOrigin -> fieldModel.origin?.let {
collectExecutionsResultFieldsRecursively(it, depth + 1)
}

Expand Down Expand Up @@ -1201,7 +1201,10 @@ open class CgMethodConstructor(val context: CgContext) : CgContextOwner by conte
expectedVariableName: String = "expected",
emptyLineIfNeeded: Boolean = false,
) {
if (expected !is UtCustomModel || !customAssertConstructor.tryConstructCustomAssert(expected, actual)) {
val successfullyConstructedCustomAssert = expected is UtCustomModel &&
customAssertConstructor.tryConstructCustomAssert(expected, actual)

if (!successfullyConstructedCustomAssert) {
val expectedVariable = variableConstructor.getOrCreateVariable(expected, expectedVariableName)
if (emptyLineIfNeeded) emptyLineIfNeeded()
assertEquality(expectedVariable, actual)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,12 @@ package org.utbot.framework.codegen.tree

import org.utbot.framework.codegen.domain.context.CgContext
import org.utbot.framework.codegen.domain.context.CgContextOwner
import org.utbot.framework.codegen.domain.models.AnnotationTarget
import org.utbot.framework.codegen.domain.models.CgVariable
import org.utbot.framework.codegen.services.access.CgCallableAccessManager
import org.utbot.framework.codegen.services.access.CgCallableAccessManagerImpl
import org.utbot.framework.codegen.tree.CgComponents.getStatementConstructorBy
import org.utbot.framework.plugin.api.UtCustomModel
import org.utbot.framework.plugin.api.UtSpringMockMvcResultActionsModel
import org.utbot.framework.plugin.api.util.SpringModelUtils.autoConfigureMockMvcClassId
import org.utbot.framework.plugin.api.util.SpringModelUtils.contentMatchersStringMethodId
import org.utbot.framework.plugin.api.util.SpringModelUtils.mockMvcResultHandlersClassId
import org.utbot.framework.plugin.api.util.SpringModelUtils.mockMvcResultMatchersClassId
Expand All @@ -34,20 +32,18 @@ class CgMockMvcResultActionsAssertConstructor(
CgCallableAccessManager by CgCallableAccessManagerImpl(context) {
override fun tryConstructCustomAssert(expected: UtCustomModel, actual: CgVariable): Boolean {
if (expected is UtSpringMockMvcResultActionsModel) {
addAnnotation(autoConfigureMockMvcClassId, AnnotationTarget.Class)
var expr = actual[resultActionsAndDoMethodId](mockMvcResultHandlersClassId[resultHandlersPrintMethodId]())
expr = expr[resultActionsAndExpectMethodId](
+actual[resultActionsAndDoMethodId](mockMvcResultHandlersClassId[resultHandlersPrintMethodId]())
+actual[resultActionsAndExpectMethodId](
mockMvcResultMatchersClassId[resultMatchersStatusMethodId]()[statusMatchersIsMethodId](expected.status)
)
expected.viewName?.let { viewName ->
expr = expr[resultActionsAndExpectMethodId](
+actual[resultActionsAndExpectMethodId](
mockMvcResultMatchersClassId[resultMatchersViewMethodId]()[viewMatchersNameMethodId](viewName)
)
}
expr = expr[resultActionsAndExpectMethodId](
+actual[resultActionsAndExpectMethodId](
mockMvcResultMatchersClassId[resultMatchersContentMethodId]()[contentMatchersStringMethodId](expected.contentAsString)
)
+expr
return true
} else
return delegateAssertConstructor.tryConstructCustomAssert(expected, actual)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import org.utbot.framework.plugin.api.ConcreteContextLoadingResult
import org.utbot.framework.plugin.api.SpringSettings.*
import org.utbot.framework.plugin.api.SpringConfiguration.*
import org.utbot.framework.plugin.api.util.IndentUtil.TAB
import org.utbot.framework.plugin.api.util.SpringModelUtils
import org.utbot.framework.plugin.api.util.SpringModelUtils.activeProfilesClassId
import org.utbot.framework.plugin.api.util.SpringModelUtils.autoConfigureTestDbClassId
import org.utbot.framework.plugin.api.util.SpringModelUtils.bootstrapWithClassId
Expand All @@ -25,6 +26,7 @@ import org.utbot.framework.plugin.api.util.SpringModelUtils.crudRepositoryClassI
import org.utbot.framework.plugin.api.util.SpringModelUtils.dirtiesContextClassId
import org.utbot.framework.plugin.api.util.SpringModelUtils.dirtiesContextClassModeClassId
import org.utbot.framework.plugin.api.util.SpringModelUtils.extendWithClassId
import org.utbot.framework.plugin.api.util.SpringModelUtils.mockMvcClassId
import org.utbot.framework.plugin.api.util.SpringModelUtils.runWithClassId
import org.utbot.framework.plugin.api.util.SpringModelUtils.springBootTestClassId
import org.utbot.framework.plugin.api.util.SpringModelUtils.springBootTestContextBootstrapperClassId
Expand All @@ -47,7 +49,7 @@ class CgSpringIntegrationTestClassConstructor(
}

override fun constructTestClass(testClassModel: SpringTestClassModel): CgClass {
addNecessarySpringSpecificAnnotations()
addNecessarySpringSpecificAnnotations(testClassModel)
return super.constructTestClass(testClassModel)
}

Expand Down Expand Up @@ -102,7 +104,7 @@ class CgSpringIntegrationTestClassConstructor(
.map { it.escapeControlChars() }
)

private fun addNecessarySpringSpecificAnnotations() {
private fun addNecessarySpringSpecificAnnotations(testClassModel: SpringTestClassModel) {
val isSpringBootTestAccessible = utContext.classLoader.tryLoadClass(springBootTestClassId.name) != null
if (isSpringBootTestAccessible) {
addAnnotation(springBootTestClassId, Class)
Expand Down Expand Up @@ -193,5 +195,8 @@ class CgSpringIntegrationTestClassConstructor(
// generated tests will fail with `ClassNotFoundException: org.springframework.dao.DataAccessException`.
if (utContext.classLoader.tryLoadClass(crudRepositoryClassId.name) != null)
addAnnotation(autoConfigureTestDbClassId, Class)

if (mockMvcClassId in testClassModel.springSpecificInformation.autowiredFromContextModels)
addAnnotation(SpringModelUtils.autoConfigureMockMvcClassId, Class)
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.utbot.framework.codegen.tree

import mu.KotlinLogging
import org.utbot.common.isStatic
import org.utbot.framework.codegen.domain.builtin.forName
import org.utbot.framework.codegen.domain.builtin.setArrayElement
Expand Down Expand Up @@ -68,6 +69,10 @@ open class CgVariableConstructor(val context: CgContext) :
CgCallableAccessManager by getCallableAccessManagerBy(context),
CgStatementConstructor by getStatementConstructorBy(context) {

companion object {
private val logger = KotlinLogging.logger {}
}

private val nameGenerator = getNameGeneratorBy(context)
val mockFrameworkManager = getMockFrameworkManagerBy(context)

Expand Down Expand Up @@ -99,7 +104,7 @@ open class CgVariableConstructor(val context: CgContext) :
constructValueByModel(model, name)
}

open fun constructValueByModel(model: UtModel, name: String?): CgValue {
private fun constructValueByModel(model: UtModel, name: String?): CgValue {
// name could be taken from existing names, or be specified manually, or be created from generator
val baseName = name ?: nameGenerator.nameFrom(model.classId)

Expand All @@ -112,7 +117,12 @@ open class CgVariableConstructor(val context: CgContext) :
is UtLambdaModel -> constructLambda(model, baseName)
is UtNullModel -> nullLiteral()
is UtPrimitiveModel -> CgLiteral(model.classId, model.value)
is UtCustomModel -> constructValueByModel(model.origin ?: error("Can't construct value for custom model without origin [$model]"), name)
is UtCustomModel -> {
logger.error { "Unexpected behaviour: value for UtCustomModel [$model] is constructed by base CgVariableConstructor" }
constructValueByModel(
model.origin ?: error("Can't construct value for UtCustomModel without origin [$model]"), name
)
}
is UtReferenceModel -> error("Unexpected UtReferenceModel: ${model::class}")
is UtVoidModel -> error("Unexpected UtVoidModel: ${model::class}")
else -> error("Unexpected UtModel: ${model::class}")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import org.utbot.framework.plugin.api.UtEnumConstantModel
import org.utbot.framework.plugin.api.UtExecution
import org.utbot.framework.plugin.api.UtLambdaModel
import org.utbot.framework.plugin.api.UtModel
import org.utbot.framework.plugin.api.UtModelWithOrigin
import org.utbot.framework.plugin.api.UtModelWithCompositeOrigin
import org.utbot.framework.plugin.api.UtNullModel
import org.utbot.framework.plugin.api.UtPrimitiveModel
import org.utbot.framework.plugin.api.UtReferenceModel
Expand Down Expand Up @@ -106,15 +106,15 @@ class ExecutionStateAnalyzer(val execution: UtExecution) {
var modelBefore = before

if (before::class != after::class) {
if (before is UtModelWithOrigin && after is UtModelWithOrigin && before.origin != null) {
if (before is UtModelWithCompositeOrigin && after is UtModelWithCompositeOrigin && before.origin != null) {
modelBefore = before.origin ?: unreachableBranch("We have already checked the origin for a null value")
} else {
doNotRun {
// it is ok because we might have modelBefore with some absent fields (i.e. statics), but
// modelAfter (constructed by concrete executor) will consist all these fields,
// therefore, AssembleModelGenerator won't be able to transform the given composite model

val reason = if (before is UtModelWithOrigin && after is UtCompositeModel) {
val reason = if (before is UtModelWithCompositeOrigin && after is UtCompositeModel) {
"ModelBefore is an UtModelWithOrigin and ModelAfter " +
"is a CompositeModel, but modelBefore doesn't have an origin model."
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ class SimpleUtExecutionInstrumentation(
delegateInstrumentation.getStaticField(fieldId).map { value ->
UtModelConstructor.createOnlyUserClassesConstructor(
pathsToUserClasses = pathsToUserClasses,
utCustomModelConstructorFinder = instrumentationContext::findUtCustomModelConstructor
utModelWithCompositeOriginConstructorFinder = instrumentationContext::findUtModelWithCompositeOriginConstructor
).construct(value, fieldId.type)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import org.utbot.framework.plugin.api.util.jClass
import org.utbot.framework.plugin.api.util.primitiveWrappers
import org.utbot.framework.plugin.api.util.voidWrapperClassId

val javaStdLibCustomModelConstructors: Map<Class<*>, () -> UtCustomModelConstructor> =
val javaStdLibModelWithCompositeOriginConstructors: Map<Class<*>, () -> UtModelWithCompositeOriginConstructor> =
mutableMapOf<Class<*>, () -> UtAssembleModelConstructorBase>(
/**
* Optionals
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ internal fun findStreamConstructor(stream: BaseStream<*, *>): UtAssembleModelCon
else -> BaseStreamConstructor()
}

internal abstract class UtAssembleModelConstructorBase : UtCustomModelConstructor {
override fun constructCustomModel(
internal abstract class UtAssembleModelConstructorBase : UtModelWithCompositeOriginConstructor {
override fun constructModelWithCompositeOrigin(
internalConstructor: UtModelConstructorInterface,
value: Any,
valueClassId: ClassId,
Expand Down

This file was deleted.

Loading

0 comments on commit e5dd7c1

Please sign in to comment.