Skip to content

Commit b4a3704

Browse files
authored
Programmatically detect DI frameworks (Spring Beans and Spring Boot) #1929 (#1956)
1 parent 1389967 commit b4a3704

File tree

4 files changed

+78
-6
lines changed

4 files changed

+78
-6
lines changed

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

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -740,3 +740,26 @@ enum class TypeReplacementApproach {
740740
*/
741741
REPLACE_IF_POSSIBLE,
742742
}
743+
744+
abstract class DependencyInjectionFramework(
745+
override val id: String,
746+
override val displayName: String,
747+
override val description: String = "Use $displayName as dependency injection framework",
748+
) : CodeGenerationSettingItem {
749+
var isInstalled = false
750+
751+
companion object : CodeGenerationSettingBox {
752+
override val defaultItem: DependencyInjectionFramework get() = SpringBoot
753+
override val allItems: List<DependencyInjectionFramework> get() = listOf(SpringBoot, SpringBeans)
754+
}
755+
}
756+
757+
object SpringBeans : DependencyInjectionFramework(
758+
id = "spring-beans",
759+
displayName = "Spring Beans"
760+
)
761+
762+
object SpringBoot : DependencyInjectionFramework(
763+
id = "spring-boot",
764+
displayName = "Spring Boot"
765+
)

utbot-framework/src/main/kotlin/org/utbot/framework/plugin/api/utils/DependencyPatterns.kt

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
package org.utbot.framework.plugin.api.utils
22

3+
import org.utbot.framework.codegen.domain.DependencyInjectionFramework
34
import org.utbot.framework.codegen.domain.Junit4
45
import org.utbot.framework.codegen.domain.Junit5
6+
import org.utbot.framework.codegen.domain.SpringBeans
7+
import org.utbot.framework.codegen.domain.SpringBoot
58
import org.utbot.framework.codegen.domain.TestFramework
69
import org.utbot.framework.codegen.domain.TestNg
710
import org.utbot.framework.plugin.api.MockFramework
@@ -16,13 +19,13 @@ fun TestFramework.patterns(): Patterns {
1619
Junit4 -> junit4ModulePatterns
1720
Junit5 -> junit5ModulePatterns
1821
TestNg -> testNgModulePatterns
19-
else -> throw UnsupportedOperationException()
22+
else -> throw UnsupportedOperationException("Unknown test framework $this")
2023
}
2124
val libraryPatterns = when (this) {
2225
Junit4 -> junit4Patterns
2326
Junit5 -> junit5Patterns
2427
TestNg -> testNgPatterns
25-
else -> throw UnsupportedOperationException()
28+
else -> throw UnsupportedOperationException("Unknown test framework $this")
2629
}
2730

2831
return Patterns(moduleLibraryPatterns, libraryPatterns)
@@ -34,13 +37,13 @@ fun TestFramework.parametrizedTestsPatterns(): Patterns {
3437
Junit4 -> emptyList()
3538
Junit5 -> emptyList() // emptyList here because JUnit5 module may not be enough for parametrized tests if :junit-jupiter-params: is not installed
3639
TestNg -> testNgModulePatterns
37-
else -> throw UnsupportedOperationException()
40+
else -> throw UnsupportedOperationException("Unknown test framework $this")
3841
}
3942
val libraryPatterns = when (this) {
4043
Junit4 -> emptyList()
4144
Junit5 -> junit5ParametrizedTestsPatterns
4245
TestNg -> testNgPatterns
43-
else -> throw UnsupportedOperationException()
46+
else -> throw UnsupportedOperationException("Unknown test framework $this")
4447
}
4548

4649
return Patterns(moduleLibraryPatterns, libraryPatterns)
@@ -58,6 +61,21 @@ fun MockFramework.patterns(): Patterns {
5861
return Patterns(moduleLibraryPatterns, libraryPatterns)
5962
}
6063

64+
fun DependencyInjectionFramework.patterns(): Patterns {
65+
val moduleLibraryPatterns = when (this) {
66+
SpringBoot -> springBootModulePatterns
67+
SpringBeans -> springBeansModulePatterns
68+
else -> throw UnsupportedOperationException("Unknown dependency injection framework $this")
69+
}
70+
val libraryPatterns = when (this) {
71+
SpringBoot -> springBootPatterns
72+
SpringBeans -> springBeansPatterns
73+
else -> throw UnsupportedOperationException("Unknown dependency injection framework $this")
74+
}
75+
76+
return Patterns(moduleLibraryPatterns, libraryPatterns)
77+
}
78+
6179
val JUNIT_4_JAR_PATTERN = Regex("junit-4(\\.1[2-9])(\\.[0-9]+)?")
6280
val JUNIT_4_MVN_PATTERN = Regex("junit:junit:4(\\.1[2-9])(\\.[0-9]+)?")
6381
val junit4Patterns = listOf(JUNIT_4_JAR_PATTERN, JUNIT_4_MVN_PATTERN)
@@ -93,4 +111,18 @@ val mockitoModulePatterns = listOf(MOCKITO_BASIC_MODULE_PATTERN)
93111

94112
const val MOCKITO_EXTENSIONS_FOLDER = "mockito-extensions"
95113
const val MOCKITO_MOCKMAKER_FILE_NAME = "org.mockito.plugins.MockMaker"
96-
val MOCKITO_EXTENSIONS_FILE_CONTENT = "mock-maker-inline"
114+
val MOCKITO_EXTENSIONS_FILE_CONTENT = "mock-maker-inline"
115+
116+
val SPRING_BEANS_JAR_PATTERN = Regex("spring-beans-([0-9]+)(\\.[0-9]+){1,2}")
117+
val SPRING_BEANS_MVN_PATTERN = Regex("org\\.springframework:spring-beans:([0-9]+)(\\.[0-9]+){1,2}")
118+
val springBeansPatterns = listOf(SPRING_BEANS_JAR_PATTERN, SPRING_BEANS_MVN_PATTERN)
119+
120+
val SPRING_BEANS_BASIC_MODULE_PATTERN = Regex("spring-beans")
121+
val springBeansModulePatterns = listOf(SPRING_BEANS_BASIC_MODULE_PATTERN)
122+
123+
val SPRING_BOOT_JAR_PATTERN = Regex("spring-boot-([0-9]+)(\\.[0-9]+){1,2}")
124+
val SPRING_BOOT_MVN_PATTERN = Regex("org\\.springframework\\.boot:spring-boot:([0-9]+)(\\.[0-9]+){1,2}")
125+
val springBootPatterns = listOf(SPRING_BOOT_JAR_PATTERN, SPRING_BOOT_MVN_PATTERN)
126+
127+
val SPRING_BOOT_BASIC_MODULE_PATTERN = Regex("spring-boot")
128+
val springBootModulePatterns = listOf(SPRING_BOOT_BASIC_MODULE_PATTERN)

utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/ui/GenerateTestsDialogWindow.kt

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,12 +98,14 @@ import org.jetbrains.concurrency.thenRun
9898
import org.utbot.common.PathUtil.toPath
9999
import org.utbot.framework.UtSettings
100100
import org.utbot.framework.codegen.domain.ApplicationType
101+
import org.utbot.framework.codegen.domain.DependencyInjectionFramework
101102
import org.utbot.framework.codegen.domain.ForceStaticMocking
102103
import org.utbot.framework.codegen.domain.Junit4
103104
import org.utbot.framework.codegen.domain.Junit5
104105
import org.utbot.framework.codegen.domain.MockitoStaticMocking
105106
import org.utbot.framework.codegen.domain.NoStaticMocking
106107
import org.utbot.framework.codegen.domain.ParametrizedTestSource
108+
import org.utbot.framework.codegen.domain.SpringBeans
107109
import org.utbot.framework.codegen.domain.TypeReplacementApproach
108110
import org.utbot.framework.codegen.domain.StaticsMocking
109111
import org.utbot.framework.codegen.domain.TestFramework
@@ -135,6 +137,7 @@ import org.utbot.intellij.plugin.ui.utils.LibrarySearchScope
135137
import org.utbot.intellij.plugin.ui.utils.addSourceRootIfAbsent
136138
import org.utbot.intellij.plugin.ui.utils.allLibraries
137139
import org.utbot.intellij.plugin.ui.utils.createTestFrameworksRenderer
140+
import org.utbot.intellij.plugin.ui.utils.findDependencyInjectionLibrary
138141
import org.utbot.intellij.plugin.ui.utils.findFrameworkLibrary
139142
import org.utbot.intellij.plugin.ui.utils.findParametrizedTestsLibrary
140143
import org.utbot.intellij.plugin.ui.utils.getOrCreateTestResourcesPath
@@ -235,6 +238,12 @@ class GenerateTestsDialogWindow(val model: GenerateTestsModel) : DialogWrapper(m
235238
MockFramework.allItems.forEach {
236239
it.isInstalled = findFrameworkLibrary(model.project, model.testModule, it) != null
237240
}
241+
DependencyInjectionFramework.allItems.forEach {
242+
it.isInstalled = findDependencyInjectionLibrary(model.project, model.testModule, it) != null
243+
}
244+
model.applicationType =
245+
if (SpringBeans.isInstalled) ApplicationType.SPRING_APPLICATION
246+
else ApplicationType.PURE_JVM
238247
StaticsMocking.allItems.forEach {
239248
it.isConfigured = staticsMockingConfigured()
240249
}
@@ -1063,4 +1072,4 @@ private fun ComboBox<*>.setHelpTooltipTextChanger(helpLabel: JBLabel) {
10631072
helpLabel.toolTipText = item.description
10641073
}
10651074
}
1066-
}
1075+
}

utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/ui/utils/LibraryMatcher.kt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import org.utbot.framework.plugin.api.MockFramework
55
import com.intellij.openapi.module.Module
66
import com.intellij.openapi.project.Project
77
import com.intellij.openapi.roots.LibraryOrderEntry
8+
import org.utbot.framework.codegen.domain.DependencyInjectionFramework
89
import org.utbot.framework.plugin.api.utils.Patterns
910
import org.utbot.framework.plugin.api.utils.parametrizedTestsPatterns
1011
import org.utbot.framework.plugin.api.utils.patterns
@@ -32,6 +33,13 @@ fun findParametrizedTestsLibrary(
3233
scope: LibrarySearchScope = LibrarySearchScope.Module,
3334
): LibraryOrderEntry? = findMatchingLibrary(project, testModule, testFramework.parametrizedTestsPatterns(), scope)
3435

36+
fun findDependencyInjectionLibrary(
37+
project: Project,
38+
testModule: Module,
39+
springModule: DependencyInjectionFramework,
40+
scope: LibrarySearchScope = LibrarySearchScope.Module
41+
): LibraryOrderEntry? = findMatchingLibrary(project, testModule, springModule.patterns(), scope)
42+
3543
private fun findMatchingLibrary(
3644
project: Project,
3745
testModule: Module,

0 commit comments

Comments
 (0)