Skip to content

Commit 0f9d41c

Browse files
committed
Refactored CgMethodConstructor
1 parent 94833f3 commit 0f9d41c

File tree

4 files changed

+250
-202
lines changed

4 files changed

+250
-202
lines changed

utbot-framework/src/main/kotlin/org/utbot/framework/codegen/Domain.kt

Lines changed: 47 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,14 @@ package org.utbot.framework.codegen
33
import org.utbot.framework.DEFAULT_CONCRETE_EXECUTION_TIMEOUT_IN_CHILD_PROCESS_MS
44
import org.utbot.framework.codegen.model.constructor.builtin.mockitoClassId
55
import org.utbot.framework.codegen.model.constructor.builtin.ongoingStubbingClassId
6+
import org.utbot.framework.codegen.model.constructor.util.argumentsClassId
67
import org.utbot.framework.codegen.model.tree.CgClassId
78
import org.utbot.framework.plugin.api.BuiltinClassId
89
import org.utbot.framework.plugin.api.ClassId
910
import org.utbot.framework.plugin.api.CodeGenerationSettingBox
1011
import org.utbot.framework.plugin.api.CodeGenerationSettingItem
1112
import org.utbot.framework.plugin.api.MethodId
13+
import org.utbot.framework.plugin.api.TypeParameters
1214
import org.utbot.framework.plugin.api.isolateCommandLineArgumentsToArgumentFile
1315
import org.utbot.framework.plugin.api.util.booleanArrayClassId
1416
import org.utbot.framework.plugin.api.util.booleanClassId
@@ -28,6 +30,7 @@ import org.utbot.framework.plugin.api.util.shortArrayClassId
2830
import org.utbot.framework.plugin.api.util.voidClassId
2931
import java.io.File
3032
import org.utbot.framework.plugin.api.util.longClassId
33+
import org.utbot.framework.plugin.api.util.objectArrayClassId
3134
import org.utbot.framework.plugin.api.util.voidWrapperClassId
3235

3336
data class TestClassFile(val packageName: String, val imports: List<Import>, val testClass: String)
@@ -184,6 +187,7 @@ sealed class TestFramework(
184187
abstract val methodSourceAnnotationId: ClassId
185188
abstract val methodSourceAnnotationFqn: String
186189
abstract val nestedClassesShouldBeStatic: Boolean
190+
abstract val argListClassId: ClassId
187191

188192
val assertEquals by lazy { assertionId("assertEquals", objectClassId, objectClassId) }
189193

@@ -304,6 +308,28 @@ object TestNg : TestFramework(displayName = "TestNG") {
304308

305309
override val nestedClassesShouldBeStatic = true
306310

311+
override val argListClassId: ClassId
312+
get() {
313+
val outerArrayId = Array<Array<Any?>?>::class.id
314+
val innerArrayId = BuiltinClassId(
315+
name = objectArrayClassId.name,
316+
simpleName = objectArrayClassId.simpleName,
317+
canonicalName = objectArrayClassId.canonicalName,
318+
packageName = objectArrayClassId.packageName,
319+
elementClassId = objectClassId,
320+
typeParameters = TypeParameters(listOf(objectClassId))
321+
)
322+
323+
return BuiltinClassId(
324+
name = outerArrayId.name,
325+
simpleName = outerArrayId.simpleName,
326+
canonicalName = outerArrayId.canonicalName,
327+
packageName = outerArrayId.packageName,
328+
elementClassId = innerArrayId,
329+
typeParameters = TypeParameters(listOf(innerArrayId))
330+
)
331+
}
332+
307333
@OptIn(ExperimentalStdlibApi::class)
308334
override fun getRunTestsCommand(
309335
executionInvoke: String,
@@ -349,14 +375,16 @@ object TestNg : TestFramework(displayName = "TestNG") {
349375
}
350376

351377
object Junit4 : TestFramework("JUnit4") {
378+
private val parametrizedTestsNotSupportedError: Nothing = error("Parametrized tests are not supported for JUnit4")
379+
352380
override val mainPackage: String = JUNIT4_PACKAGE
353381
override val testAnnotation = "@$mainPackage.Test"
354382
override val testAnnotationFqn: String = "$mainPackage.Test"
355383

356-
override val parameterizedTestAnnotation = "Parameterized tests are not supported for JUnit4"
357-
override val parameterizedTestAnnotationFqn = "Parameterized tests are not supported for JUnit4"
358-
override val methodSourceAnnotation = "Parameterized tests are not supported for JUnit4"
359-
override val methodSourceAnnotationFqn = "Parameterized tests are not supported for JUnit4"
384+
override val parameterizedTestAnnotation = parametrizedTestsNotSupportedError
385+
override val parameterizedTestAnnotationFqn = parametrizedTestsNotSupportedError
386+
override val methodSourceAnnotation = parametrizedTestsNotSupportedError
387+
override val methodSourceAnnotationFqn = parametrizedTestsNotSupportedError
360388

361389
override val testAnnotationId = BuiltinClassId(
362390
name = "$JUNIT4_PACKAGE.Test",
@@ -391,6 +419,9 @@ object Junit4 : TestFramework("JUnit4") {
391419

392420
override val nestedClassesShouldBeStatic = true
393421

422+
override val argListClassId: ClassId
423+
get() = parametrizedTestsNotSupportedError
424+
394425
@OptIn(ExperimentalStdlibApi::class)
395426
override fun getRunTestsCommand(
396427
executionInvoke: String,
@@ -515,6 +546,18 @@ object Junit5 : TestFramework("JUnit5") {
515546

516547
override val nestedClassesShouldBeStatic = false
517548

549+
override val argListClassId: ClassId
550+
get() {
551+
val arrayListId = java.util.ArrayList::class.id
552+
return BuiltinClassId(
553+
name = arrayListId.name,
554+
simpleName = arrayListId.simpleName,
555+
canonicalName = arrayListId.canonicalName,
556+
packageName = arrayListId.packageName,
557+
typeParameters = TypeParameters(listOf(argumentsClassId))
558+
)
559+
}
560+
518561
private const val junitVersion = "1.7.1" // TODO read it from gradle.properties
519562
private const val platformJarName: String = "junit-platform-console-standalone-$junitVersion.jar"
520563

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

Lines changed: 9 additions & 175 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,15 @@ package org.utbot.framework.codegen.model.constructor.tree
33
import org.utbot.common.PathUtil
44
import org.utbot.framework.assemble.assemble
55
import org.utbot.framework.codegen.ForceStaticMocking
6-
import org.utbot.framework.codegen.Junit4
7-
import org.utbot.framework.codegen.Junit5
86
import org.utbot.framework.codegen.ParametrizedTestSource
97
import org.utbot.framework.codegen.RuntimeExceptionTestsBehaviour.PASS
10-
import org.utbot.framework.codegen.TestNg
118
import org.utbot.framework.codegen.model.constructor.CgMethodTestSet
129
import org.utbot.framework.codegen.model.constructor.builtin.closeMethodIdOrNull
1310
import org.utbot.framework.codegen.model.constructor.builtin.forName
1411
import org.utbot.framework.codegen.model.constructor.builtin.getClass
1512
import org.utbot.framework.codegen.model.constructor.builtin.getTargetException
1613
import org.utbot.framework.codegen.model.constructor.builtin.invoke
1714
import org.utbot.framework.codegen.model.constructor.builtin.newInstance
18-
import org.utbot.framework.codegen.model.constructor.builtin.setArrayElement
1915
import org.utbot.framework.codegen.model.constructor.context.CgContext
2016
import org.utbot.framework.codegen.model.constructor.context.CgContextOwner
2117
import org.utbot.framework.codegen.model.constructor.util.CgComponents
@@ -26,9 +22,9 @@ import org.utbot.framework.codegen.model.constructor.util.classCgClassId
2622
import org.utbot.framework.codegen.model.constructor.util.needExpectedDeclaration
2723
import org.utbot.framework.codegen.model.constructor.util.overridesEquals
2824
import org.utbot.framework.codegen.model.constructor.util.plus
25+
import org.utbot.framework.codegen.model.constructor.util.setArgumentsArrayElement
2926
import org.utbot.framework.codegen.model.constructor.util.typeCast
3027
import org.utbot.framework.codegen.model.tree.CgAllocateArray
31-
import org.utbot.framework.codegen.model.tree.CgAnnotation
3228
import org.utbot.framework.codegen.model.tree.CgArrayElementAccess
3329
import org.utbot.framework.codegen.model.tree.CgClassId
3430
import org.utbot.framework.codegen.model.tree.CgDeclaration
@@ -69,7 +65,6 @@ import org.utbot.framework.codegen.model.tree.buildParameterizedTestDataProvider
6965
import org.utbot.framework.codegen.model.tree.buildTestMethod
7066
import org.utbot.framework.codegen.model.tree.convertDocToCg
7167
import org.utbot.framework.codegen.model.tree.toStatement
72-
import org.utbot.framework.codegen.model.util.at
7368
import org.utbot.framework.codegen.model.util.canBeSetIn
7469
import org.utbot.framework.codegen.model.util.equalTo
7570
import org.utbot.framework.codegen.model.util.get
@@ -116,7 +111,6 @@ import org.utbot.framework.plugin.api.UtVoidModel
116111
import org.utbot.framework.plugin.api.onFailure
117112
import org.utbot.framework.plugin.api.onSuccess
118113
import org.utbot.framework.plugin.api.util.booleanClassId
119-
import org.utbot.framework.plugin.api.util.builtinStaticMethodId
120114
import org.utbot.framework.plugin.api.util.doubleArrayClassId
121115
import org.utbot.framework.plugin.api.util.doubleClassId
122116
import org.utbot.framework.plugin.api.util.doubleWrapperClassId
@@ -137,7 +131,6 @@ import org.utbot.framework.plugin.api.util.isPrimitiveWrapper
137131
import org.utbot.framework.plugin.api.util.isRefType
138132
import org.utbot.framework.plugin.api.util.jClass
139133
import org.utbot.framework.plugin.api.util.kClass
140-
import org.utbot.framework.plugin.api.util.methodId
141134
import org.utbot.framework.plugin.api.util.objectArrayClassId
142135
import org.utbot.framework.plugin.api.util.objectClassId
143136
import org.utbot.framework.plugin.api.util.stringClassId
@@ -1317,7 +1310,7 @@ internal class CgMethodConstructor(val context: CgContext) : CgContextOwner by c
13171310
return withDataProviderScope {
13181311
dataProviderMethod(dataProviderMethodName) {
13191312
val argListLength = testSet.executions.size
1320-
val argListVariable = createArgList(argListLength)
1313+
val argListVariable = testFrameworkManager.createArgList(argListLength, "argList")
13211314

13221315
emptyLine()
13231316

@@ -1432,161 +1425,15 @@ internal class CgMethodConstructor(val context: CgContext) : CgContextOwner by c
14321425
CgAllocateArray(objectArrayClassId, objectClassId, arguments.size)
14331426
}
14341427
for ((i, argument) in arguments.withIndex()) {
1435-
setArgumentsArrayElement(argsArray, i, argument)
1436-
}
1437-
when (testFramework) {
1438-
Junit5 -> {
1439-
+argsVariable[addToListMethodId](
1440-
argumentsClassId[argumentsMethodId](argsArray)
1441-
)
1442-
}
1443-
TestNg -> {
1444-
setArgumentsArrayElement(argsVariable, executionIndex, argsArray)
1445-
}
1446-
Junit4 -> error("Parameterized tests are not supported for JUnit4")
1447-
}
1448-
}
1449-
1450-
/**
1451-
* Sets an element of arguments array in parameterized test,
1452-
* if test framework represents arguments as array.
1453-
*/
1454-
private fun setArgumentsArrayElement(array: CgVariable, index: Int, value: CgExpression) {
1455-
when (array.type) {
1456-
objectClassId -> {
1457-
+java.lang.reflect.Array::class.id[setArrayElement](array, index, value)
1458-
}
1459-
else -> array.at(index) `=` value
1428+
setArgumentsArrayElement(argsArray, i, argument, this)
14601429
}
1430+
testFrameworkManager.passArgumentsToArgsVariable(argsVariable, argsArray, executionIndex)
14611431
}
14621432

1463-
/**
1464-
* Creates annotations for data provider method in parameterized tests
1465-
* depending on test framework.
1466-
*/
1467-
private fun createDataProviderAnnotations(dataProviderMethodName: String?): MutableList<CgAnnotation> =
1468-
when (testFramework) {
1469-
Junit5 -> mutableListOf()
1470-
TestNg -> mutableListOf(
1471-
annotation(
1472-
testFramework.methodSourceAnnotationId,
1473-
listOf("name" to CgLiteral(stringClassId, dataProviderMethodName))
1474-
),
1475-
)
1476-
Junit4 -> error("Parameterized tests are not supported for JUnit4")
1477-
}
1478-
1479-
/**
1480-
* Creates declaration of argList collection in parameterized tests.
1481-
*/
1482-
private fun createArgList(length: Int): CgVariable {
1483-
val argListName = "argList"
1484-
return when (testFramework) {
1485-
Junit5 ->
1486-
newVar(argListClassId, argListName) {
1487-
val constructor = ConstructorId(argListClassId, emptyList())
1488-
constructor.invoke()
1489-
}
1490-
TestNg ->
1491-
newVar(argListClassId, argListName) {
1492-
CgAllocateArray(argListClassId, Array<Any>::class.java.id, length)
1493-
}
1494-
Junit4 -> error("Parameterized tests are not supported for JUnit4")
1495-
}
1496-
}
1497-
1498-
/**
1499-
* Creates a [ClassId] for arguments collection.
1500-
*/
1501-
private val argListClassId: ClassId
1502-
get() = when (testFramework) {
1503-
Junit5 -> {
1504-
val arrayListId = java.util.ArrayList::class.id
1505-
BuiltinClassId(
1506-
name = arrayListId.name,
1507-
simpleName = arrayListId.simpleName,
1508-
canonicalName = arrayListId.canonicalName,
1509-
packageName = arrayListId.packageName,
1510-
typeParameters = TypeParameters(listOf(argumentsClassId))
1511-
)
1512-
}
1513-
TestNg -> {
1514-
val outerArrayId = Array<Array<Any?>?>::class.id
1515-
val innerArrayId = BuiltinClassId(
1516-
name = objectArrayClassId.name,
1517-
simpleName = objectArrayClassId.simpleName,
1518-
canonicalName = objectArrayClassId.canonicalName,
1519-
packageName = objectArrayClassId.packageName,
1520-
elementClassId = objectClassId,
1521-
typeParameters = TypeParameters(listOf(objectClassId))
1522-
)
1523-
1524-
BuiltinClassId(
1525-
name = outerArrayId.name,
1526-
simpleName = outerArrayId.simpleName,
1527-
canonicalName = outerArrayId.canonicalName,
1528-
packageName = outerArrayId.packageName,
1529-
elementClassId = innerArrayId,
1530-
typeParameters = TypeParameters(listOf(innerArrayId))
1531-
)
1532-
}
1533-
Junit4 -> error("Parameterized tests are not supported for JUnit4")
1534-
}
1535-
1536-
1537-
/**
1538-
* A [MethodId] to add an item into [ArrayList].
1539-
*/
1540-
private val addToListMethodId: MethodId
1541-
get() = methodId(
1542-
classId = ArrayList::class.id,
1543-
name = "add",
1544-
returnType = booleanClassId,
1545-
arguments = arrayOf(Object::class.id),
1546-
)
1547-
1548-
/**
1549-
* A [ClassId] of class `org.junit.jupiter.params.provider.Arguments`
1550-
*/
1551-
private val argumentsClassId: BuiltinClassId
1552-
get() = BuiltinClassId(
1553-
name = "org.junit.jupiter.params.provider.Arguments",
1554-
simpleName = "Arguments",
1555-
canonicalName = "org.junit.jupiter.params.provider.Arguments",
1556-
packageName = "org.junit.jupiter.params.provider"
1557-
)
1558-
1559-
/**
1560-
* A [MethodId] to call JUnit Arguments method.
1561-
*/
1562-
private val argumentsMethodId: BuiltinMethodId
1563-
get() = builtinStaticMethodId(
1564-
classId = argumentsClassId,
1565-
name = "arguments",
1566-
returnType = argumentsClassId,
1567-
// vararg of Objects
1568-
arguments = arrayOf(objectArrayClassId)
1569-
)
1570-
15711433
private fun containsFailureExecution(testSet: CgMethodTestSet) =
15721434
testSet.executions.any { it.result is UtExecutionFailure }
15731435

15741436

1575-
private fun collectParameterizedTestAnnotations(dataProviderMethodName: String?): Set<CgAnnotation> =
1576-
when (testFramework) {
1577-
Junit5 -> setOf(
1578-
annotation(testFramework.parameterizedTestAnnotationId),
1579-
annotation(testFramework.methodSourceAnnotationId, "${outerMostTestClass.canonicalName}#$dataProviderMethodName"),
1580-
)
1581-
TestNg -> setOf(
1582-
annotation(
1583-
testFramework.parameterizedTestAnnotationId,
1584-
listOf("dataProvider" to CgLiteral(stringClassId, dataProviderMethodName))
1585-
),
1586-
)
1587-
Junit4 -> error("Parameterized tests are not supported for JUnit4")
1588-
}
1589-
15901437
private fun testMethod(
15911438
methodName: String,
15921439
displayName: String?,
@@ -1596,26 +1443,13 @@ internal class CgMethodConstructor(val context: CgContext) : CgContextOwner by c
15961443
body: () -> Unit,
15971444
): CgTestMethod {
15981445
collectedMethodAnnotations += if (parameterized) {
1599-
collectParameterizedTestAnnotations(dataProviderMethodName)
1446+
testFrameworkManager.collectParameterizedTestAnnotations(dataProviderMethodName)
16001447
} else {
16011448
setOf(annotation(testFramework.testAnnotationId))
16021449
}
16031450

1604-
/* Add a short test's description depending on the test framework type:
1605-
DisplayName annotation in case of JUni5, and description argument to Test annotation in case of TestNG.
1606-
*/
1607-
if (displayName != null) {
1608-
when (testFramework) {
1609-
is Junit5 -> {
1610-
displayName.let { testFrameworkManager.addDisplayName(it) }
1611-
}
1612-
is TestNg -> {
1613-
testFrameworkManager.addTestDescription(displayName)
1614-
}
1615-
else -> {
1616-
// nothing
1617-
}
1618-
}
1451+
displayName?.let {
1452+
testFrameworkManager.addTestDescription(displayName)
16191453
}
16201454

16211455
val result = currentExecution!!.result
@@ -1676,12 +1510,12 @@ internal class CgMethodConstructor(val context: CgContext) : CgContextOwner by c
16761510
private fun dataProviderMethod(dataProviderMethodName: String, body: () -> Unit): CgParameterizedTestDataProviderMethod {
16771511
return buildParameterizedTestDataProviderMethod {
16781512
name = dataProviderMethodName
1679-
returnType = argListClassId
1513+
returnType = testFramework.argListClassId
16801514
statements = block(body)
16811515
// Exceptions and annotations assignment must run after the statements block is build,
16821516
// because we collect info about exceptions and required annotations while building the statements
16831517
exceptions += collectedExceptions
1684-
annotations += createDataProviderAnnotations(dataProviderMethodName)
1518+
annotations += testFrameworkManager.createDataProviderAnnotations(dataProviderMethodName)
16851519
}
16861520
}
16871521

0 commit comments

Comments
 (0)