@@ -13,9 +13,11 @@ import com.intellij.openapi.roots.ProjectFileIndex
13
13
import com.intellij.openapi.ui.Messages
14
14
import com.intellij.openapi.util.Computable
15
15
import com.intellij.openapi.util.text.StringUtil
16
+ import com.intellij.psi.JavaPsiFacade
16
17
import com.intellij.openapi.vfs.VirtualFile
17
18
import com.intellij.psi.PsiClass
18
19
import com.intellij.psi.PsiMethod
20
+ import com.intellij.psi.search.GlobalSearchScope
19
21
import com.intellij.refactoring.util.classMembers.MemberInfo
20
22
import com.intellij.task.ProjectTask
21
23
import com.intellij.task.ProjectTaskManager
@@ -38,7 +40,7 @@ import kotlin.io.path.pathString
38
40
import mu.KotlinLogging
39
41
import org.jetbrains.concurrency.Promise
40
42
import org.jetbrains.idea.maven.project.MavenProjectsManager
41
- import org.jetbrains.kotlin.idea.util.module
43
+ import org.jetbrains.kotlin.idea.base. util.module
42
44
import org.utbot.framework.CancellationStrategyType.CANCEL_EVERYTHING
43
45
import org.utbot.framework.CancellationStrategyType.NONE
44
46
import org.utbot.framework.CancellationStrategyType.SAVE_PROCESSED_RESULTS
@@ -58,6 +60,7 @@ import org.utbot.intellij.plugin.models.GenerateTestsModel
58
60
import org.utbot.intellij.plugin.models.packageName
59
61
import org.utbot.intellij.plugin.process.EngineProcess
60
62
import org.utbot.intellij.plugin.process.RdTestGenerationResult
63
+ import org.utbot.intellij.plugin.process.SpringAnalyzerProcess
61
64
import org.utbot.intellij.plugin.settings.Settings
62
65
import org.utbot.intellij.plugin.ui.GenerateTestsDialogWindow
63
66
import org.utbot.intellij.plugin.ui.utils.isBuildWithGradle
@@ -156,7 +159,15 @@ object UtTestsDialogProcessor {
156
159
}
157
160
158
161
private fun createTests (project : Project , model : GenerateTestsModel ) {
159
- val promise = compile(project, model.srcClasses.map { it.containingFile.virtualFile }.toTypedArray())
162
+ val springConfigClass = when (val approach = model.typeReplacementApproach) {
163
+ TypeReplacementApproach .DoNotReplace -> null
164
+ is TypeReplacementApproach .ReplaceIfPossible ->
165
+ approach.configFqn.takeUnless { it.endsWith(" .xml" ) }?.let {
166
+ JavaPsiFacade .getInstance(project).findClass(it, GlobalSearchScope .projectScope(project)) ? :
167
+ error(" Can't find configuration class $it " )
168
+ }
169
+ }
170
+ val promise = compile(project, (model.srcClasses + listOfNotNull(springConfigClass)).map { it.containingFile.virtualFile }.toTypedArray())
160
171
promise.onSuccess {
161
172
if (it.hasErrors() || it.isAborted)
162
173
return @onSuccess
@@ -183,7 +194,7 @@ object UtTestsDialogProcessor {
183
194
updateIndicator(indicator, ProgressRange .SOLVING , " Generate tests: read classes" , 0.0 )
184
195
185
196
val buildPaths = ReadAction
186
- .nonBlocking<BuildPaths ?> { findPaths(model.srcClasses) }
197
+ .nonBlocking<BuildPaths ?> { findPaths(model.srcClasses, springConfigClass ) }
187
198
.executeSynchronously()
188
199
? : return
189
200
@@ -204,23 +215,39 @@ object UtTestsDialogProcessor {
204
215
205
216
val applicationContext = when (model.projectType) {
206
217
Spring -> {
207
- val shouldUseImplementors = when (model.typeReplacementApproach) {
208
- TypeReplacementApproach .DoNotReplace -> false
209
- is TypeReplacementApproach .ReplaceIfPossible -> true
218
+ val beanQualifiedNames =
219
+ if (! model.useSpringAnalyzer) emptyList()
220
+ else when (val approach = model.typeReplacementApproach) {
221
+ TypeReplacementApproach .DoNotReplace -> emptyList()
222
+ is TypeReplacementApproach .ReplaceIfPossible -> {
223
+ val springAnalyzerProcess = SpringAnalyzerProcess .createBlocking(Unit )
224
+
225
+ springAnalyzerProcess.terminateOnException { _ ->
226
+ val beans = springAnalyzerProcess.getBeanQualifiedNames(
227
+ classpathList,
228
+ approach.configFqn,
229
+ emptyList(),
230
+ emptyList()
231
+ )
232
+ invokeLater {
233
+ springAnalyzerProcess.terminate()
234
+ }
235
+ beans
236
+ }
237
+ }
210
238
}
211
239
212
240
SpringApplicationContext (
213
241
mockFrameworkInstalled,
214
242
staticMockingConfigured,
215
- // TODO: obtain bean definitions and other info from `utbot-spring-analyzer`
216
- beanQualifiedNames = emptyList(),
217
- shouldUseImplementors = shouldUseImplementors,
243
+ beanQualifiedNames,
244
+ shouldUseImplementors = beanQualifiedNames.isNotEmpty(),
218
245
)
219
246
}
220
247
else -> ApplicationContext (mockFrameworkInstalled, staticMockingConfigured)
221
248
}
222
249
223
- val process = EngineProcess .createBlocking(project, classNameToPath)
250
+ val process = EngineProcess .createBlocking(EngineProcess . Params ( project, classNameToPath) )
224
251
225
252
process.terminateOnException { _ ->
226
253
process.setupUtContext(buildDirs + classpathList)
@@ -409,16 +436,23 @@ object UtTestsDialogProcessor {
409
436
}
410
437
}
411
438
412
- private fun findPaths (srcClasses : Set <PsiClass >): BuildPaths ? {
439
+ private fun findPaths (srcClasses : Set <PsiClass >, springConfigPsiClass : PsiClass ? ): BuildPaths ? {
413
440
val srcModule = findSrcModule(srcClasses)
441
+ val springConfigModule = springConfigPsiClass?.let { it.module ? : error(" Module for spring configuration class not found" ) }
414
442
415
- val buildDirs = CompilerPaths .getOutputPaths(arrayOf(srcModule))
443
+ val buildDirs = CompilerPaths .getOutputPaths(setOfNotNull(
444
+ srcModule, springConfigModule
445
+ ).toTypedArray())
416
446
.toList()
417
447
.filter { Paths .get(it).exists() }
418
448
.nullize() ? : return null
419
449
420
450
val pathsList = OrderEnumerator .orderEntries(srcModule).recursively().pathsList
421
451
452
+ springConfigModule?.takeIf { it != srcModule }?.let { module ->
453
+ pathsList.addAll(OrderEnumerator .orderEntries(module).recursively().pathsList.pathList)
454
+ }
455
+
422
456
val (classpath, classpathList) = if (IntelliJApiHelper .isAndroidStudio()) {
423
457
// Filter out manifests from classpath.
424
458
val filterPredicate = { it: String ->
@@ -442,6 +476,6 @@ object UtTestsDialogProcessor {
442
476
val classpath : String ,
443
477
val classpathList : List <String >,
444
478
val pluginJarsPath : List <String >
445
- // ^ TODO: Now we collect ALL dependent libs and pass them to the instrumented process . Most of them are redundant.
479
+ // ^ TODO: Now we collect ALL dependent libs and pass them to the instrumented and spring analyzer processes . Most of them are redundant.
446
480
)
447
481
}
0 commit comments