Skip to content

Commit 39914b3

Browse files
Improve library versions analysis #2259 (#2263)
1 parent 5af13ec commit 39914b3

File tree

4 files changed

+107
-31
lines changed

4 files changed

+107
-31
lines changed

utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/models/ExternalLibraryDescriptors.kt

Lines changed: 54 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package org.utbot.intellij.plugin.models
22

33
import com.intellij.openapi.roots.ExternalLibraryDescriptor
44
import org.jetbrains.idea.maven.utils.library.RepositoryLibraryDescription
5+
import org.utbot.intellij.plugin.ui.utils.Version
56

67
val ExternalLibraryDescriptor.mavenCoordinates: String
78
get() = "$libraryGroupId:$libraryArtifactId:${preferredVersion ?: RepositoryLibraryDescription.ReleaseVersionId}"
@@ -10,33 +11,70 @@ val ExternalLibraryDescriptor.id: String
1011
get() = "$libraryGroupId:$libraryArtifactId"
1112

1213
//TODO: think about using JUnitExternalLibraryDescriptor from intellij-community sources (difficult to install)
13-
fun jUnit4LibraryDescriptor(versionInProject: String?) =
14-
ExternalLibraryDescriptor("junit", "junit", "4.12", null, versionInProject ?: "4.13.2")
14+
fun jUnit4LibraryDescriptor(versionInProject: Version?): ExternalLibraryDescriptor {
15+
val preferredVersion = if (versionInProject?.hasNumericOrEmptyPatch() == true) versionInProject?.plainText else "4.13.2"
16+
return ExternalLibraryDescriptor(
17+
"junit", "junit",
18+
"4.12", null, preferredVersion
19+
)
20+
}
1521

16-
fun jUnit5LibraryDescriptor(versionInProject: String?) =
17-
ExternalLibraryDescriptor("org.junit.jupiter", "junit-jupiter", "5.8.1", null, versionInProject ?: "5.8.1")
22+
fun jUnit5LibraryDescriptor(versionInProject: Version?): ExternalLibraryDescriptor {
23+
val preferredVersion = if (versionInProject?.hasNumericOrEmptyPatch() == true) versionInProject?.plainText else "5.8.1"
24+
return ExternalLibraryDescriptor(
25+
"org.junit.jupiter", "junit-jupiter",
26+
"5.8.1", null, preferredVersion
27+
)
28+
}
1829

19-
fun jUnit5ParametrizedTestsLibraryDescriptor(versionInProject: String?) =
20-
ExternalLibraryDescriptor("org.junit.jupiter", "junit-jupiter-params", "5.8.1", null, versionInProject ?: "5.8.1")
30+
fun jUnit5ParametrizedTestsLibraryDescriptor(versionInProject: Version?): ExternalLibraryDescriptor {
31+
val preferredVersion = if (versionInProject?.hasNumericOrEmptyPatch() == true) versionInProject?.plainText else "5.8.1"
32+
return ExternalLibraryDescriptor(
33+
"org.junit.jupiter", "junit-jupiter-params",
34+
"5.8.1", null, preferredVersion
35+
)
36+
}
2137

22-
fun mockitoCoreLibraryDescriptor(versionInProject: String?) =
23-
ExternalLibraryDescriptor("org.mockito", "mockito-core", "3.5.0", null, versionInProject ?: "4.2.0")
38+
fun mockitoCoreLibraryDescriptor(versionInProject: Version?): ExternalLibraryDescriptor {
39+
val preferredVersion = if (versionInProject?.hasNumericOrEmptyPatch() == true) versionInProject?.plainText else "4.2.0"
40+
return ExternalLibraryDescriptor(
41+
"org.mockito", "mockito-core",
42+
"3.5.0", null, preferredVersion
43+
)
44+
}
2445

25-
fun springBootTestLibraryDescriptor(versionInProject: String?) =
26-
ExternalLibraryDescriptor("org.springframework.boot", "spring-boot-test", "2.4.0", null, versionInProject ?: "3.0.6")
46+
fun springBootTestLibraryDescriptor(versionInProject: Version?): ExternalLibraryDescriptor {
47+
val preferredVersion = if (versionInProject?.hasNumericOrEmptyPatch() == true) versionInProject?.plainText else "3.0.6"
48+
return ExternalLibraryDescriptor(
49+
"org.springframework.boot", "spring-boot-test",
50+
"2.4.0", null, preferredVersion
51+
)
52+
}
2753

28-
fun springTestLibraryDescriptor(versionInProject: String?) =
29-
ExternalLibraryDescriptor("org.springframework", "spring-test", "2.5", null, versionInProject ?: "6.0.8")
54+
fun springTestLibraryDescriptor(versionInProject: Version?): ExternalLibraryDescriptor {
55+
val preferredVersion = if (versionInProject?.hasNumericOrEmptyPatch() == true) versionInProject?.plainText else "6.0.8"
56+
return ExternalLibraryDescriptor(
57+
"org.springframework", "spring-test",
58+
"2.5", null, preferredVersion
59+
)
60+
}
3061

3162

3263
/**
3364
* TestNg requires JDK 11 since version 7.6.0
3465
* For projects with JDK 8 version 7.5 should be installed.
3566
* See https://groups.google.com/g/testng-users/c/BAFB1vk-kok?pli=1 for more details.
3667
*/
37-
38-
fun testNgNewLibraryDescriptor(versionInProject: String?) =
39-
ExternalLibraryDescriptor("org.testng", "testng", "7.6.0", null, versionInProject ?: "7.6.0")
68+
fun testNgNewLibraryDescriptor(versionInProject: Version?): ExternalLibraryDescriptor {
69+
val preferredVersion = if (versionInProject?.hasNumericOrEmptyPatch() == true) versionInProject?.plainText else "7.6.0"
70+
return ExternalLibraryDescriptor(
71+
"org.testng", "testng",
72+
"7.6.0", null, preferredVersion
73+
)
74+
}
4075

4176
fun testNgOldLibraryDescriptor() =
42-
ExternalLibraryDescriptor("org.testng", "testng", "7.5", "7.5", "7.5")
77+
ExternalLibraryDescriptor(
78+
"org.testng", "testng",
79+
"7.5", "7.5", "7.5"
80+
)

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -964,7 +964,9 @@ class GenerateTestsDialogWindow(val model: GenerateTestsModel) : DialogWrapper(m
964964
?: error("Trying to install Spring test framework, but Spring framework is not found in module ${model.srcModule.name}")
965965
val frameworkTestVersionInProject = frameworkTestLibrary?.libraryName?.parseVersion()
966966

967-
if (frameworkTestVersionInProject == null || frameworkTestVersionInProject < frameworkVersionInProject) {
967+
if (frameworkTestVersionInProject == null ||
968+
!frameworkTestVersionInProject.isCompatibleWith(frameworkVersionInProject)
969+
) {
968970
val libraryDescriptor = when (framework) {
969971
SpringBoot -> springBootTestLibraryDescriptor(frameworkVersionInProject)
970972
SpringBeans -> springTestLibraryDescriptor(frameworkVersionInProject)

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

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -25,20 +25,6 @@ fun Module.allLibraries(): List<LibraryOrderEntry> {
2525
val moduleRootManager = ModuleRootManager.getInstance(this)
2626
return allLibraries(moduleRootManager.orderEntries())
2727
}
28-
29-
fun String.parseVersion(): String? {
30-
val lastSemicolon = lastIndexOf(':')
31-
val version = substring(lastSemicolon + 1)
32-
33-
if (lastSemicolon == -1 ||
34-
version.split('.').any { it.toIntOrNull() == null }
35-
) {
36-
return null
37-
}
38-
39-
return version
40-
}
41-
4228
fun List<LibraryOrderEntry>.matchesAnyOf(patterns: List<Regex>): LibraryOrderEntry? =
4329
firstOrNull { entry ->
4430
patterns.any { pattern ->
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package org.utbot.intellij.plugin.ui.utils
2+
3+
/**
4+
* Describes the version of a library.
5+
* Contains three standard components: major, minor and patch.
6+
*
7+
* Major and minor components are always numbers, while patch
8+
* may contain a number with some postfix like -RELEASE.
9+
*
10+
* Sometimes patch is empty, e.g. for TestNg 7.5 version.
11+
*
12+
* @param plainText is optional and represents whole version as text.
13+
*/
14+
data class Version(
15+
val major: Int,
16+
val minor: Int,
17+
val patch: String,
18+
val plainText: String? = null,
19+
) {
20+
fun isCompatibleWith(another: Version): Boolean {
21+
//Non-numeric versions can't be compared to each other, so we cannot be sure that current is compatible
22+
if (!hasNumericOrEmptyPatch() || !hasNumericOrEmptyPatch()) {
23+
return false
24+
}
25+
26+
return major > another.major ||
27+
major == another.major && minor > another.minor ||
28+
major == another.major && minor == another.minor &&
29+
(another.patch.isEmpty() || patch.isNotEmpty() && patch.toInt() >= another.patch.toInt())
30+
}
31+
32+
fun hasNumericOrEmptyPatch(): Boolean = patch.toIntOrNull() != null
33+
}
34+
35+
fun String.parseVersion(): Version? {
36+
val lastSemicolon = lastIndexOf(':')
37+
val versionText = substring(lastSemicolon + 1)
38+
val versionComponents = versionText.split('.')
39+
40+
// Components must be: major, minor and (optional) patch
41+
if (versionComponents.size < 2 || versionComponents.size > 3) {
42+
return null
43+
}
44+
45+
val major = versionComponents[0].toIntOrNull() ?: return null
46+
val minor = versionComponents[1].toIntOrNull() ?: return null
47+
val patch = if (versionComponents.size == 3) versionComponents[2] else ""
48+
49+
return Version(major, minor, patch, versionText)
50+
}

0 commit comments

Comments
 (0)