@@ -212,8 +212,9 @@ internal class CgMethodConstructor(val context: CgContext) : CgContextOwner by c
212
212
* Thus, this method only caches an actual initial static fields state in order to recover it
213
213
* at the end of the test, and it has nothing to do with the 'before' and 'after' caches.
214
214
*/
215
- private fun rememberInitialStaticFields () {
216
- for ((field, _) in currentExecution!! .stateBefore.statics.accessibleFields()) {
215
+ private fun rememberInitialStaticFields (statics : Map <FieldId , UtModel >) {
216
+ val accessibleStaticFields = statics.accessibleFields()
217
+ for ((field, _) in accessibleStaticFields) {
217
218
val declaringClass = field.declaringClass
218
219
val fieldAccessible = field.isAccessibleFrom(testClassPackageName)
219
220
@@ -236,11 +237,18 @@ internal class CgMethodConstructor(val context: CgContext) : CgContextOwner by c
236
237
}
237
238
}
238
239
239
- private fun mockStaticFields () {
240
- for ((field, model) in currentExecution!! .stateBefore.statics.accessibleFields()) {
240
+ private fun substituteStaticFields (statics : Map <FieldId , UtModel >, isParametrized : Boolean = false) {
241
+ val accessibleStaticFields = statics.accessibleFields()
242
+ for ((field, model) in accessibleStaticFields) {
241
243
val declaringClass = field.declaringClass
242
244
val fieldAccessible = field.canBeSetIn(testClassPackageName)
243
- val fieldValue = variableConstructor.getOrCreateVariable(model, field.name)
245
+
246
+ val fieldValue = if (isParametrized) {
247
+ currentMethodParameters[CgParameterKind .Statics (model)]
248
+ } else {
249
+ variableConstructor.getOrCreateVariable(model, field.name)
250
+ }
251
+
244
252
if (fieldAccessible) {
245
253
declaringClass[field] `= ` fieldValue
246
254
} else {
@@ -1097,12 +1105,13 @@ internal class CgMethodConstructor(val context: CgContext) : CgContextOwner by c
1097
1105
// TODO: remove this line when SAT-1273 is completed
1098
1106
execution.displayName = execution.displayName?.let { " ${executableId.name} : $it " }
1099
1107
testMethod(testMethodName, execution.displayName) {
1100
- rememberInitialStaticFields()
1108
+ val statics = currentExecution!! .stateBefore.statics
1109
+ rememberInitialStaticFields(statics)
1101
1110
val stateAnalyzer = ExecutionStateAnalyzer (execution)
1102
1111
val modificationInfo = stateAnalyzer.findModifiedFields()
1103
1112
// TODO: move such methods to another class and leave only 2 public methods: remember initial and final states
1104
1113
val mainBody = {
1105
- mockStaticFields( )
1114
+ substituteStaticFields(statics )
1106
1115
setupInstrumentation()
1107
1116
// build this instance
1108
1117
thisInstance = execution.stateBefore.thisInstance?.let {
@@ -1120,7 +1129,6 @@ internal class CgMethodConstructor(val context: CgContext) : CgContextOwner by c
1120
1129
generateFieldStateAssertions()
1121
1130
}
1122
1131
1123
- val statics = currentExecution!! .stateBefore.statics
1124
1132
if (statics.isNotEmpty()) {
1125
1133
+ tryBlock {
1126
1134
mainBody()
@@ -1177,11 +1185,14 @@ internal class CgMethodConstructor(val context: CgContext) : CgContextOwner by c
1177
1185
.firstOrNull { it.result is UtExecutionSuccess && (it.result as UtExecutionSuccess ).model !is UtNullModel }
1178
1186
? : testSet.executions.first()
1179
1187
1188
+ val statics = genericExecution.stateBefore.statics
1189
+
1180
1190
return withTestMethodScope(genericExecution) {
1181
1191
val testName = nameGenerator.parameterizedTestMethodName(dataProviderMethodName)
1182
1192
withNameScope {
1183
1193
val testParameterDeclarations = createParameterDeclarations(testSet, genericExecution)
1184
1194
val mainBody = {
1195
+ substituteStaticFields(statics, isParametrized = true )
1185
1196
// build this instance
1186
1197
thisInstance = genericExecution.stateBefore.thisInstance?.let { currentMethodParameters[CgParameterKind .ThisInstance ] }
1187
1198
@@ -1203,16 +1214,30 @@ internal class CgMethodConstructor(val context: CgContext) : CgContextOwner by c
1203
1214
parameterized = true ,
1204
1215
dataProviderMethodName
1205
1216
) {
1206
- if (containsFailureExecution(testSet)) {
1207
- + tryBlock(mainBody)
1208
- .catch (Throwable ::class .java.id) { e ->
1217
+ rememberInitialStaticFields(statics)
1218
+
1219
+ if (containsFailureExecution(testSet) || statics.isNotEmpty()) {
1220
+ var currentTryBlock = tryBlock {
1221
+ mainBody()
1222
+ }
1223
+
1224
+ if (containsFailureExecution(testSet)) {
1225
+ currentTryBlock = currentTryBlock.catch (Throwable ::class .java.id) { e ->
1209
1226
val pseudoExceptionVarName = when (codegenLanguage) {
1210
1227
CodegenLanguage .JAVA -> " ${expectedErrorVarName} .isInstance(${e.name.decapitalize()} )"
1211
1228
CodegenLanguage .KOTLIN -> " ${expectedErrorVarName} !!.isInstance(${e.name.decapitalize()} )"
1212
1229
}
1213
1230
1214
1231
testFrameworkManager.assertBoolean(CgVariable (pseudoExceptionVarName, booleanClassId))
1215
1232
}
1233
+ }
1234
+
1235
+ if (statics.isNotEmpty()) {
1236
+ currentTryBlock = currentTryBlock.finally {
1237
+ recoverStaticFields()
1238
+ }
1239
+ }
1240
+ + currentTryBlock
1216
1241
} else {
1217
1242
mainBody()
1218
1243
}
@@ -1265,6 +1290,22 @@ internal class CgMethodConstructor(val context: CgContext) : CgContextOwner by c
1265
1290
currentMethodParameters[CgParameterKind .Argument (index)] = argument.parameter
1266
1291
}
1267
1292
1293
+ val statics = genericExecution.stateBefore.statics
1294
+ if (statics.isNotEmpty()) {
1295
+ for ((fieldId, model) in statics) {
1296
+ val staticType = wrapTypeIfRequired(model.classId)
1297
+ val static = CgParameterDeclaration (
1298
+ parameter = declareParameter(
1299
+ type = staticType,
1300
+ name = nameGenerator.variableName(fieldId.name, isStatic = true )
1301
+ ),
1302
+ isReferenceType = staticType.isRefType
1303
+ )
1304
+ this + = static
1305
+ currentMethodParameters[CgParameterKind .Statics (model)] = static.parameter
1306
+ }
1307
+ }
1308
+
1268
1309
val expectedResultClassId = wrapTypeIfRequired(testSet.resultType())
1269
1310
if (expectedResultClassId != voidClassId) {
1270
1311
val wrappedType = wrapIfPrimitive(expectedResultClassId)
@@ -1347,6 +1388,12 @@ internal class CgMethodConstructor(val context: CgContext) : CgContextOwner by c
1347
1388
arguments + = variableConstructor.getOrCreateVariable(paramModel, argumentName)
1348
1389
}
1349
1390
1391
+ val statics = execution.stateBefore.statics
1392
+ for ((field, model) in statics) {
1393
+ arguments + = variableConstructor.getOrCreateVariable(model, field.name)
1394
+ }
1395
+
1396
+
1350
1397
val method = currentExecutable!!
1351
1398
val needsReturnValue = method.returnType != voidClassId
1352
1399
val containsFailureExecution = containsFailureExecution(testSet)
0 commit comments