mirror of
https://github.com/jlengrand/detekt.git
synced 2026-03-10 08:11:23 +00:00
Refactor config printer to improve testability (#4580)
Co-authored-by: Markus Schwarz <post@markus-schwarz.net>
This commit is contained in:
@@ -14,8 +14,7 @@ internal fun YamlNode.printRuleSetPage(ruleSetPage: RuleSetPage) {
|
||||
printRuleSet(ruleSetPage.ruleSet, ruleSetPage.rules)
|
||||
}
|
||||
|
||||
@Suppress("ComplexMethod") // preserving the declarative structure while building the dsl
|
||||
private fun YamlNode.printRuleSet(ruleSet: RuleSetProvider, rules: List<Rule>) {
|
||||
internal fun YamlNode.printRuleSet(ruleSet: RuleSetProvider, rules: List<Rule>) {
|
||||
node(ruleSet.name) {
|
||||
keyValue { Config.ACTIVE_KEY to "${ruleSet.defaultActivationStatus.active}" }
|
||||
val ruleSetExclusion = exclusions.singleOrNull { ruleSet.name in it.ruleSets }
|
||||
@@ -23,26 +22,29 @@ private fun YamlNode.printRuleSet(ruleSet: RuleSetProvider, rules: List<Rule>) {
|
||||
keyValue { Config.EXCLUDES_KEY to ruleSetExclusion.pattern }
|
||||
}
|
||||
|
||||
ruleSet.configuration.forEach { printConfiguration(it) }
|
||||
ruleSet.configuration.forEach(::printConfiguration)
|
||||
|
||||
rules.forEach(::printRule)
|
||||
|
||||
rules.forEach { rule ->
|
||||
node(rule.name) {
|
||||
keyValue { Config.ACTIVE_KEY to "${rule.defaultActivationStatus.active}" }
|
||||
if (rule.autoCorrect) {
|
||||
keyValue { Config.AUTO_CORRECT_KEY to "true" }
|
||||
}
|
||||
val ruleExclusion = exclusions.singleOrNull { it.isExcluded(rule) }
|
||||
if (ruleExclusion != null) {
|
||||
keyValue { Config.EXCLUDES_KEY to ruleExclusion.pattern }
|
||||
}
|
||||
rule.configuration.forEach { printConfiguration(it) }
|
||||
}
|
||||
}
|
||||
emptyLine()
|
||||
}
|
||||
}
|
||||
|
||||
private fun YamlNode.printConfiguration(configuration: Configuration) {
|
||||
internal fun YamlNode.printRule(rule: Rule) {
|
||||
node(rule.name) {
|
||||
keyValue { Config.ACTIVE_KEY to "${rule.defaultActivationStatus.active}" }
|
||||
if (rule.autoCorrect) {
|
||||
keyValue { Config.AUTO_CORRECT_KEY to "true" }
|
||||
}
|
||||
val ruleExclusion = exclusions.singleOrNull { it.isExcluded(rule) }
|
||||
if (ruleExclusion != null) {
|
||||
keyValue { Config.EXCLUDES_KEY to ruleExclusion.pattern }
|
||||
}
|
||||
rule.configuration.forEach(::printConfiguration)
|
||||
}
|
||||
}
|
||||
|
||||
internal fun YamlNode.printConfiguration(configuration: Configuration) {
|
||||
if (configuration.isDeprecated()) return
|
||||
|
||||
if (configuration.isDefaultValueNonEmptyList()) {
|
||||
|
||||
@@ -0,0 +1,205 @@
|
||||
package io.gitlab.arturbosch.detekt.generator.printer.defaultconfig
|
||||
|
||||
import io.gitlab.arturbosch.detekt.api.Config
|
||||
import io.gitlab.arturbosch.detekt.generator.collection.Active
|
||||
import io.gitlab.arturbosch.detekt.generator.collection.Configuration
|
||||
import io.gitlab.arturbosch.detekt.generator.collection.DefaultValue
|
||||
import io.gitlab.arturbosch.detekt.generator.collection.Inactive
|
||||
import io.gitlab.arturbosch.detekt.generator.collection.Rule
|
||||
import io.gitlab.arturbosch.detekt.generator.collection.RuleSetProvider
|
||||
import io.gitlab.arturbosch.detekt.generator.out.yaml
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.junit.jupiter.api.Nested
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.params.ParameterizedTest
|
||||
import org.junit.jupiter.params.provider.ValueSource
|
||||
|
||||
internal class RuleSetConfigPrinterTest {
|
||||
private val ruleSetProviderTemplate = RuleSetProvider(
|
||||
name = "rulesetName",
|
||||
description = "description",
|
||||
defaultActivationStatus = Inactive
|
||||
)
|
||||
private val ruleTemplate = Rule(
|
||||
name = "ruleName",
|
||||
description = "",
|
||||
nonCompliantCodeExample = "",
|
||||
compliantCodeExample = "",
|
||||
defaultActivationStatus = Inactive,
|
||||
severity = "",
|
||||
debt = "",
|
||||
aliases = null,
|
||||
parent = ""
|
||||
)
|
||||
|
||||
private val configurationTemplate = Configuration(
|
||||
name = "name",
|
||||
description = "description",
|
||||
defaultValue = DefaultValue.of(1),
|
||||
defaultAndroidValue = null,
|
||||
deprecated = null,
|
||||
)
|
||||
|
||||
@Nested
|
||||
inner class PrintRuleSet {
|
||||
|
||||
@Test
|
||||
fun `starts with name on top level`() {
|
||||
val ruleset = ruleSetProviderTemplate.copy(name = "rule-set-name")
|
||||
val actual = yaml { printRuleSet(ruleset, emptyList()) }
|
||||
assertThat(actual).startsWith("rule-set-name:\n")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `includes all rules`() {
|
||||
val rules = listOf(ruleTemplate.copy(name = "RuleA"), ruleTemplate.copy(name = "RuleB"))
|
||||
val actual = yaml { printRuleSet(ruleSetProviderTemplate, rules) }
|
||||
assertThat(actual.lines()).contains(" RuleA:", " RuleB:")
|
||||
}
|
||||
|
||||
@Nested
|
||||
inner class ActivationStatus {
|
||||
|
||||
@Test
|
||||
fun `has active property`() {
|
||||
val ruleset = ruleSetProviderTemplate.copy(defaultActivationStatus = Active("1.0.0"))
|
||||
val actual = yaml { printRuleSet(ruleset, emptyList()) }
|
||||
assertThat(actual.lines()).contains(" active: true")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `has active property if inactive`() {
|
||||
val ruleset = ruleSetProviderTemplate.copy(defaultActivationStatus = Inactive)
|
||||
val actual = yaml { printRuleSet(ruleset, emptyList()) }
|
||||
assertThat(actual.lines()).contains(" active: false")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
inner class PrintRule {
|
||||
|
||||
@Test
|
||||
fun `starts with rule name`() {
|
||||
val rule = ruleTemplate.copy(name = "RuleA")
|
||||
val actual = yaml { printRule(rule) }
|
||||
assertThat(actual).startsWith("RuleA:\n")
|
||||
}
|
||||
|
||||
@Nested
|
||||
inner class ActivationStatus {
|
||||
|
||||
@Test
|
||||
fun `has active property`() {
|
||||
val rule = ruleTemplate.copy(defaultActivationStatus = Active("1.0.0"))
|
||||
val actual = yaml { printRule(rule) }
|
||||
assertThat(actual.lines()).contains(" active: true")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `has active property if inactive`() {
|
||||
val rule = ruleTemplate.copy(defaultActivationStatus = Inactive)
|
||||
val actual = yaml { printRule(rule) }
|
||||
assertThat(actual.lines()).contains(" active: false")
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
inner class AutoCorrect {
|
||||
|
||||
@Test
|
||||
fun `has auto correct property`() {
|
||||
val rule = ruleTemplate.copy(autoCorrect = true)
|
||||
val actual = yaml { printRule(rule) }
|
||||
assertThat(actual.lines()).contains(" autoCorrect: true")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `omits auto correct property if false`() {
|
||||
val rule = ruleTemplate.copy(autoCorrect = false)
|
||||
val actual = yaml { printRule(rule) }
|
||||
assertThat(actual).doesNotContain(Config.AUTO_CORRECT_KEY)
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
inner class Exclusion {
|
||||
|
||||
@Test
|
||||
fun `rule is excluded`() {
|
||||
val anExclusion = exclusions[0]
|
||||
val anExcludedRuleName = anExclusion.rules.first()
|
||||
val rule = ruleTemplate.copy(name = anExcludedRuleName)
|
||||
val actual = yaml { printRule(rule) }
|
||||
assertThat(actual.lines()).contains(" excludes: ${anExclusion.pattern}")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `omits excludes property if rule is not excluded in any exclusion`() {
|
||||
val rule = ruleTemplate.copy(name = "ARuleNameThatIsNotExcluded")
|
||||
val actual = yaml { printRule(rule) }
|
||||
assertThat(actual).doesNotContain(Config.EXCLUDES_KEY)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
inner class PrintConfiguration {
|
||||
|
||||
@Test
|
||||
fun `ignore deprecated`() {
|
||||
val given = configurationTemplate.copy(deprecated = "use something else")
|
||||
val actual = yaml { printConfiguration(given) }
|
||||
assertThat(actual).isEmpty()
|
||||
}
|
||||
|
||||
@Nested
|
||||
inner class DefaultValues {
|
||||
|
||||
@Test
|
||||
fun `int default value`() {
|
||||
val given = configurationTemplate.copy(defaultValue = DefaultValue.of(99))
|
||||
val actual = yaml { printConfiguration(given) }
|
||||
assertThat(actual).isEqualTo("name: 99")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `boolean default value`() {
|
||||
val given = configurationTemplate.copy(defaultValue = DefaultValue.of(false))
|
||||
val actual = yaml { printConfiguration(given) }
|
||||
assertThat(actual).isEqualTo("name: false")
|
||||
}
|
||||
|
||||
@ValueSource(
|
||||
strings = [
|
||||
"", " ", "a", "a b", "a\$b"
|
||||
]
|
||||
)
|
||||
@ParameterizedTest
|
||||
fun `string default value is quoted`(value: String) {
|
||||
val given = configurationTemplate.copy(defaultValue = DefaultValue.of(value))
|
||||
val actual = yaml { printConfiguration(given) }
|
||||
assertThat(actual).isEqualTo("name: '$value'")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `empty list default value uses array syntax`() {
|
||||
val given = configurationTemplate.copy(defaultValue = DefaultValue.of(emptyList()))
|
||||
val actual = yaml { printConfiguration(given) }
|
||||
assertThat(actual).isEqualTo("name: []")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `string list default value`() {
|
||||
val given = configurationTemplate.copy(defaultValue = DefaultValue.of(listOf("a", "b", "c")))
|
||||
val actual = yaml { printConfiguration(given) }
|
||||
val expected = """name:
|
||||
| - 'a'
|
||||
| - 'b'
|
||||
| - 'c'
|
||||
""".trimMargin()
|
||||
assertThat(actual).isEqualTo(expected)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user