@@ -3,28 +3,14 @@ package org.utbot.external.api
33import org.utbot.common.FileUtil
44import org.utbot.common.nameOfPackage
55import org.utbot.framework.UtSettings
6- import org.utbot.framework.codegen.domain.ForceStaticMocking
7- import org.utbot.framework.codegen.domain.Junit5
8- import org.utbot.framework.codegen.domain.NoStaticMocking
9- import org.utbot.framework.codegen.domain.ProjectType
10- import org.utbot.framework.codegen.domain.StaticsMocking
11- import org.utbot.framework.codegen.domain.TestFramework
12- import org.utbot.framework.codegen.generator.CodeGenerator
6+ import org.utbot.framework.codegen.domain.*
137import org.utbot.framework.codegen.generator.CodeGeneratorParams
148import org.utbot.framework.codegen.services.language.CgLanguageAssistant
15- import org.utbot.framework.context.simple.SimpleApplicationContext
9+ import org.utbot.framework.context.ApplicationContext
1610import org.utbot.framework.context.utils.transformValueProvider
1711import org.utbot.instrumentation.instrumentation.execution.UtConcreteExecutionData
1812import org.utbot.instrumentation.instrumentation.execution.UtConcreteExecutionResult
1913import org.utbot.instrumentation.instrumentation.execution.UtExecutionInstrumentation
20- import org.utbot.framework.plugin.api.ClassId
21- import org.utbot.framework.plugin.api.CodegenLanguage
22- import org.utbot.framework.plugin.api.MockFramework
23- import org.utbot.framework.plugin.api.MockStrategyApi
24- import org.utbot.framework.plugin.api.TestCaseGenerator
25- import org.utbot.framework.plugin.api.UtMethodTestSet
26- import org.utbot.framework.plugin.api.UtPrimitiveModel
27- import org.utbot.framework.plugin.api.UtSymbolicExecution
2814import org.utbot.framework.plugin.api.util.UtContext
2915import org.utbot.framework.plugin.api.util.executableId
3016import org.utbot.framework.plugin.api.util.id
@@ -36,26 +22,53 @@ import org.utbot.framework.plugin.api.util.stringClassId
3622import org.utbot.framework.plugin.api.util.withUtContext
3723import org.utbot.framework.plugin.api.util.wrapperByPrimitive
3824import org.utbot.framework.plugin.services.JdkInfoDefaultProvider
39- import org.utbot.fuzzer.FuzzedType
4025import org.utbot.fuzzer.FuzzedValue
41- import org.utbot.fuzzing.FuzzedDescription
4226import org.utbot.fuzzing.JavaValueProvider
4327import org.utbot.fuzzing.Seed
44- import org.utbot.fuzzing.ValueProvider
4528import org.utbot.instrumentation.ConcreteExecutor
4629import org.utbot.instrumentation.execute
47- import org.utbot.instrumentation.instrumentation.execution.SimpleUtExecutionInstrumentation
48- import java.io.File
4930import kotlin.reflect.jvm.kotlinFunction
31+ import org.utbot.framework.codegen.domain.StaticsMocking
32+ import org.utbot.framework.plugin.api.*
33+ import java.lang.reflect.Method
5034
5135object UtBotJavaApi {
5236
37+ /* *
38+ * For running tests it could be reasonable to reuse the same concrete executor
39+ */
5340 @JvmStatic
5441 var stopConcreteExecutorOnExit: Boolean = true
5542
43+ /* *
44+ * Generates test code
45+ * @param methodsForGeneration specify methods that are supposed to be executed concretely.
46+ * In order to execute method you are supposed to provide some
47+ * values to pass in it this is why we use [TestMethodInfo] here.
48+ * @param generatedTestCases specify [UtMethodTestSet]s that are used for test code
49+ * generation. By comparison with the first parameter,
50+ * {@code UtMethodTestSet} contains more information about
51+ * test, including result of the executions. Note, that
52+ * you can get the object with any sort of analysis,
53+ * for instance, symbolic or fuzz execution.
54+ * @param destinationClassName the name of containing class for the generated tests
55+ * @param classpath classpath that are used to build the class under test
56+ * @param dependencyClassPath class path including dependencies required for the code generation
57+ * @param classUnderTest for this class test should be generated
58+ * @param projectType JVM, Spring, Python, or other type of project
59+ * @param testFramework test framework that is going to be used for running generated tests
60+ * @param mockFramework framework that will be used in the generated tests
61+ * @param codegenLanguage the target language of the test generation. It can be different from the source language.
62+ * @param staticsMocking the approach to the statics mocking
63+ * @param generateWarningsForStaticMocking enable generation of warning about forced static mocking in comments
64+ * of generated tests.
65+ * @param forceStaticMocking enables static mocking
66+ * @param testClassPackageName package name for the generated class with the tests
67+ * @param applicationContext specify application context here
68+ */
5669 @JvmStatic
5770 @JvmOverloads
58- fun generate (
71+ fun generateTestCode (
5972 methodsForGeneration : List <TestMethodInfo >,
6073 generatedTestCases : List <UtMethodTestSet > = mutableListOf(),
6174 destinationClassName : String ,
@@ -69,16 +82,18 @@ object UtBotJavaApi {
6982 staticsMocking : StaticsMocking = NoStaticMocking ,
7083 generateWarningsForStaticMocking : Boolean = false,
7184 forceStaticMocking : ForceStaticMocking = ForceStaticMocking .DO_NOT_FORCE ,
72- testClassPackageName : String = classUnderTest.nameOfPackage
85+ testClassPackageName : String = classUnderTest.nameOfPackage,
86+ applicationContext : ApplicationContext
7387 ): String {
7488
75- val utContext = UtContext (classUnderTest.classLoader)
76-
7789 val testSets: MutableList <UtMethodTestSet > = generatedTestCases.toMutableList()
7890
7991 val concreteExecutor = ConcreteExecutor (
80- SimpleUtExecutionInstrumentation .Factory (pathsToUserClasses = classpath.split(File .pathSeparator).toSet()),
81- classpath,
92+ applicationContext.createConcreteExecutionContext(
93+ fullClasspath = dependencyClassPath,
94+ classpathWithoutDependencies = classpath
95+ ).instrumentationFactory,
96+ classpath
8297 )
8398
8499 testSets.addAll(generateUnitTests(concreteExecutor, methodsForGeneration, classUnderTest))
@@ -87,8 +102,8 @@ object UtBotJavaApi {
87102 concreteExecutor.close()
88103 }
89104
90- return withUtContext(utContext ) {
91- val codeGenerator = CodeGenerator (
105+ return withUtContext(UtContext (classUnderTest.classLoader) ) {
106+ applicationContext.createCodeGenerator (
92107 CodeGeneratorParams (
93108 classUnderTest = classUnderTest.id,
94109 projectType = projectType,
@@ -99,11 +114,9 @@ object UtBotJavaApi {
99114 staticsMocking = staticsMocking,
100115 forceStaticMocking = forceStaticMocking,
101116 generateWarningsForStaticMocking = generateWarningsForStaticMocking,
102- testClassPackageName = testClassPackageName
117+ testClassPackageName = testClassPackageName,
103118 )
104- )
105-
106- codeGenerator.generateAsString(testSets, destinationClassName)
119+ ).generateAsString(testSets, destinationClassName)
107120 }
108121 }
109122
@@ -114,29 +127,36 @@ object UtBotJavaApi {
114127 */
115128 @JvmStatic
116129 @JvmOverloads
117- fun generateTestSets (
118- methodsForAutomaticGeneration : List <TestMethodInfo >,
130+ fun generateTestSetsForMethods (
131+ methodsToAnalyze : List <Method >,
119132 classUnderTest : Class <* >,
120133 classpath : String ,
121134 dependencyClassPath : String ,
122135 mockStrategyApi : MockStrategyApi = MockStrategyApi .OTHER_PACKAGES ,
123- generationTimeoutInMillis : Long = UtSettings .utBotGenerationTimeoutInMillis
136+ generationTimeoutInMillis : Long = UtSettings .utBotGenerationTimeoutInMillis,
137+ applicationContext : ApplicationContext
124138 ): MutableList <UtMethodTestSet > {
125139
140+ assert (methodsToAnalyze.all {classUnderTest.declaredMethods.contains(it)})
141+ { " Some methods are absent in the ${classUnderTest.name} class." }
142+
126143 val utContext = UtContext (classUnderTest.classLoader)
127144 val testSets: MutableList <UtMethodTestSet > = mutableListOf ()
128145
129146 testSets.addAll(withUtContext(utContext) {
130147 val buildPath = FileUtil .isolateClassFiles(classUnderTest).toPath()
131- TestCaseGenerator (listOf (buildPath), classpath, dependencyClassPath, jdkInfo = JdkInfoDefaultProvider ().info)
132- .generate(
133- methodsForAutomaticGeneration.map {
134- it.methodToBeTestedFromUserInput.executableId
135- },
136- mockStrategyApi,
137- chosenClassesToMockAlways = emptySet(),
138- generationTimeoutInMillis
139- )
148+ TestCaseGenerator (
149+ listOf (buildPath),
150+ classpath,
151+ dependencyClassPath,
152+ jdkInfo = JdkInfoDefaultProvider ().info,
153+ applicationContext = applicationContext
154+ ).generate(
155+ methodsToAnalyze.map { it.executableId },
156+ mockStrategyApi,
157+ chosenClassesToMockAlways = emptySet(),
158+ generationTimeoutInMillis
159+ )
140160 })
141161
142162 return testSets
@@ -145,19 +165,24 @@ object UtBotJavaApi {
145165 /* *
146166 * Generates test cases using only fuzzing workflow.
147167 *
148- * @see [generateTestSets ]
168+ * @see [generateTestSetsForMethods ]
149169 */
150170 @JvmStatic
151171 @JvmOverloads
152172 fun fuzzingTestSets (
153- methodsForAutomaticGeneration : List <TestMethodInfo >,
173+ methodsToAnalyze : List <Method >,
154174 classUnderTest : Class <* >,
155175 classpath : String ,
156176 dependencyClassPath : String ,
157177 mockStrategyApi : MockStrategyApi = MockStrategyApi .OTHER_PACKAGES ,
158178 generationTimeoutInMillis : Long = UtSettings .utBotGenerationTimeoutInMillis,
159- primitiveValuesSupplier : CustomFuzzerValueSupplier = CustomFuzzerValueSupplier { null }
179+ primitiveValuesSupplier : CustomFuzzerValueSupplier = CustomFuzzerValueSupplier { null },
180+ applicationContext : ApplicationContext
160181 ): MutableList <UtMethodTestSet > {
182+
183+ assert (methodsToAnalyze.all {classUnderTest.declaredMethods.contains(it)})
184+ { " Some methods are absent in the ${classUnderTest.name} class." }
185+
161186 fun createPrimitiveModels (supplier : CustomFuzzerValueSupplier , classId : ClassId ): Sequence <UtPrimitiveModel > =
162187 supplier
163188 .takeIf { classId.isPrimitive || classId.isPrimitiveWrapper || classId == stringClassId }
@@ -189,14 +214,12 @@ object UtBotJavaApi {
189214 classpath,
190215 dependencyClassPath,
191216 jdkInfo = JdkInfoDefaultProvider ().info,
192- applicationContext = SimpleApplicationContext () .transformValueProvider { defaultModelProvider ->
217+ applicationContext = applicationContext .transformValueProvider { defaultModelProvider ->
193218 customModelProvider.withFallback(defaultModelProvider)
194219 }
195220 )
196221 .generate(
197- methodsForAutomaticGeneration.map {
198- it.methodToBeTestedFromUserInput.executableId
199- },
222+ methodsToAnalyze.map{ it.executableId },
200223 mockStrategyApi,
201224 chosenClassesToMockAlways = emptySet(),
202225 generationTimeoutInMillis,
0 commit comments