diff --git a/utbot-cli/src/main/kotlin/org/utbot/cli/GenerateTestsCommand.kt b/utbot-cli/src/main/kotlin/org/utbot/cli/GenerateTestsCommand.kt index bed9c79779..9c88095e31 100644 --- a/utbot-cli/src/main/kotlin/org/utbot/cli/GenerateTestsCommand.kt +++ b/utbot-cli/src/main/kotlin/org/utbot/cli/GenerateTestsCommand.kt @@ -21,6 +21,9 @@ import java.nio.file.Paths import java.time.temporal.ChronoUnit import kotlin.reflect.KClass import mu.KotlinLogging +import org.utbot.common.filterWhen +import org.utbot.framework.UtSettings +import org.utbot.framework.util.isKnownSyntheticMethod private val logger = KotlinLogging.logger {} @@ -92,6 +95,7 @@ class GenerateTestsCommand : val classUnderTest: KClass<*> = loadClassBySpecifiedFqn(targetClassFqn) val targetMethods = classUnderTest.targetMethods() + .filterWhen(UtSettings.skipTestGenerationForSyntheticMethods) { !isKnownSyntheticMethod(it) } initializeEngine(workingDirectory) if (targetMethods.isEmpty()) { diff --git a/utbot-core/src/main/kotlin/org/utbot/common/FilterWhen.kt b/utbot-core/src/main/kotlin/org/utbot/common/FilterWhen.kt new file mode 100644 index 0000000000..e85e1afa78 --- /dev/null +++ b/utbot-core/src/main/kotlin/org/utbot/common/FilterWhen.kt @@ -0,0 +1,21 @@ +package org.utbot.common + +/** + * If [condition] is true, returns a list containing only elements matching [predicate]. + * Otherwise, returns list with all elements of collection + */ +inline fun Iterable.filterWhen(condition: Boolean, predicate: (T) -> Boolean): List = + if (condition) + this.filter(predicate) + else + this.toList() + +/** + * If [condition] is true, returns a sequence containing only elements matching [predicate]. + * Otherwise, leaves sequence unchanged + */ +fun Sequence.filterWhen(condition: Boolean, predicate: (T) -> Boolean): Sequence = + if (condition) + this.filter(predicate) + else + this \ No newline at end of file diff --git a/utbot-framework-api/src/main/kotlin/org/utbot/framework/UtSettings.kt b/utbot-framework-api/src/main/kotlin/org/utbot/framework/UtSettings.kt index 230ebb24d1..0b428a7065 100644 --- a/utbot-framework-api/src/main/kotlin/org/utbot/framework/UtSettings.kt +++ b/utbot-framework-api/src/main/kotlin/org/utbot/framework/UtSettings.kt @@ -375,6 +375,11 @@ object UtSettings { */ var singleSelector by getBooleanProperty(true) + /** + * Flag that indicates whether tests for synthetic methods (values, valueOf in enums) should be generated, or not + */ + var skipTestGenerationForSyntheticMethods by getBooleanProperty(true) + override fun toString(): String = properties .entries diff --git a/utbot-framework/src/main/kotlin/org/utbot/framework/util/SyntheticMethods.kt b/utbot-framework/src/main/kotlin/org/utbot/framework/util/SyntheticMethods.kt new file mode 100644 index 0000000000..bbb7f50eaf --- /dev/null +++ b/utbot-framework/src/main/kotlin/org/utbot/framework/util/SyntheticMethods.kt @@ -0,0 +1,19 @@ +package org.utbot.framework.util + +import org.utbot.engine.displayName +import org.utbot.framework.plugin.api.UtMethod + +fun isKnownSyntheticMethod(method: UtMethod<*>): Boolean = + if (method.clazz.java.isEnum) + method.displayName.substringBefore('(') in KnownSyntheticMethodNames.enumSyntheticMethodNames + else + false + +/** + * Contains names of methods that are always autogenerated and thus it is unlikely that + * one would want to generate tests for them. + */ +private object KnownSyntheticMethodNames { + /** List with names of enum methods that are autogenerated */ + val enumSyntheticMethodNames = listOf("values", "valueOf") +} \ No newline at end of file diff --git a/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/generator/UtTestsDialogProcessor.kt b/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/generator/UtTestsDialogProcessor.kt index ab357d3aef..2555db36bb 100644 --- a/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/generator/UtTestsDialogProcessor.kt +++ b/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/generator/UtTestsDialogProcessor.kt @@ -15,6 +15,7 @@ import com.intellij.openapi.project.Project import com.intellij.openapi.roots.OrderEnumerator import com.intellij.openapi.util.text.StringUtil import com.intellij.psi.PsiClass +import com.intellij.psi.SyntheticElement import com.intellij.refactoring.util.classMembers.MemberInfo import com.intellij.testIntegration.TestIntegrationUtils import com.intellij.util.concurrency.AppExecutorUtil @@ -45,6 +46,7 @@ import java.net.URLClassLoader import java.nio.file.Path import java.nio.file.Paths import java.util.concurrent.TimeUnit +import org.utbot.common.filterWhen import org.utbot.engine.util.mockListeners.ForceStaticMockListener import kotlin.reflect.KClass import kotlin.reflect.full.functions @@ -134,6 +136,9 @@ object UtTestsDialogProcessor { val clazz = classLoader.loadClass(srcClass.qualifiedName).kotlin val srcMethods = model.selectedMethods?.toList() ?: TestIntegrationUtils.extractClassMethods(srcClass, false) + .filterWhen(UtSettings.skipTestGenerationForSyntheticMethods) { + it.member !is SyntheticElement + } findMethodsInClassMatchingSelected(clazz, srcMethods) }.executeSynchronously() 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 90cda951e1..7204290ee7 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 @@ -39,6 +39,7 @@ import com.intellij.openapi.wm.ToolWindowManager import com.intellij.psi.PsiClass import com.intellij.psi.PsiManager import com.intellij.psi.PsiMethod +import com.intellij.psi.SyntheticElement import com.intellij.refactoring.PackageWrapper import com.intellij.refactoring.ui.MemberSelectionTable import com.intellij.refactoring.ui.PackageNameReferenceEditorCombo @@ -125,6 +126,7 @@ import javax.swing.JComponent import javax.swing.JList import javax.swing.JPanel import kotlin.streams.toList +import org.utbot.common.filterWhen private const val RECENTS_KEY = "org.utbot.recents" @@ -358,6 +360,7 @@ class GenerateTestsDialogWindow(val model: GenerateTestsModel) : DialogWrapper(m val items: List if (srcClasses.size == 1) { items = TestIntegrationUtils.extractClassMethods(srcClasses.single(), false) + .filterWhen(UtSettings.skipTestGenerationForSyntheticMethods) { it.member !is SyntheticElement } updateMethodsTable(items) } else { items = srcClasses.map { MemberInfo(it) } diff --git a/utbot-junit-contest/src/main/kotlin/org/utbot/contest/Contest.kt b/utbot-junit-contest/src/main/kotlin/org/utbot/contest/Contest.kt index 3075ca38f7..0b6f1e4729 100644 --- a/utbot-junit-contest/src/main/kotlin/org/utbot/contest/Contest.kt +++ b/utbot-junit-contest/src/main/kotlin/org/utbot/contest/Contest.kt @@ -61,6 +61,8 @@ import kotlin.reflect.jvm.isAccessible import kotlin.reflect.jvm.javaConstructor import kotlin.reflect.jvm.javaGetter import kotlin.reflect.jvm.javaMethod +import org.utbot.common.filterWhen +import org.utbot.framework.util.isKnownSyntheticMethod internal const val junitVersion = 4 private val logger = KotlinLogging.logger {} @@ -442,12 +444,12 @@ private fun prepareClass(kotlinClass: KClass<*>, methodNameFilter: String?): Lis //join .union(kotlin2javaCtors) - val classFilteredMethods = methodsToGenerate + val classFilteredMethods = methodsToGenerate.asSequence() .map { UtMethod(it.first, kotlinClass) } .filter { methodNameFilter?.equals(it.callable.name) ?: true } - .filterNot { - it.isConstructor && (it.clazz.isAbstract || it.clazz.java.isEnum) - } + .filterNot { it.isConstructor && (it.clazz.isAbstract || it.clazz.java.isEnum) } + .filterWhen(UtSettings.skipTestGenerationForSyntheticMethods) { !isKnownSyntheticMethod(it) } + .toList() return if (kotlinClass.nestedClasses.isEmpty()) { classFilteredMethods