From 4d52183c23a901d70d3123adcc68a0aa8e68fc04 Mon Sep 17 00:00:00 2001 From: Ivan Volkov Date: Tue, 30 Aug 2022 21:49:21 +0300 Subject: [PATCH] Autoadd Junit5-params dependency for junit5 projects without it when needed --- .../org/utbot/framework/codegen/Domain.kt | 1 + .../codegen/model/util/DependencyPatterns.kt | 24 +++++++++++- .../models/ExternalLibraryDescriptors.kt | 3 ++ .../plugin/ui/GenerateTestsDialogWindow.kt | 39 ++++++++++++++++++- .../plugin/ui/utils/LibraryMatcher.kt | 8 ++++ 5 files changed, 73 insertions(+), 2 deletions(-) diff --git a/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/Domain.kt b/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/Domain.kt index 54a70861a9..2e8fe3d200 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/Domain.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/Domain.kt @@ -173,6 +173,7 @@ sealed class TestFramework( override val displayName: String, override val description: String = "Use $displayName as test framework", ) : CodeGenerationSettingItem { + var isParametrizedTestsConfigured = false var isInstalled: Boolean = false abstract val mainPackage: String abstract val assertionsClass: ClassId diff --git a/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/model/util/DependencyPatterns.kt b/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/model/util/DependencyPatterns.kt index 14245d10c0..f84398ecbb 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/model/util/DependencyPatterns.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/model/util/DependencyPatterns.kt @@ -26,6 +26,23 @@ fun TestFramework.patterns(): Patterns { return Patterns(moduleLibraryPatterns, libraryPatterns) } + +fun TestFramework.parametrizedTestsPatterns(): Patterns { + val moduleLibraryPatterns = when (this) { + Junit4 -> emptyList() + Junit5 -> emptyList() // emptyList here because JUnit5 module may not be enough for parametrized tests if :junit-jupiter-params: is not installed + TestNg -> testNgModulePatterns + } + val libraryPatterns = when (this) { + Junit4 -> emptyList() + Junit5 -> junit5ParametrizedTestsPatterns + TestNg -> testNgPatterns + } + + return Patterns(moduleLibraryPatterns, libraryPatterns) +} + + fun MockFramework.patterns(): Patterns { val moduleLibraryPatterns = when (this) { MockFramework.MOCKITO -> mockitoModulePatterns @@ -47,11 +64,16 @@ val JUNIT_5_MVN_PATTERN = Regex("org\\.junit\\.jupiter:junit-jupiter-api:5(\\.[0 val JUNIT_5_BASIC_PATTERN = Regex("JUnit5\\.4") val junit5Patterns = listOf(JUNIT_5_JAR_PATTERN, JUNIT_5_MVN_PATTERN, JUNIT_5_BASIC_PATTERN) +val JUNIT_5_PARAMETRIZED_JAR_PATTERN = Regex("junit-jupiter-params-5(\\.[0-9]+){1,2}") +val JUNIT_5_PARAMETRIZED_MVN_PATTERN = Regex("org\\.junit\\.jupiter\\.junit-jupiter-params:5(\\.[0-9]+){1,2}") +val junit5ParametrizedTestsPatterns = listOf(JUNIT_5_JAR_PATTERN, JUNIT_5_BASIC_PATTERN, + JUNIT_5_PARAMETRIZED_JAR_PATTERN, JUNIT_5_PARAMETRIZED_MVN_PATTERN) + val JUNIT5_BASIC_MODULE_PATTERN = Regex("junit-jupiter") val junit5ModulePatterns = listOf(JUNIT5_BASIC_MODULE_PATTERN) val TEST_NG_JAR_PATTERN = Regex("testng-[0-9](\\.[0-9]+){2}") -val TEST_NG_MVN_PATTERN = Regex("org\\.testng:testng:(\\.[0-9]+){3}") +val TEST_NG_MVN_PATTERN = Regex("org\\.testng:testng:[0-9](\\.[0-9]+){2}") val TEST_NG_BASIC_PATTERN = Regex("testng") val testNgPatterns = listOf(TEST_NG_JAR_PATTERN, TEST_NG_MVN_PATTERN, TEST_NG_BASIC_PATTERN) diff --git a/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/models/ExternalLibraryDescriptors.kt b/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/models/ExternalLibraryDescriptors.kt index 634620d45d..e3106f37e8 100644 --- a/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/models/ExternalLibraryDescriptors.kt +++ b/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/models/ExternalLibraryDescriptors.kt @@ -12,5 +12,8 @@ fun jUnit5LibraryDescriptor(versionInProject: String?) = fun testNgLibraryDescriptor(versionInProject: String?) = ExternalLibraryDescriptor("org.testng", "testng", "6.8.8", null, versionInProject ?: "6.9.6") +fun jUnit5ParametrizedTestsLibraryDescriptor(versionInProject: String?) = + ExternalLibraryDescriptor("org.junit.jupiter", "junit-jupiter-params", "5.8.1", null, versionInProject ?: "5.8.1") + fun mockitoCoreLibraryDescriptor(versionInProject: String?) = ExternalLibraryDescriptor("org.mockito", "mockito-core", "3.5.0", "4.2.0", versionInProject ?: "4.2.0") \ No newline at end of file diff --git a/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/ui/GenerateTestsDialogWindow.kt b/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/ui/GenerateTestsDialogWindow.kt index 9fa4228dcb..80813ae7f8 100644 --- a/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/ui/GenerateTestsDialogWindow.kt +++ b/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/ui/GenerateTestsDialogWindow.kt @@ -116,6 +116,7 @@ import org.utbot.framework.util.Conflict import org.utbot.intellij.plugin.models.GenerateTestsModel import org.utbot.intellij.plugin.models.jUnit4LibraryDescriptor import org.utbot.intellij.plugin.models.jUnit5LibraryDescriptor +import org.utbot.intellij.plugin.models.jUnit5ParametrizedTestsLibraryDescriptor import org.utbot.intellij.plugin.models.mockitoCoreLibraryDescriptor import org.utbot.intellij.plugin.models.packageName import org.utbot.intellij.plugin.models.testNgLibraryDescriptor @@ -125,6 +126,7 @@ import org.utbot.intellij.plugin.ui.utils.LibrarySearchScope import org.utbot.intellij.plugin.ui.utils.addSourceRootIfAbsent import org.utbot.intellij.plugin.ui.utils.allLibraries import org.utbot.intellij.plugin.ui.utils.findFrameworkLibrary +import org.utbot.intellij.plugin.ui.utils.findParametrizedTestsLibrary import org.utbot.intellij.plugin.ui.utils.getOrCreateTestResourcesPath import org.utbot.intellij.plugin.ui.utils.isBuildWithGradle import org.utbot.intellij.plugin.ui.utils.kotlinTargetPlatform @@ -196,6 +198,7 @@ class GenerateTestsDialogWindow(val model: GenerateTestsModel) : DialogWrapper(m TestFramework.allItems.forEach { it.isInstalled = findFrameworkLibrary(model.project, model.testModule, it) != null + it.isParametrizedTestsConfigured = findParametrizedTestsLibrary(model.project, model.testModule, it) != null } MockFramework.allItems.forEach { it.isInstalled = findFrameworkLibrary(model.project, model.testModule, it) != null @@ -532,6 +535,7 @@ class GenerateTestsDialogWindow(val model: GenerateTestsModel) : DialogWrapper(m configureTestFrameworkIfRequired() configureMockFrameworkIfRequired() configureStaticMockingIfRequired() + configureParametrizedTestsIfRequired() super.doOKAction() } @@ -665,8 +669,14 @@ class GenerateTestsDialogWindow(val model: GenerateTestsModel) : DialogWrapper(m //region configure frameworks private fun configureTestFrameworkIfRequired() { - if (!testFrameworks.item.isInstalled) { + val testFramework = testFrameworks.item + if (!testFramework.isInstalled) { configureTestFramework() + + // Configuring framework will configure parametrized tests automatically + // TODO: do something more general here + // Note: we can't just update isParametrizedTestsConfigured as before because project.allLibraries() won't be updated immediately + testFramework.isParametrizedTestsConfigured = true } model.conflictTriggers[Conflict.TestFrameworkConflict] = TestFramework.allItems.count { it.isInstalled } > 1 @@ -684,6 +694,12 @@ class GenerateTestsDialogWindow(val model: GenerateTestsModel) : DialogWrapper(m } } + private fun configureParametrizedTestsIfRequired() { + if (parametrizedTestSources.item != ParametrizedTestSource.DO_NOT_PARAMETRIZE && !testFrameworks.item.isParametrizedTestsConfigured) { + configureParametrizedTests() + } + } + private fun configureTestFramework() { val selectedTestFramework = testFrameworks.item @@ -742,6 +758,27 @@ class GenerateTestsDialogWindow(val model: GenerateTestsModel) : DialogWrapper(m } } + private fun configureParametrizedTests() { + // TODO: currently first three declarations are copy-pasted from configureTestFramework(), maybe fix this somehow? + val selectedTestFramework = testFrameworks.item + + val libraryInProject = + findFrameworkLibrary(model.project, model.testModule, selectedTestFramework, LibrarySearchScope.Project) + val versionInProject = libraryInProject?.libraryName?.parseVersion() + + val libraryDescriptor: ExternalLibraryDescriptor? = when (selectedTestFramework) { + Junit4 -> error("Parametrized tests are not supported for JUnit 4") + Junit5 -> jUnit5ParametrizedTestsLibraryDescriptor(versionInProject) + TestNg -> null // Parametrized tests come with TestNG by default + } + + selectedTestFramework.isParametrizedTestsConfigured = true + libraryDescriptor?.let { + addDependency(model.testModule, it) + .onError { selectedTestFramework.isParametrizedTestsConfigured = false } + } + } + /** * Adds the dependency for selected framework via [JavaProjectModelModificationService]. * diff --git a/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/ui/utils/LibraryMatcher.kt b/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/ui/utils/LibraryMatcher.kt index cc82cde6b6..e6ae80afdc 100644 --- a/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/ui/utils/LibraryMatcher.kt +++ b/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/ui/utils/LibraryMatcher.kt @@ -6,6 +6,7 @@ import org.utbot.framework.plugin.api.MockFramework import com.intellij.openapi.module.Module import com.intellij.openapi.project.Project import com.intellij.openapi.roots.LibraryOrderEntry +import org.utbot.framework.codegen.model.util.parametrizedTestsPatterns import org.utbot.framework.codegen.model.util.Patterns fun findFrameworkLibrary( @@ -24,6 +25,13 @@ fun findFrameworkLibrary( scope: LibrarySearchScope = LibrarySearchScope.Module, ): LibraryOrderEntry? = findMatchingLibrary(project, testModule, mockFramework.patterns(), scope) +fun findParametrizedTestsLibrary( + project: Project, + testModule: Module, + testFramework: TestFramework, + scope: LibrarySearchScope = LibrarySearchScope.Module, +): LibraryOrderEntry? = findMatchingLibrary(project, testModule, testFramework.parametrizedTestsPatterns(), scope) + private fun findMatchingLibrary( project: Project, testModule: Module,