Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 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
2 changes: 1 addition & 1 deletion utbot-gradle/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ pluginBundle {
gradlePlugin {
plugins {
sarifReportPlugin {
version = '1.0.0-alpha-9' // last published version
version = '1.0.0-alpha' // last published version
id = 'org.utbot.gradle.plugin'
displayName = 'UnitTestBot gradle plugin'
description = 'The gradle plugin for generating tests and creating SARIF reports based on UnitTestBot'
Expand Down
19 changes: 19 additions & 0 deletions utbot-gradle/docs/utbot-gradle.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,25 @@ __Kotlin DSL:__
}
```

Also, you can configure the task using `-P<parameterName>=<value>` syntax.

For example,
```Kotlin
generateTestsAndSarifReport
-PtargetClasses='[com.abc.Main, com.qwerty.Util]'
-PprojectRoot='C:/.../SomeDirectory'
-PgeneratedTestsRelativeRoot='build/generated/test'
-PsarifReportsRelativeRoot='build/generated/sarif'
-PtestFramework=junit5
-PmockFramework=mockito
-PgenerationTimeout=60000
-PcodegenLanguage=java
-PmockStrategy='other-packages'
-PstaticsMocking='mock-statics'
-PforceStaticMocking=force
-PclassesToMockAlways='[org.slf4j.Logger, java.util.Random]'
```

**Note:** All configuration fields have default values, so there is no need to configure the plugin if you don't want to.

**Description of fields:**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ open class GenerateTestsAndSarifReportTask @Inject constructor(
*/
@TaskAction
fun generateTestsAndSarifReport() {
// the user specifies the parameters using "-Pname=value"
sarifProperties.taskParameters = project.gradle.startParameter.projectProperties
val rootGradleProject = try {
GradleProjectWrapper(project, sarifProperties)
} catch (t: Throwable) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,70 +15,106 @@ import java.io.File
/**
* Provides all [SarifGradleExtension] fields in a convenient form:
* Defines default values and a transform function for these fields.
* Takes the fields from the [taskParameters] if they are available there,
* otherwise takes them from the [extension].
*/
class SarifGradleExtensionProvider(
private val project: Project,
private val extension: SarifGradleExtension
private val extension: SarifGradleExtension,
var taskParameters: Map<String, String> = mapOf()
) : SarifExtensionProvider {

override val targetClasses: List<String>
get() = extension.targetClasses
.getOrElse(listOf())
get() = taskParameters["targetClasses"]?.transformKeywordAll()?.parseToList()
?: extension.targetClasses.orNull
?: listOf()

override val projectRoot: File
get() = extension.projectRoot.orNull
get() = (taskParameters["projectRoot"] ?: extension.projectRoot.orNull)
?.toPath()?.toFile()
?: project.projectDir

override val generatedTestsRelativeRoot: String
get() = extension.generatedTestsRelativeRoot.orNull
get() = taskParameters["generatedTestsRelativeRoot"]
?: extension.generatedTestsRelativeRoot.orNull
?: "build/generated/test"

override val sarifReportsRelativeRoot: String
get() = extension.sarifReportsRelativeRoot.orNull
get() = taskParameters["sarifReportsRelativeRoot"]
?: extension.sarifReportsRelativeRoot.orNull
?: "build/generated/sarif"

// We don't get this field from `taskParameters` because marking the directory
// as a test source root is possible while the gradle project is reloading,
// but `taskParameters` become available only when the user runs the gradle task
// `generateTestsAndSarifReport` (that is, after a reloading).
override val markGeneratedTestsDirectoryAsTestSourcesRoot: Boolean
get() = extension.markGeneratedTestsDirectoryAsTestSourcesRoot.orNull
?: true

override val testFramework: TestFramework
get() = extension.testFramework
.map(::testFrameworkParse)
.getOrElse(TestFramework.defaultItem)
get() = (taskParameters["testFramework"] ?: extension.testFramework.orNull)
?.let(::testFrameworkParse)
?: TestFramework.defaultItem

override val mockFramework: MockFramework
get() = extension.mockFramework
.map(::mockFrameworkParse)
.getOrElse(MockFramework.defaultItem)
get() = (taskParameters["mockFramework"] ?: extension.mockFramework.orNull)
?.let(::mockFrameworkParse)
?: MockFramework.defaultItem

override val generationTimeout: Long
get() = extension.generationTimeout
.map(::generationTimeoutParse)
.getOrElse(60 * 1000L) // 60 seconds
get() = (taskParameters["generationTimeout"]?.toLongOrNull() ?: extension.generationTimeout.orNull)
?.let(::generationTimeoutParse)
?: (60 * 1000L) // 60 seconds

override val codegenLanguage: CodegenLanguage
get() = extension.codegenLanguage
.map(::codegenLanguageParse)
.getOrElse(CodegenLanguage.defaultItem)
get() = (taskParameters["codegenLanguage"] ?: extension.codegenLanguage.orNull)
?.let(::codegenLanguageParse)
?: CodegenLanguage.defaultItem

override val mockStrategy: MockStrategyApi
get() = extension.mockStrategy
.map(::mockStrategyParse)
.getOrElse(MockStrategyApi.defaultItem)
get() = (taskParameters["mockStrategy"] ?: extension.mockStrategy.orNull)
?.let(::mockStrategyParse)
?: MockStrategyApi.defaultItem

override val staticsMocking: StaticsMocking
get() = extension.staticsMocking
.map(::staticsMockingParse)
.getOrElse(StaticsMocking.defaultItem)
get() = (taskParameters["staticsMocking"] ?: extension.staticsMocking.orNull)
?.let(::staticsMockingParse)
?: StaticsMocking.defaultItem

override val forceStaticMocking: ForceStaticMocking
get() = extension.forceStaticMocking
.map(::forceStaticMockingParse)
.getOrElse(ForceStaticMocking.defaultItem)
get() = (taskParameters["forceStaticMocking"] ?: extension.forceStaticMocking.orNull)
?.let(::forceStaticMockingParse)
?: ForceStaticMocking.defaultItem

override val classesToMockAlways: Set<ClassId>
get() = classesToMockAlwaysParse(
extension.classesToMockAlways.getOrElse(listOf())
specifiedClasses = taskParameters["classesToMockAlways"]?.parseToList()
?: extension.classesToMockAlways.orNull
?: listOf()
)

/**
* SARIF report file containing static analysis information about all [targetClasses].
*/
val mergedSarifReportFileName: String?
get() = taskParameters["mergedSarifReportFileName"]

// internal

/**
* Keyword "all" is the same as "[]" for [targetClasses], but more user-friendly.
*/
private fun String.transformKeywordAll(): String =
if (this == "all") "[]" else this

/**
* Example: "[A, B, C]" -> ["A", "B", "C"].
*/
private fun String.parseToList() =
this.removePrefix("[")
.removeSuffix("]")
.split(",")
.map { it.trim() }
.filter { it != "" }
}
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,12 @@ class GradleProjectWrapper(
}

/**
* SARIF report file containing results from all others reports from the [project].
* SARIF report file containing results from all other reports from the [project].
*/
val sarifReportFile: File by lazy {
Paths.get(
generatedSarifDirectory.path,
"${project.name}Report.sarif"
sarifProperties.mergedSarifReportFileName ?: "${project.name}Report.sarif"
).toFile().apply {
createNewFileWithParentDirectories()
}
Expand Down
Loading