Skip to content

Little improvements related to TODOs in code of CLion plugin #351

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jul 26, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,34 @@ import org.utbot.cpp.clion.plugin.client.requests.FunctionReturnTypeRequest
import org.utbot.cpp.clion.plugin.client.requests.PredicateRequest
import org.utbot.cpp.clion.plugin.utils.activeProject
import org.utbot.cpp.clion.plugin.utils.client
import org.utbot.cpp.clion.plugin.utils.notifyError
import testsgen.Util.ValidationType
import java.awt.Dimension
import java.awt.event.KeyAdapter
import java.awt.event.KeyEvent
import java.math.BigInteger
import java.util.function.Supplier

/**
* Action to take needed information from user and trigger generation for predicate.
*
* Predicate request generates tests that satisfy some condition (predicate) for
* function return type. E.g. tests where return value (function return type is int)
* is smaller than 10.
*
* To assemble predicate request we need to know function return type.
* For that we send request to server @see [FunctionReturnTypeRequest].
* Depending on return type we ask user what comparison operator to use.
* For example, if return type is bool, we suggest == or !=, if it is
* not bool, then available operators are: ==, <=, >=, <, >. @see [chooseComparisonOperator]
* Then we ask user for a value to compare with, @see [chooseReturnValue].
* Then we assemble the predicate request and launch its execution @see [sendPredicateToServer].
*
* For asking comparison operator and return value we use popups.
*/
class GenerateForPredicateAction : BaseGenerateTestsAction() {

override fun actionPerformed(e: AnActionEvent) {
// when we gathered all needed information for predicate request, assemble it and execute it.
fun sendPredicateToServer(validationType: ValidationType, valueToCompare: String, comparisonOperator: String) =
PredicateRequest(
getPredicateGrpcRequest(e, comparisonOperator, validationType, valueToCompare),
Expand All @@ -33,7 +51,7 @@ class GenerateForPredicateAction : BaseGenerateTestsAction() {
e.client.executeRequest(this)
}

//TODO: this code requires some comments
// ask for comparison operator to use in predicate
fun chooseComparisonOperator(
validationType: ValidationType,
proceedWithComparisonOperator: (comparisonOperator: String) -> Unit,
Expand All @@ -44,6 +62,20 @@ class GenerateForPredicateAction : BaseGenerateTestsAction() {
proceedWithComparisonOperator("==")
return
}
ValidationType.UNSUPPORTED -> {
notifyError(
"Unsupported return type for \'Generate Tests With Prompted Result\' feature: \n" +
"supported types are integers, booleans, characters, floats and strings"
)
return
}
ValidationType.UNRECOGNIZED -> {
notifyError(
"Could not recognise return type for 'Generate Tests With Prompted Result' feature: \n" +
"supported types are integers, booleans, characters, floats and strings"
)
return
}
else -> {
val operators = listOf("==", "<=", "=>", "<", ">")
createListPopup("Select predicate", operators) { comparisonOperator ->
Expand All @@ -53,6 +85,7 @@ class GenerateForPredicateAction : BaseGenerateTestsAction() {
}
}

// ask for return value of the function to compare with
fun chooseReturnValue(
validationType: ValidationType,
proceedWithValueToCompare: (valueToCompare: String) -> Unit,
Expand All @@ -63,14 +96,17 @@ class GenerateForPredicateAction : BaseGenerateTestsAction() {
}
popup.showInBestPositionFor(e.dataContext)
}

//ask server for return type
FunctionReturnTypeRequest(
getFunctionGrpcRequest(e),
e.activeProject(),
) { functionReturnType ->
val validationType = functionReturnType.validationType
// then ask for comparison operator to use from user
chooseComparisonOperator(validationType) { comparisonOperator ->
// then ask for return value to compare with from user
chooseReturnValue(validationType) { valueToCompare ->
// when we have all needed information, assemble and execute
sendPredicateToServer(validationType, valueToCompare, comparisonOperator)
}
}
Expand All @@ -95,6 +131,7 @@ class GenerateForPredicateAction : BaseGenerateTestsAction() {
private fun createTrueFalsePopup(onChoose: (String) -> Unit) =
createListPopup("Select bool value", listOf("true", "false")) { onChoose(it) }

//creates popup with input textfield, used for asking return value
private fun createTextFieldPopup(type: ValidationType, onChoose: (String) -> Unit): JBPopup {
val textField = ExtendableTextField()
textField.minimumSize = Dimension(100, textField.width)
Expand Down Expand Up @@ -142,7 +179,7 @@ class GenerateForPredicateAction : BaseGenerateTestsAction() {
}

companion object {
//TODO: why don't we have DOUBLE and BYTE here?
//Note: server does not support some types like byte or boolean
val defaultReturnValues = mapOf(
ValidationType.INT8_T to "0",
ValidationType.INT16_T to "0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,8 @@ class Client(

fun configureProject() {
CheckProjectConfigurationRequest(
getProjectConfigGrpcRequest(project, Testgen.ConfigMode.CHECK),
project,
getProjectConfigGrpcRequest(project, Testgen.ConfigMode.CHECK)
).also {
executeRequest(it)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import org.utbot.cpp.clion.plugin.utils.refreshAndFindIOFile
import testsgen.Testgen
import testsgen.Util
import java.nio.file.Path
import java.nio.file.Paths

class TestsStreamHandler(
project: Project,
Expand All @@ -36,10 +35,10 @@ class TestsStreamHandler(

private fun handleSourceCode(sources: List<Util.SourceCode>, isStubs: Boolean = false) {
sources.forEach { sourceCode ->
val filePath: String = sourceCode.filePath.convertFromRemotePathIfNeeded(project)
val filePath: Path = sourceCode.filePath.convertFromRemotePathIfNeeded(project)

if (!isStubs)
myGeneratedTestFilesLocalFS.add(Paths.get(filePath))
myGeneratedTestFilesLocalFS.add(filePath)

if (sourceCode.code.isNotEmpty()) {
project.logger.trace { "Creating generated test file: $filePath." }
Expand All @@ -50,7 +49,7 @@ class TestsStreamHandler(
}

var infoMessage = "Generated " + if (isStubs) "stub" else "test" + " file"
if (isGeneratedFileTestSourceFile(filePath))
if (isGeneratedFileTestSourceFile(filePath.toString()))
infoMessage += " with ${sourceCode.regressionMethodsNumber} tests in regression suite" +
" and ${sourceCode.errorMethodsNumber} tests in error suite"
project.logger.info { "$infoMessage: $filePath" }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,16 @@ import testsgen.Testgen
import java.io.File
import java.nio.charset.StandardCharsets
import java.nio.file.Files
import java.nio.file.Paths
import java.nio.file.Path

/**
* This class is used to convert from our representation of coverage to IntelliJ's [ProjectData]
*/
class UTBotCoverageRunner : CoverageRunner() {
private val log = Logger.getInstance(this::class.java)
private fun getLineCount(filePath: String): Int {
private fun getLineCount(filePath: Path): Int {
var lineCount: Int
Files.lines(Paths.get(filePath), StandardCharsets.UTF_8).use { stream -> lineCount = stream.count().toInt() }
Files.lines(filePath, StandardCharsets.UTF_8).use { stream -> lineCount = stream.count().toInt() }
return lineCount
}

Expand All @@ -40,12 +40,12 @@ class UTBotCoverageRunner : CoverageRunner() {
if (filePathFromServer.isNotEmpty()) {
isAnyCoverage = true
val localFilePath = filePathFromServer.convertFromRemotePathIfNeeded(baseCoverageSuite.project)
if (!Paths.get(localFilePath).exists()) {
if (!localFilePath.exists()) {
log.warn("Skipping $localFilePath in coverage processing as it does not exist!")
continue
}
val lines = arrayOfNulls<LineData>(getLineCount(localFilePath))
val classData = projectData.getOrCreateClassData(provideQualifiedNameForFile(localFilePath))
val classData = projectData.getOrCreateClassData(provideQualifiedNameForFile(localFilePath.toAbsolutePath().toString()))
fun processRanges(rangesList: List<Testgen.SourceLine?>, status: Byte) {
rangesList.filterNotNull().forEach {
val lineData = LineData(it.line + 1, null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@ package org.utbot.cpp.clion.plugin.grpc

import testsgen.Testgen

//TODO: hardcoding the version is a bad practice, determine it somehow
fun getVersionGrpcRequest(): Testgen.VersionInfo = Testgen.VersionInfo.newBuilder().setVersion("2022.7").build()
//TODO: when plugin is ready for release, take version from publish github action.
fun getVersionGrpcRequest(): Testgen.VersionInfo = Testgen.VersionInfo.newBuilder().setVersion("0.0.1").build()
Original file line number Diff line number Diff line change
Expand Up @@ -212,11 +212,15 @@ class UTBotAllSettings(val project: Project) {

val convertedProjectPath: String get() = projectPath.convertToRemotePathIfNeeded(project)

//TODO: it seems to be a kind of boolshit to me
private val isLocalHost: Boolean
get() = serverName == "localhost" || serverName == "127.0.0.01"

//TODO: it is unclear, requires a comment
get() = serverName == "localhost" || serverName == "127.0.0.1"

/**
* If this property returns true, plugin must convert path sent and returned from server.
* @see [String.convertToRemotePathIfNeeded], [String.convertFromRemotePathIfNeeded]
*
* If we are on Windows, this is not a server, so it is always a remote scenario.
*/
val isRemoteScenario: Boolean
get() = !(remotePath == projectPath && isLocalHost) || isWindows

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
package org.utbot.cpp.clion.plugin.ui.sourceFoldersView

import com.intellij.psi.PsiDirectory
import org.utbot.cpp.clion.plugin.utils.addDirectoriesRecursive
import org.utbot.cpp.clion.plugin.utils.removeDirectoriesRecursive
import org.utbot.cpp.clion.plugin.utils.visitAllDirectories

interface DirectoriesStatusUpdater {
fun toggle()
Expand All @@ -11,6 +10,30 @@ interface DirectoriesStatusUpdater {
}

abstract class BaseUpdater(val selectedDirectories: List<PsiDirectory>) : DirectoriesStatusUpdater {
// merge directories' paths from this set, with all the directories from passed list including nested directories
private fun Set<String>.addDirectoriesRecursive(dirsToAdd: List<PsiDirectory>): Set<String> {
val newSourceFolders = this.toMutableSet()
dirsToAdd.forEach { dir ->
newSourceFolders.add(dir.virtualFile.path)
dir.virtualFile.toNioPath().visitAllDirectories {
newSourceFolders.add(it.toString())
}
}
return newSourceFolders
}

// subtract from this set of directories the passed directories including nested directories
private fun Set<String>.removeDirectoriesRecursive(dirsToRemove: List<PsiDirectory>): Set<String> {
val newSourceFolders = this.toMutableSet()
dirsToRemove.forEach { dir ->
newSourceFolders.add(dir.virtualFile.path)
dir.virtualFile.toNioPath().visitAllDirectories {
newSourceFolders.remove(it.toString())
}
}
return newSourceFolders
}

abstract fun getCurrentMarkedDirs(): Set<String>
abstract fun setCurrentMarkedDirs(value: Set<String>)
override fun markAsSource() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ import testsgen.Testgen

data class UTBotTarget(val path: String, val name: String, val description: String) {
constructor(target: Testgen.ProjectTarget, project: Project) : this(
if (target.name == autoTarget.name) target.path else target.path.convertFromRemotePathIfNeeded(project),
if (target.name == autoTarget.name) target.path else target.path.convertFromRemotePathIfNeeded(project)
.toAbsolutePath().toString(),
target.name,
target.description
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ class TestsResultsStorage(val project: Project) {
it.file?.toNioPath()
}
for (testResult in storage.values) {
if (Paths.get(testResult.testFilePath.convertFromRemotePathIfNeeded(project)) in currentlyOpenedFilePaths) {
if (testResult.testFilePath.convertFromRemotePathIfNeeded(project) in currentlyOpenedFilePaths) {
return true
}
}
Expand Down
Loading