Skip to content

Commit 475918f

Browse files
committed
Store version of util class in a comment and use it to decide whether to overwrite an existing util class or not
1 parent 98f75fb commit 475918f

File tree

4 files changed

+57
-21
lines changed

4 files changed

+57
-21
lines changed

utbot-framework/src/main/kotlin/org/utbot/framework/codegen/model/CodeGenerator.kt

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ import org.utbot.framework.plugin.api.ExecutableId
2323
import org.utbot.framework.plugin.api.MockFramework
2424
import org.utbot.framework.plugin.api.UtMethodTestSet
2525
import org.utbot.framework.codegen.model.constructor.TestClassModel
26+
import org.utbot.framework.codegen.model.tree.CgComment
27+
import org.utbot.framework.codegen.model.tree.CgSingleLineComment
2628

2729
class CodeGenerator(
2830
private val classUnderTest: ClassId,
@@ -145,6 +147,21 @@ sealed class UtilClassKind(
145147
private val priority: Int
146148
) : Comparable<UtilClassKind> {
147149

150+
/**
151+
* The version of util class being generated.
152+
* For more details see [UtilClassFileMethodProvider.UTIL_CLASS_VERSION].
153+
*/
154+
val utilClassVersion: String
155+
get() = UtilClassFileMethodProvider.UTIL_CLASS_VERSION
156+
157+
/**
158+
* The comment specifying the version of util class being generated.
159+
*
160+
* @see UtilClassFileMethodProvider.UTIL_CLASS_VERSION
161+
*/
162+
val utilClassVersionComment: CgComment
163+
get() = CgSingleLineComment("$UTIL_CLASS_VERSION_COMMENT_PREFIX${utilClassVersion}")
164+
148165
/**
149166
* A kind of regular UtUtils class. "Regular" here means that this class does not use a mock framework.
150167
*/
@@ -171,6 +188,14 @@ sealed class UtilClassKind(
171188
}
172189

173190
companion object {
191+
192+
/**
193+
* Class UtUtils will contain a comment specifying the version of this util class
194+
* (if we ever change util methods, then util class will be different, hence the update of its version).
195+
* This is a prefix that will go before the version in the comment.
196+
*/
197+
const val UTIL_CLASS_VERSION_COMMENT_PREFIX = "UtUtils class version: "
198+
174199
/**
175200
* Check if an util class is required, and if so, what kind.
176201
* @return `null` if [CgContext.utilMethodProvider] is not [UtilClassFileMethodProvider],

utbot-framework/src/main/kotlin/org/utbot/framework/codegen/model/constructor/builtin/UtilMethodBuiltins.kt

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package org.utbot.framework.codegen.model.constructor.builtin
33
import org.utbot.framework.codegen.MockitoStaticMocking
44
import org.utbot.framework.codegen.model.constructor.util.utilMethodId
55
import org.utbot.framework.codegen.model.tree.CgClassId
6+
import org.utbot.framework.codegen.model.visitor.utilMethodTextById
67
import org.utbot.framework.plugin.api.BuiltinClassId
78
import org.utbot.framework.plugin.api.ClassId
89
import org.utbot.framework.plugin.api.MethodId
@@ -155,7 +156,21 @@ internal abstract class UtilMethodProvider(val utilClassId: ClassId) {
155156
*
156157
* Content of this util class may be different (due to mocks in deepEquals), but the methods (and their ids) are the same.
157158
*/
158-
internal object UtilClassFileMethodProvider : UtilMethodProvider(utUtilsClassId)
159+
internal object UtilClassFileMethodProvider : UtilMethodProvider(utUtilsClassId) {
160+
/**
161+
* This property contains the current version of util class.
162+
* This version will be written to the util class file inside a comment.
163+
*
164+
* Whenever we want to create an util class, we first check if there is an already existing one.
165+
* If there is, then we decide whether we need to overwrite it or not. One of the factors here
166+
* is the version of this existing class. If the version of existing class is older than the one
167+
* that is currently stored in [UtilClassFileMethodProvider.UTIL_CLASS_VERSION], then we need to
168+
* overwrite an util class, because it might have been changed in the new version.
169+
*
170+
* **IMPORTANT** if you make any changes to util methods (see [utilMethodTextById]), do not forget to update this version.
171+
*/
172+
const val UTIL_CLASS_VERSION = "1.0"
173+
}
159174

160175
internal class TestClassUtilMethodProvider(testClassId: ClassId) : UtilMethodProvider(testClassId)
161176

utbot-framework/src/main/kotlin/org/utbot/framework/codegen/model/constructor/tree/CgUtilClassConstructor.kt

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import org.utbot.framework.codegen.model.CodeGenerator
44
import org.utbot.framework.codegen.model.UtilClassKind
55
import org.utbot.framework.codegen.model.constructor.builtin.utUtilsClassId
66
import org.utbot.framework.codegen.model.tree.CgRegularClassFile
7-
import org.utbot.framework.codegen.model.tree.CgSingleLineComment
87
import org.utbot.framework.codegen.model.tree.CgUtilMethod
98
import org.utbot.framework.codegen.model.tree.buildRegularClass
109
import org.utbot.framework.codegen.model.tree.buildRegularClassBody
@@ -23,8 +22,7 @@ internal object CgUtilClassConstructor {
2322
declaredClass = buildRegularClass {
2423
id = utUtilsClassId
2524
body = buildRegularClassBody {
26-
// TODO: get actual UTBot version and use it instead of the hardcoded one
27-
content += CgSingleLineComment("UTBot version: 1.0-SNAPSHOT")
25+
content += utilClassKind.utilClassVersionComment
2826
content += utilMethodProvider.utilMethodIds.map { CgUtilMethod(it) }
2927
}
3028
}

utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/generator/CodeGenerationController.kt

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import com.intellij.psi.PsiMethod
3333
import com.intellij.psi.codeStyle.CodeStyleManager
3434
import com.intellij.psi.codeStyle.JavaCodeStyleManager
3535
import com.intellij.psi.search.GlobalSearchScopesCore
36+
import com.intellij.psi.util.childrenOfType
3637
import com.intellij.refactoring.util.classMembers.MemberInfo
3738
import com.intellij.testIntegration.TestIntegrationUtils
3839
import com.intellij.util.IncorrectOperationException
@@ -50,7 +51,6 @@ import org.jetbrains.kotlin.psi.KtPsiFactory
5051
import org.jetbrains.kotlin.psi.psiUtil.endOffset
5152
import org.jetbrains.kotlin.psi.psiUtil.startOffset
5253
import org.jetbrains.kotlin.scripting.resolve.classId
53-
import org.jetbrains.plugins.groovy.lang.psi.util.childrenOfType
5454
import org.utbot.common.HTML_LINE_SEPARATOR
5555
import org.utbot.common.PathUtil.toHtmlLinkTag
5656
import org.utbot.common.appendHtmlLine
@@ -153,11 +153,12 @@ object CodeGenerationController {
153153

154154
run(EDT_LATER) {
155155
waitForCountDown(latch, timeout = 100, timeUnit = TimeUnit.MILLISECONDS) {
156+
val mockFrameworkUsed = utilClassListener.mockFrameworkUsed
156157
val utilClassKind = utilClassListener.requiredUtilClassKind
157158
?: return@waitForCountDown // no util class needed
158159

159160
val existingUtilClass = model.codegenLanguage.getUtilClassOrNull(model.project, model.testModule)
160-
if (shouldCreateOrUpdateUtilClass(existingUtilClass, utilClassListener)) {
161+
if (shouldCreateOrUpdateUtilClass(existingUtilClass, mockFrameworkUsed, utilClassKind)) {
161162
createOrUpdateUtilClass(
162163
testDirectory = baseTestDirectory,
163164
utilClassKind = utilClassKind,
@@ -195,13 +196,12 @@ object CodeGenerationController {
195196
}
196197
}
197198

198-
private fun shouldCreateOrUpdateUtilClass(existingUtilClass: PsiFile?, utilClassListener: UtilClassListener): Boolean {
199-
val existingUtilClassVersion = existingUtilClass?.utilClassVersionOrNull
200-
// TODO: here should be the current version of UTBot
201-
val newUtilClassVersion = "1.0-SNAPSHOT"
202-
val versionIsUpdated = existingUtilClassVersion != newUtilClassVersion
203-
204-
val mockFrameworkNotUsed = !utilClassListener.mockFrameworkUsed
199+
private fun shouldCreateOrUpdateUtilClass(
200+
existingUtilClass: PsiFile?,
201+
mockFrameworkUsed: Boolean,
202+
requiredUtilClassKind: UtilClassKind
203+
): Boolean {
204+
val mockFrameworkNotUsed = !mockFrameworkUsed
205205

206206
val utilClassExists = existingUtilClass != null
207207

@@ -210,6 +210,10 @@ object CodeGenerationController {
210210
return true
211211
}
212212

213+
val existingUtilClassVersion = existingUtilClass?.utilClassVersionOrNull
214+
val newUtilClassVersion = requiredUtilClassKind.utilClassVersion
215+
val versionIsUpdated = existingUtilClassVersion != newUtilClassVersion
216+
213217
if (versionIsUpdated) {
214218
// If an existing util class is out of date,
215219
// then we must overwrite it with a newer version.
@@ -345,17 +349,11 @@ object CodeGenerationController {
345349

346350
utilClass.childrenOfType<PsiComment>()
347351
.map { comment -> comment.text }
348-
.firstOrNull { text -> UTBOT_VERSION_PREFIX in text }
349-
?.substringAfterLast(UTBOT_VERSION_PREFIX)
352+
.firstOrNull { text -> UtilClassKind.UTIL_CLASS_VERSION_COMMENT_PREFIX in text }
353+
?.substringAfterLast(UtilClassKind.UTIL_CLASS_VERSION_COMMENT_PREFIX)
350354
?.trim()
351355
}
352356

353-
/**
354-
* Util class must have a comment that specifies the version of UTBot it was generated with.
355-
* This prefix is the start of this comment. The version of UTBot goes after it in the comment.
356-
*/
357-
private const val UTBOT_VERSION_PREFIX = "UTBot version:"
358-
359357
/**
360358
* @param srcClass class under test
361359
* @return name of the package of a given [srcClass].

0 commit comments

Comments
 (0)