From 9defc401fbf1849a173f72118cb86ea6445e3bb8 Mon Sep 17 00:00:00 2001 From: IlyaMuravjov Date: Mon, 13 Mar 2023 15:47:27 +0300 Subject: [PATCH 1/3] Implement BaseTestsModel.getSortedSpringConfigurationClasses() --- .../intellij/plugin/models/BaseTestModel.kt | 45 +++++++++++++++++++ .../TestFolderComboWithBrowseButton.kt | 9 +--- 2 files changed, 46 insertions(+), 8 deletions(-) diff --git a/utbot-ui-commons/src/main/kotlin/org/utbot/intellij/plugin/models/BaseTestModel.kt b/utbot-ui-commons/src/main/kotlin/org/utbot/intellij/plugin/models/BaseTestModel.kt index 97e0a4c0c6..b29438fc81 100644 --- a/utbot-ui-commons/src/main/kotlin/org/utbot/intellij/plugin/models/BaseTestModel.kt +++ b/utbot-ui-commons/src/main/kotlin/org/utbot/intellij/plugin/models/BaseTestModel.kt @@ -1,15 +1,24 @@ package org.utbot.intellij.plugin.models import com.intellij.openapi.module.Module +import com.intellij.openapi.module.ModuleManager import com.intellij.openapi.module.ModuleUtil import com.intellij.openapi.project.Project +import com.intellij.openapi.roots.TestModuleProperties import com.intellij.openapi.vfs.VirtualFile import com.intellij.openapi.vfs.newvfs.impl.FakeVirtualFile +import com.intellij.psi.JavaPsiFacade import com.intellij.psi.PsiClass +import com.intellij.psi.search.GlobalSearchScope +import com.intellij.psi.search.ProjectScope +import com.intellij.psi.search.searches.AnnotatedElementsSearch import org.jetbrains.kotlin.idea.core.getPackage import org.jetbrains.kotlin.idea.util.projectStructure.allModules +import org.jetbrains.kotlin.idea.util.rootManager +import org.jetbrains.kotlin.idea.util.sourceRoot import org.utbot.framework.plugin.api.CodegenLanguage import org.utbot.intellij.plugin.ui.utils.ITestSourceRoot +import org.utbot.intellij.plugin.ui.utils.getSortedTestRoots import org.utbot.intellij.plugin.ui.utils.isBuildWithGradle import org.utbot.intellij.plugin.ui.utils.suitableTestSourceRoots @@ -56,6 +65,42 @@ open class BaseTestsModel( } } + fun getSortedTestRoots(): MutableList = getSortedTestRoots( + getAllTestSourceRoots(), + sourceRootHistory, + srcModule.rootManager.sourceRoots.map { file: VirtualFile -> file.toNioPath().toString() }, + codegenLanguage + ) + + fun getSortedSpringConfigurationClasses(): List { + val psiFacade = JavaPsiFacade.getInstance(project) + val testRootToIndex = getSortedTestRoots().withIndex().associate { (i, root) -> root.dir to i } + + // not using `srcModule.testModules(project)` here because it returns + // test modules for dependencies of source module if no test roots are found + // for the source module itself, however we don't want to search for + // configurations there because they are unlikely to be of any use + val testModules = ModuleManager.getInstance(project).modules.filter { module -> + srcModule == TestModuleProperties.getInstance(module).productionModule + } + + val searchScope = testModules.fold(GlobalSearchScope.moduleScope(srcModule)) { accScope, module -> + accScope.union(GlobalSearchScope.moduleScope(module)) + } + + return listOf( + "org.springframework.boot.test.context.TestConfiguration", + "org.springframework.context.annotation.Configuration" + ).mapNotNull { + psiFacade.findClass(it, ProjectScope.getLibrariesScope(project)) + }.flatMap { annotation -> + AnnotatedElementsSearch + .searchPsiClasses(annotation, searchScope) + .findAll() + .sortedBy { testRootToIndex[it.containingFile.sourceRoot] ?: Int.MAX_VALUE } + } + } + fun updateSourceRootHistory(path: String) { sourceRootHistory.apply { remove(path)//Remove existing entry if any diff --git a/utbot-ui-commons/src/main/kotlin/org/utbot/intellij/plugin/ui/components/TestFolderComboWithBrowseButton.kt b/utbot-ui-commons/src/main/kotlin/org/utbot/intellij/plugin/ui/components/TestFolderComboWithBrowseButton.kt index a5a7bd2a8c..618df2cf6c 100644 --- a/utbot-ui-commons/src/main/kotlin/org/utbot/intellij/plugin/ui/components/TestFolderComboWithBrowseButton.kt +++ b/utbot-ui-commons/src/main/kotlin/org/utbot/intellij/plugin/ui/components/TestFolderComboWithBrowseButton.kt @@ -17,12 +17,10 @@ import com.intellij.util.ui.UIUtil import java.io.File import javax.swing.DefaultComboBoxModel import javax.swing.JList -import org.jetbrains.kotlin.idea.util.rootManager import org.utbot.common.PathUtil import org.utbot.intellij.plugin.models.BaseTestsModel import org.utbot.intellij.plugin.ui.utils.ITestSourceRoot import org.utbot.intellij.plugin.ui.utils.addDedicatedTestRoot -import org.utbot.intellij.plugin.ui.utils.getSortedTestRoots import org.utbot.intellij.plugin.ui.utils.isBuildWithGradle private const val SET_TEST_FOLDER = "set test folder" @@ -58,12 +56,7 @@ class TestFolderComboWithBrowseButton(private val model: BaseTestsModel) : } } - val testRoots = getSortedTestRoots( - model.getAllTestSourceRoots(), - model.sourceRootHistory, - model.srcModule.rootManager.sourceRoots.map { file: VirtualFile -> file.toNioPath().toString() }, - model.codegenLanguage - ) + val testRoots = model.getSortedTestRoots() // this method is blocked for Gradle, where multiple test modules can exist model.testModule.addDedicatedTestRoot(testRoots, model.codegenLanguage) From 71931345a2f13d9b97025a705c320fdcdf16bdb5 Mon Sep 17 00:00:00 2001 From: IlyaMuravjov Date: Mon, 13 Mar 2023 16:15:44 +0300 Subject: [PATCH 2/3] Document BaseTestsModel.getSortedSpringConfigurationClasses() --- .../utbot/intellij/plugin/models/BaseTestModel.kt | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/utbot-ui-commons/src/main/kotlin/org/utbot/intellij/plugin/models/BaseTestModel.kt b/utbot-ui-commons/src/main/kotlin/org/utbot/intellij/plugin/models/BaseTestModel.kt index b29438fc81..1a1e2fcebf 100644 --- a/utbot-ui-commons/src/main/kotlin/org/utbot/intellij/plugin/models/BaseTestModel.kt +++ b/utbot-ui-commons/src/main/kotlin/org/utbot/intellij/plugin/models/BaseTestModel.kt @@ -72,6 +72,21 @@ open class BaseTestsModel( codegenLanguage ) + /** + * Searches for classes marked with `@Configuration` and `@TestConfiguration` annotations + * in source module and its test modules. + * + * Classes are sorted in the following order: + * - Classes marked with `@TestConfiguration` annotation + * - Classes marked with `@Configuration` annotation + * + * Inside one group classes are sorted by their roots in the following order: + * - Classes from test roots + * - Classes from source roots + * + * Classes from the test roots are additionally sorted by their roots + * in the order provided by [getSortedTestRoots] + */ fun getSortedSpringConfigurationClasses(): List { val psiFacade = JavaPsiFacade.getInstance(project) val testRootToIndex = getSortedTestRoots().withIndex().associate { (i, root) -> root.dir to i } From 27e370547af652bd148cdb9c36ac1bac4b78da85 Mon Sep 17 00:00:00 2001 From: Egor Kulikov Date: Tue, 14 Mar 2023 11:17:29 +0300 Subject: [PATCH 3/3] Little documentation improvements --- .../intellij/plugin/models/BaseTestModel.kt | 37 ++++++++----------- 1 file changed, 16 insertions(+), 21 deletions(-) diff --git a/utbot-ui-commons/src/main/kotlin/org/utbot/intellij/plugin/models/BaseTestModel.kt b/utbot-ui-commons/src/main/kotlin/org/utbot/intellij/plugin/models/BaseTestModel.kt index 1a1e2fcebf..61bb01eb72 100644 --- a/utbot-ui-commons/src/main/kotlin/org/utbot/intellij/plugin/models/BaseTestModel.kt +++ b/utbot-ui-commons/src/main/kotlin/org/utbot/intellij/plugin/models/BaseTestModel.kt @@ -13,6 +13,7 @@ import com.intellij.psi.search.GlobalSearchScope import com.intellij.psi.search.ProjectScope import com.intellij.psi.search.searches.AnnotatedElementsSearch import org.jetbrains.kotlin.idea.core.getPackage +import org.jetbrains.kotlin.idea.search.allScope import org.jetbrains.kotlin.idea.util.projectStructure.allModules import org.jetbrains.kotlin.idea.util.rootManager import org.jetbrains.kotlin.idea.util.sourceRoot @@ -73,42 +74,36 @@ open class BaseTestsModel( ) /** - * Searches for classes marked with `@Configuration` and `@TestConfiguration` annotations - * in source module and its test modules. + * Searches configuration classes in Spring application. * - * Classes are sorted in the following order: + * Classes are selected and sorted in the following order: * - Classes marked with `@TestConfiguration` annotation * - Classes marked with `@Configuration` annotation - * - * Inside one group classes are sorted by their roots in the following order: - * - Classes from test roots - * - Classes from source roots - * - * Classes from the test roots are additionally sorted by their roots - * in the order provided by [getSortedTestRoots] + * - firstly, from test source roots (in the order provided by [getSortedTestRoots]) + * - after that, from source roots */ fun getSortedSpringConfigurationClasses(): List { - val psiFacade = JavaPsiFacade.getInstance(project) val testRootToIndex = getSortedTestRoots().withIndex().associate { (i, root) -> root.dir to i } - // not using `srcModule.testModules(project)` here because it returns - // test modules for dependencies of source module if no test roots are found - // for the source module itself, however we don't want to search for - // configurations there because they are unlikely to be of any use - val testModules = ModuleManager.getInstance(project).modules.filter { module -> - srcModule == TestModuleProperties.getInstance(module).productionModule - } + // Not using `srcModule.testModules(project)` here because it returns + // test modules for dependent modules if no test roots are found in the source module itself. + // We don't want to search configurations there because they seem useless. + val testModules = ModuleManager.getInstance(project) + .modules + .filter { module -> TestModuleProperties.getInstance(module).productionModule == srcModule } val searchScope = testModules.fold(GlobalSearchScope.moduleScope(srcModule)) { accScope, module -> accScope.union(GlobalSearchScope.moduleScope(module)) } - return listOf( + val annotationClasses = listOf( "org.springframework.boot.test.context.TestConfiguration", "org.springframework.context.annotation.Configuration" ).mapNotNull { - psiFacade.findClass(it, ProjectScope.getLibrariesScope(project)) - }.flatMap { annotation -> + JavaPsiFacade.getInstance(project).findClass(it, project.allScope()) + } + + return annotationClasses.flatMap { annotation -> AnnotatedElementsSearch .searchPsiClasses(annotation, searchScope) .findAll()