Skip to content

Commit 661a89a

Browse files
Required libraries can be installed silently #492 (#494)
1 parent c85accc commit 661a89a

File tree

3 files changed

+93
-46
lines changed

3 files changed

+93
-46
lines changed

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

Lines changed: 7 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -187,16 +187,12 @@ class GenerateTestsDialogWindow(val model: GenerateTestsModel) : DialogWrapper(m
187187
setResizable(false)
188188

189189
// Configure notification urls callbacks
190-
TestReportUrlOpeningListener.callbacks[TestReportUrlOpeningListener.mockitoSuffix]?.plusAssign {
191-
if (createMockFrameworkNotificationDialog() == Messages.YES) {
192-
configureMockFramework()
193-
}
190+
TestsReportNotifier.urlOpeningListener.callbacks[TestReportUrlOpeningListener.mockitoSuffix]?.plusAssign {
191+
configureMockFramework()
194192
}
195193

196-
TestReportUrlOpeningListener.callbacks[TestReportUrlOpeningListener.mockitoInlineSuffix]?.plusAssign {
197-
if (createStaticsMockingNotificationDialog() == Messages.YES) {
198-
configureStaticMocking()
199-
}
194+
TestsReportNotifier.urlOpeningListener.callbacks[TestReportUrlOpeningListener.mockitoInlineSuffix]?.plusAssign {
195+
configureStaticMocking()
200196
}
201197

202198
TestReportUrlOpeningListener.callbacks[TestReportUrlOpeningListener.eventLogSuffix]?.plusAssign {
@@ -619,29 +615,21 @@ class GenerateTestsDialogWindow(val model: GenerateTestsModel) : DialogWrapper(m
619615
//region configure frameworks
620616

621617
private fun configureTestFrameworkIfRequired() {
622-
val frameworkNotInstalled = !testFrameworks.item.isInstalled
623-
624-
if (frameworkNotInstalled && createTestFrameworkNotificationDialog() == Messages.YES) {
618+
if (!testFrameworks.item.isInstalled) {
625619
configureTestFramework()
626620
}
627621

628622
model.conflictTriggers[Conflict.TestFrameworkConflict] = TestFramework.allItems.count { it.isInstalled } > 1
629623
}
630624

631625
private fun configureMockFrameworkIfRequired() {
632-
val frameworkNotInstalled =
633-
mockStrategies.item != MockStrategyApi.NO_MOCKS && !MOCKITO.isInstalled
634-
635-
if (frameworkNotInstalled && createMockFrameworkNotificationDialog() == Messages.YES) {
626+
if (mockStrategies.item != MockStrategyApi.NO_MOCKS && !MOCKITO.isInstalled) {
636627
configureMockFramework()
637628
}
638629
}
639630

640631
private fun configureStaticMockingIfRequired() {
641-
val frameworkNotConfigured =
642-
staticsMocking.item != NoStaticMocking && !staticsMocking.item.isConfigured
643-
644-
if (frameworkNotConfigured && createStaticsMockingNotificationDialog() == Messages.YES) {
632+
if (staticsMocking.item != NoStaticMocking && !staticsMocking.item.isConfigured) {
645633
configureStaticMocking()
646634
}
647635
}
@@ -664,15 +652,6 @@ class GenerateTestsDialogWindow(val model: GenerateTestsModel) : DialogWrapper(m
664652
.onError { selectedTestFramework.isInstalled = false }
665653
}
666654

667-
private fun createTestFrameworkNotificationDialog() = Messages.showYesNoDialog(
668-
"""Selected test framework ${testFrameworks.item.displayName} is not installed into current module.
669-
|Would you like to install it now?""".trimMargin(),
670-
title,
671-
"Yes",
672-
"No",
673-
Messages.getQuestionIcon(),
674-
)
675-
676655
private fun configureMockFramework() {
677656
val selectedMockFramework = MOCKITO
678657

@@ -749,24 +728,6 @@ class GenerateTestsDialogWindow(val model: GenerateTestsModel) : DialogWrapper(m
749728
}
750729
}
751730

752-
private fun createMockFrameworkNotificationDialog() = Messages.showYesNoDialog(
753-
"""Mock framework ${MOCKITO.displayName} is not installed into current module.
754-
|Would you like to install it now?""".trimMargin(),
755-
title,
756-
"Yes",
757-
"No",
758-
Messages.getQuestionIcon(),
759-
)
760-
761-
private fun createStaticsMockingNotificationDialog() = Messages.showYesNoDialog(
762-
"""A framework ${MOCKITO.displayName} is not configured to mock static methods.
763-
|Would you like to configure it now?""".trimMargin(),
764-
title,
765-
"Yes",
766-
"No",
767-
Messages.getQuestionIcon(),
768-
)
769-
770731
//endregion
771732

772733
/**
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
package org.utbot.intellij.plugin.util
2+
3+
import com.intellij.codeInsight.daemon.impl.quickfix.LocateLibraryDialog
4+
import com.intellij.codeInsight.daemon.impl.quickfix.OrderEntryFix
5+
import com.intellij.jarRepository.JarRepositoryManager
6+
import com.intellij.openapi.application.WriteAction
7+
import com.intellij.openapi.module.Module
8+
import com.intellij.openapi.project.Project
9+
import com.intellij.openapi.roots.DependencyScope
10+
import com.intellij.openapi.roots.ExternalLibraryDescriptor
11+
import com.intellij.openapi.roots.ModuleRootModificationUtil
12+
import com.intellij.openapi.roots.OrderRootType
13+
import com.intellij.openapi.roots.impl.IdeaProjectModelModifier
14+
import com.intellij.openapi.roots.libraries.LibraryTablesRegistrar
15+
import com.intellij.openapi.roots.libraries.LibraryUtil
16+
import com.intellij.util.PathUtil
17+
import com.intellij.util.containers.ContainerUtil
18+
import org.jetbrains.concurrency.Promise
19+
import org.jetbrains.concurrency.resolvedPromise
20+
import org.jetbrains.idea.maven.utils.library.RepositoryLibraryDescription
21+
import org.jetbrains.idea.maven.utils.library.RepositoryLibraryProperties
22+
import org.jetbrains.jps.model.library.JpsMavenRepositoryLibraryDescriptor
23+
24+
class UtProjectModelModifier(val project: Project) : IdeaProjectModelModifier(project) {
25+
override fun addExternalLibraryDependency(
26+
modules: Collection<Module>,
27+
descriptor: ExternalLibraryDescriptor,
28+
scope: DependencyScope
29+
): Promise<Void>? {
30+
val defaultRoots = descriptor.libraryClassesRoots
31+
val firstModule = ContainerUtil.getFirstItem(modules) ?: return null
32+
val classesRoots = if (defaultRoots.isNotEmpty()) {
33+
LocateLibraryDialog(
34+
firstModule,
35+
defaultRoots,
36+
descriptor.presentableName
37+
).showAndGetResult()
38+
} else {
39+
val roots = JarRepositoryManager.loadDependenciesModal(
40+
project,
41+
RepositoryLibraryProperties(JpsMavenRepositoryLibraryDescriptor(descriptor.mavenCoordinates())),
42+
/* loadSources = */ false,
43+
/* loadJavadoc = */ false,
44+
/* copyTo = */ null,
45+
/* repositories = */ null
46+
)
47+
if (roots.isEmpty()) {
48+
return null
49+
}
50+
roots.filter { orderRoot -> orderRoot.type === OrderRootType.CLASSES }
51+
.map { PathUtil.getLocalPath(it.file) }.toList()
52+
}
53+
if (classesRoots.isNotEmpty()) {
54+
val urls = OrderEntryFix.refreshAndConvertToUrls(classesRoots)
55+
if (modules.size == 1) {
56+
ModuleRootModificationUtil.addModuleLibrary(
57+
firstModule,
58+
if (classesRoots.size > 1) descriptor.presentableName else null,
59+
urls,
60+
emptyList(),
61+
scope
62+
)
63+
} else {
64+
WriteAction.run<RuntimeException> {
65+
LibraryUtil.createLibrary(
66+
LibraryTablesRegistrar.getInstance().getLibraryTable(project),
67+
descriptor.presentableName
68+
).let {
69+
val model = it.modifiableModel
70+
urls.forEach { url -> model.addRoot(url, OrderRootType.CLASSES) }
71+
model.commit()
72+
modules.forEach { module ->
73+
ModuleRootModificationUtil.addDependency(module, it, scope, false)
74+
}
75+
}
76+
}
77+
}
78+
}
79+
return resolvedPromise()
80+
}
81+
82+
private fun ExternalLibraryDescriptor.mavenCoordinates(): String {
83+
return "$libraryGroupId:$libraryArtifactId:${preferredVersion ?: RepositoryLibraryDescription.ReleaseVersionId}"
84+
}
85+
}

utbot-intellij/src/main/resources/META-INF/plugin.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
<projectService serviceImplementation="org.utbot.intellij.plugin.settings.Settings" preload="true"/>
3434
<registryKey defaultValue="false" description="Enable editing Kotlin test files" key="kotlin.ultra.light.classes.empty.text.range"/>
3535
<postStartupActivity implementation="org.utbot.intellij.plugin.ui.GotItTooltipActivity"/>
36+
<projectModelModifier implementation="org.utbot.intellij.plugin.util.UtProjectModelModifier"/>
3637
</extensions>
3738

3839
<!-- Minimum and maximum build of IDE compatible with the plugin -->

0 commit comments

Comments
 (0)