diff --git a/ktlint-core/src/main/kotlin/com/pinterest/ktlint/core/Rule.kt b/ktlint-core/src/main/kotlin/com/pinterest/ktlint/core/Rule.kt index 58d0242553..b8b9c98911 100644 --- a/ktlint-core/src/main/kotlin/com/pinterest/ktlint/core/Rule.kt +++ b/ktlint-core/src/main/kotlin/com/pinterest/ktlint/core/Rule.kt @@ -9,7 +9,7 @@ import org.jetbrains.kotlin.com.intellij.lang.ASTNode * Implementation **doesn't** have to be thread-safe or stateless * (provided [RuleSetProvider] creates a new instance on each `get()` call). * - * @param id must be unique within the ruleset + * @param id: For non-standard rules, it is expected that this id consist of the ruleSetId and ruleId, e.g. "some-rule-set-id:some-rule-id" * @param visitorModifiers: set of modifiers of the visitor. Preferably a rule has no modifiers at all, meaning that it * is completely independent of all other rules. * @@ -20,7 +20,7 @@ abstract class Rule( public val visitorModifiers: Set = emptySet() ) { init { - IdNamingPolicy.enforceNaming(id) + IdNamingPolicy.enforceRuleIdNaming(id) } /** diff --git a/ktlint-core/src/main/kotlin/com/pinterest/ktlint/core/RuleSet.kt b/ktlint-core/src/main/kotlin/com/pinterest/ktlint/core/RuleSet.kt index 168ac3f121..bee3736f1c 100644 --- a/ktlint-core/src/main/kotlin/com/pinterest/ktlint/core/RuleSet.kt +++ b/ktlint-core/src/main/kotlin/com/pinterest/ktlint/core/RuleSet.kt @@ -12,7 +12,7 @@ open class RuleSet( ) : Iterable { init { - IdNamingPolicy.enforceNaming(id) + IdNamingPolicy.enforceRuleSetIdNaming(id) require(rules.isNotEmpty()) { "At least one rule must be provided" } } diff --git a/ktlint-core/src/main/kotlin/com/pinterest/ktlint/core/VisitorProvider.kt b/ktlint-core/src/main/kotlin/com/pinterest/ktlint/core/VisitorProvider.kt index a9dfdc2d29..5102096f48 100644 --- a/ktlint-core/src/main/kotlin/com/pinterest/ktlint/core/VisitorProvider.kt +++ b/ktlint-core/src/main/kotlin/com/pinterest/ktlint/core/VisitorProvider.kt @@ -6,11 +6,10 @@ import org.jetbrains.kotlin.com.intellij.lang.ASTNode public class VisitorProvider( ruleSets: Iterable, - private val debug: Boolean, - isUnitTestContext: Boolean = false + private val debug: Boolean ) { private val ruleReferences: List = - VisitorProviderInitializer(ruleSets, debug, isUnitTestContext).getRulePreferences() + VisitorProviderInitializer(ruleSets, debug).getRulePreferences() internal fun visitor( ruleSets: Iterable, @@ -27,7 +26,7 @@ public class VisitorProvider( .rules .filter { rule -> toQualifiedRuleId(ruleSet.id, rule.id) in enabledQualifiedRuleIds } .filter { rule -> isNotDisabled(rootNode, toQualifiedRuleId(ruleSet.id, rule.id)) } - .map { rule -> "${ruleSet.id}:${rule.id}" to rule } + .map { rule -> "${toQualifiedRuleId(ruleSet.id, rule.id)}" to rule } }.toMap() if (debug && enabledRules.isEmpty()) { println( @@ -130,7 +129,11 @@ private fun toQualifiedRuleId( ruleSetId: String, ruleId: String ) = - "$ruleSetId:$ruleId" + if (ruleId.startsWith("$ruleSetId:")) { + ruleId + } else { + "$ruleSetId:$ruleId" + } private fun String.toQualifiedRuleId() = if (contains(":")) { @@ -141,8 +144,7 @@ private fun String.toQualifiedRuleId() = private class VisitorProviderInitializer( val ruleSets: Iterable, - val debug: Boolean, - val isUnitTestContext: Boolean = false + val debug: Boolean ) { fun getRulePreferences(): List { return ruleSets @@ -275,13 +277,7 @@ private class VisitorProviderInitializer( while (ruleReferencesIterator.hasNext()) { val ruleReference = ruleReferencesIterator.next() - if (ruleReference.runAfterRule != null && isUnitTestContext) { - // When running unit tests,the RunAfterRule annotation is ignored. The code provided in the unit should - // be formatted as if the rule on which it depends was already applied. In this way the unit test can be - // restricted to one single rule instead of having to take into account all other rules on which it - // might depend. - newRuleReferences.add(ruleReference.copy(runAfterRule = null)) - } else if (ruleReference.runAfterRule != null && newRuleReferences.none { rule -> rule.runsAfter(ruleReference) }) { + if (ruleReference.runAfterRule != null && newRuleReferences.none { rule -> rule.runsAfter(ruleReference) }) { // The RunAfterRule refers to a rule which is not yet added to the new list of rule references. if (this.none { it.runsAfter(ruleReference) }) { // The RunAfterRule refers to a rule which is not loaded at all. diff --git a/ktlint-core/src/main/kotlin/com/pinterest/ktlint/core/internal/IdNamingPolicy.kt b/ktlint-core/src/main/kotlin/com/pinterest/ktlint/core/internal/IdNamingPolicy.kt index a687e35fcf..27c6a5f0e4 100644 --- a/ktlint-core/src/main/kotlin/com/pinterest/ktlint/core/internal/IdNamingPolicy.kt +++ b/ktlint-core/src/main/kotlin/com/pinterest/ktlint/core/internal/IdNamingPolicy.kt @@ -4,14 +4,23 @@ package com.pinterest.ktlint.core.internal * Provides policy to have consistent and restricted `id` field naming style. */ internal object IdNamingPolicy { - private const val ID_REGEX = "[a-z]+([-][a-z]+)*" - private val idRegex = ID_REGEX.toRegex() + private const val SIMPLE_ID_REGEX = "[a-z]+([-][a-z]+)*" + private val ruleIdRegex = "($SIMPLE_ID_REGEX:)?($SIMPLE_ID_REGEX)".toRegex() + private val ruleSetIdRegex = "($SIMPLE_ID_REGEX)".toRegex() /** - * Checks provided [id] is valid. + * Checks provided [ruleId] is valid. * - * Will throw [IllegalArgumentException] on invalid [id] name. + * Will throw [IllegalArgumentException] on invalid [ruleId] name. */ - internal fun enforceNaming(id: String) = - require(id.matches(idRegex)) { "id $id must match $ID_REGEX" } + internal fun enforceRuleIdNaming(ruleId: String) = + require(ruleId.matches(ruleIdRegex)) { "Rule id '$ruleId' must match '${ruleIdRegex.pattern}'" } + + /** + * Checks provided [ruleSetId] is valid. + * + * Will throw [IllegalArgumentException] on invalid [ruleSetId] name. + */ + internal fun enforceRuleSetIdNaming(ruleSetId: String) = + require(ruleSetId.matches(ruleSetIdRegex)) { "RuleSet id '$ruleSetId' must match '${ruleSetIdRegex.pattern}'" } } diff --git a/ktlint-core/src/test/kotlin/com/pinterest/ktlint/core/VisitorProviderTest.kt b/ktlint-core/src/test/kotlin/com/pinterest/ktlint/core/VisitorProviderTest.kt index 8fb609083c..7f049d1d27 100644 --- a/ktlint-core/src/test/kotlin/com/pinterest/ktlint/core/VisitorProviderTest.kt +++ b/ktlint-core/src/test/kotlin/com/pinterest/ktlint/core/VisitorProviderTest.kt @@ -580,10 +580,7 @@ class VisitorProviderTest { return VisitorProvider( ruleSets = ruleSetList, // Enable debug mode as it is helpful when a test fails - debug = true, - // Although this is a unit test, the isUnitTestContext is disabled by default so that rules marked with - // RunAfterRule can be tested as well. - isUnitTestContext = isUnitTestContext ?: false + debug = true ).run { var visits: MutableList? = null visitor(ruleSetList, SOME_ROOT_AST_NODE, concurrent ?: false) diff --git a/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/AnnotationRule.kt b/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/AnnotationRule.kt index 5458260ab9..aea0a98473 100644 --- a/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/AnnotationRule.kt +++ b/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/AnnotationRule.kt @@ -34,7 +34,7 @@ import org.jetbrains.kotlin.psi.psiUtil.nextLeaf * * @see [AnnotationSpacingRule] for white space rules. Moved since */ -class AnnotationRule : Rule("annotation") { +class AnnotationRule : Rule("$experimentalRulesetId:annotation") { companion object { const val multipleAnnotationsOnSameLineAsAnnotatedConstructErrorMessage = diff --git a/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/AnnotationSpacingRule.kt b/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/AnnotationSpacingRule.kt index c7a988540c..dc0e96302d 100644 --- a/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/AnnotationSpacingRule.kt +++ b/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/AnnotationSpacingRule.kt @@ -24,7 +24,7 @@ import org.jetbrains.kotlin.psi.psiUtil.leaves * * https://kotlinlang.org/docs/reference/coding-conventions.html#annotation-formatting */ -class AnnotationSpacingRule : Rule("annotation-spacing") { +class AnnotationSpacingRule : Rule("$experimentalRulesetId:annotation-spacing") { companion object { const val ERROR_MESSAGE = "Annotations should occur immediately before the annotated construct" diff --git a/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/ArgumentListWrappingRule.kt b/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/ArgumentListWrappingRule.kt index 554774be0d..48c52adbf8 100644 --- a/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/ArgumentListWrappingRule.kt +++ b/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/ArgumentListWrappingRule.kt @@ -41,7 +41,7 @@ import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType */ @OptIn(FeatureInAlphaState::class) class ArgumentListWrappingRule : - Rule("argument-list-wrapping"), + Rule("$experimentalRulesetId:argument-list-wrapping"), UsesEditorConfigProperties { private var editorConfigIndent = IndentConfig.DEFAULT_INDENT_CONFIG private var maxLineLength = -1 diff --git a/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/BlockCommentInitialStarAlignmentRule.kt b/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/BlockCommentInitialStarAlignmentRule.kt index 18321fd11d..c6bed583b7 100644 --- a/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/BlockCommentInitialStarAlignmentRule.kt +++ b/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/BlockCommentInitialStarAlignmentRule.kt @@ -11,7 +11,7 @@ import org.jetbrains.kotlin.com.intellij.psi.impl.source.tree.LeafElement */ class BlockCommentInitialStarAlignmentRule : Rule( - "block-comment-initial-star-alignment", + "$experimentalRulesetId:block-comment-initial-star-alignment", visitorModifiers = setOf( // The block comment is a node which can contain multiple lines. The indent of the second and later line // should be determined based on the indent of the block comment node. This indent is determined by the diff --git a/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/CommentWrappingRule.kt b/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/CommentWrappingRule.kt index 2f3f822431..dfa80efd97 100644 --- a/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/CommentWrappingRule.kt +++ b/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/CommentWrappingRule.kt @@ -22,7 +22,7 @@ import org.jetbrains.kotlin.com.intellij.psi.impl.source.tree.PsiCommentImpl */ @OptIn(FeatureInAlphaState::class) public class CommentWrappingRule : - Rule("comment-wrapping"), + Rule("$experimentalRulesetId:comment-wrapping"), UsesEditorConfigProperties { override val editorConfigProperties: List> = listOf( diff --git a/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/DiscouragedCommentLocationRule.kt b/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/DiscouragedCommentLocationRule.kt index 6979a11a3d..3e17a4e685 100644 --- a/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/DiscouragedCommentLocationRule.kt +++ b/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/DiscouragedCommentLocationRule.kt @@ -27,7 +27,7 @@ import org.jetbrains.kotlin.com.intellij.lang.ASTNode * foo(t: T) = "some-result" * ``` */ -public class DiscouragedCommentLocationRule : Rule("discouraged-comment-location") { +public class DiscouragedCommentLocationRule : Rule("$experimentalRulesetId:discouraged-comment-location") { override fun visit( node: ASTNode, autoCorrect: Boolean, diff --git a/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/EnumEntryNameCaseRule.kt b/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/EnumEntryNameCaseRule.kt index 14f1f28009..abb65991fb 100644 --- a/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/EnumEntryNameCaseRule.kt +++ b/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/EnumEntryNameCaseRule.kt @@ -5,8 +5,7 @@ import org.jetbrains.kotlin.com.intellij.lang.ASTNode import org.jetbrains.kotlin.com.intellij.psi.impl.source.tree.CompositeElement import org.jetbrains.kotlin.psi.KtEnumEntry -public class EnumEntryNameCaseRule : Rule("enum-entry-name-case") { - +public class EnumEntryNameCaseRule : Rule("$experimentalRulesetId:enum-entry-name-case") { internal companion object { val regex = Regex("[A-Z]([A-Za-z\\d]*|[A-Z_\\d]*)") } diff --git a/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/ExperimentalRuleSetProvider.kt b/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/ExperimentalRuleSetProvider.kt index af15095de0..523ac73b74 100644 --- a/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/ExperimentalRuleSetProvider.kt +++ b/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/ExperimentalRuleSetProvider.kt @@ -4,10 +4,11 @@ import com.pinterest.ktlint.core.RuleSet import com.pinterest.ktlint.core.RuleSetProvider import com.pinterest.ktlint.ruleset.experimental.trailingcomma.TrailingCommaRule -public class ExperimentalRuleSetProvider : RuleSetProvider { +public const val experimentalRulesetId = "experimental" +public class ExperimentalRuleSetProvider : RuleSetProvider { override fun get(): RuleSet = RuleSet( - "experimental", + experimentalRulesetId, AnnotationRule(), ArgumentListWrappingRule(), MultiLineIfElseRule(), diff --git a/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/FunKeywordSpacingRule.kt b/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/FunKeywordSpacingRule.kt index 638a1befc2..c62ba33fa3 100644 --- a/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/FunKeywordSpacingRule.kt +++ b/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/FunKeywordSpacingRule.kt @@ -10,7 +10,7 @@ import org.jetbrains.kotlin.com.intellij.psi.impl.source.tree.LeafPsiElement /** * Lints and formats the spacing after the fun keyword */ -public class FunKeywordSpacingRule : Rule("fun-keyword-spacing") { +public class FunKeywordSpacingRule : Rule("$experimentalRulesetId:fun-keyword-spacing") { override fun visit( node: ASTNode, autoCorrect: Boolean, diff --git a/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/FunctionReturnTypeSpacingRule.kt b/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/FunctionReturnTypeSpacingRule.kt index c98d45d615..2518f99a53 100644 --- a/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/FunctionReturnTypeSpacingRule.kt +++ b/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/FunctionReturnTypeSpacingRule.kt @@ -10,7 +10,7 @@ import com.pinterest.ktlint.core.ast.upsertWhitespaceAfterMe import org.jetbrains.kotlin.com.intellij.lang.ASTNode import org.jetbrains.kotlin.com.intellij.psi.impl.source.tree.LeafElement -public class FunctionReturnTypeSpacingRule : Rule("function-return-type-spacing") { +public class FunctionReturnTypeSpacingRule : Rule("$experimentalRulesetId:function-return-type-spacing") { override fun visit( node: ASTNode, autoCorrect: Boolean, diff --git a/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/FunctionStartOfBodySpacingRule.kt b/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/FunctionStartOfBodySpacingRule.kt index f826b35ebf..afd8871eab 100644 --- a/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/FunctionStartOfBodySpacingRule.kt +++ b/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/FunctionStartOfBodySpacingRule.kt @@ -14,7 +14,7 @@ import org.jetbrains.kotlin.com.intellij.psi.impl.source.tree.LeafPsiElement /** * Lints and formats the spacing after the fun keyword */ -public class FunctionStartOfBodySpacingRule : Rule("function-start-of-body-spacing") { +public class FunctionStartOfBodySpacingRule : Rule("$experimentalRulesetId:function-start-of-body-spacing") { override fun visit( node: ASTNode, autoCorrect: Boolean, diff --git a/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/FunctionTypeReferenceSpacingRule.kt b/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/FunctionTypeReferenceSpacingRule.kt index ce7bacb00b..6aa8656b8d 100644 --- a/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/FunctionTypeReferenceSpacingRule.kt +++ b/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/FunctionTypeReferenceSpacingRule.kt @@ -9,7 +9,7 @@ import com.pinterest.ktlint.core.ast.ElementType.WHITE_SPACE import com.pinterest.ktlint.core.ast.nextSibling import org.jetbrains.kotlin.com.intellij.lang.ASTNode -public class FunctionTypeReferenceSpacingRule : Rule("function-type-reference-spacing") { +public class FunctionTypeReferenceSpacingRule : Rule("$experimentalRulesetId:function-type-reference-spacing") { override fun visit( node: ASTNode, autoCorrect: Boolean, diff --git a/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/KdocWrappingRule.kt b/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/KdocWrappingRule.kt index 480390dc80..6d429594d2 100644 --- a/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/KdocWrappingRule.kt +++ b/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/KdocWrappingRule.kt @@ -21,7 +21,7 @@ import org.jetbrains.kotlin.com.intellij.psi.impl.source.tree.LeafPsiElement */ @OptIn(FeatureInAlphaState::class) public class KdocWrappingRule : - Rule("kdoc-wrapping"), + Rule("$experimentalRulesetId:kdoc-wrapping"), UsesEditorConfigProperties { override val editorConfigProperties: List> = listOf( diff --git a/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/ModifierListSpacingRule.kt b/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/ModifierListSpacingRule.kt index 4ffc5624fa..cedf3d124d 100644 --- a/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/ModifierListSpacingRule.kt +++ b/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/ModifierListSpacingRule.kt @@ -17,7 +17,7 @@ import org.jetbrains.kotlin.com.intellij.psi.impl.source.tree.LeafPsiElement /** * Lint and format the spacing between the modifiers in and after the last modifier in a modifier list. */ -public class ModifierListSpacingRule : Rule("modifier-list-spacing") { +public class ModifierListSpacingRule : Rule("$experimentalRulesetId:modifier-list-spacing") { override fun visit( node: ASTNode, autoCorrect: Boolean, diff --git a/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/MultiLineIfElseRule.kt b/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/MultiLineIfElseRule.kt index 9e11d82dd1..3dd50d83dc 100644 --- a/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/MultiLineIfElseRule.kt +++ b/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/MultiLineIfElseRule.kt @@ -22,7 +22,7 @@ import org.jetbrains.kotlin.psi.psiUtil.leaves * * TODO: if, for, when branch, do, while */ -class MultiLineIfElseRule : Rule("multiline-if-else") { +class MultiLineIfElseRule : Rule("$experimentalRulesetId:multiline-if-else") { override fun visit( node: ASTNode, diff --git a/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/NoEmptyFirstLineInMethodBlockRule.kt b/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/NoEmptyFirstLineInMethodBlockRule.kt index 345980399f..0f24ef368f 100644 --- a/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/NoEmptyFirstLineInMethodBlockRule.kt +++ b/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/NoEmptyFirstLineInMethodBlockRule.kt @@ -10,8 +10,7 @@ import org.jetbrains.kotlin.com.intellij.lang.ASTNode import org.jetbrains.kotlin.com.intellij.psi.PsiWhiteSpace import org.jetbrains.kotlin.com.intellij.psi.impl.source.tree.LeafPsiElement -class NoEmptyFirstLineInMethodBlockRule : Rule("no-empty-first-line-in-method-block") { - +class NoEmptyFirstLineInMethodBlockRule : Rule("$experimentalRulesetId:no-empty-first-line-in-method-block") { override fun visit( node: ASTNode, autoCorrect: Boolean, diff --git a/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/NullableTypeSpacingRule.kt b/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/NullableTypeSpacingRule.kt index 2ed271aabe..2a460d649d 100644 --- a/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/NullableTypeSpacingRule.kt +++ b/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/NullableTypeSpacingRule.kt @@ -7,7 +7,7 @@ import com.pinterest.ktlint.core.ast.prevLeaf import org.jetbrains.kotlin.com.intellij.lang.ASTNode import org.jetbrains.kotlin.com.intellij.psi.impl.source.tree.LeafPsiElement -public class NullableTypeSpacingRule : Rule("nullable-type-spacing") { +public class NullableTypeSpacingRule : Rule("$experimentalRulesetId:nullable-type-spacing") { override fun visit( node: ASTNode, autoCorrect: Boolean, diff --git a/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/PackageNameRule.kt b/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/PackageNameRule.kt index 6d85bc87c8..74ad5efbae 100644 --- a/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/PackageNameRule.kt +++ b/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/PackageNameRule.kt @@ -5,8 +5,7 @@ import com.pinterest.ktlint.core.ast.ElementType.PACKAGE_DIRECTIVE import org.jetbrains.kotlin.com.intellij.lang.ASTNode import org.jetbrains.kotlin.psi.KtPackageDirective -class PackageNameRule : Rule("package-name") { - +class PackageNameRule : Rule("$experimentalRulesetId:package-name") { override fun visit( node: ASTNode, autoCorrect: Boolean, diff --git a/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/ParameterListSpacingRule.kt b/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/ParameterListSpacingRule.kt index 72caf43100..fbe41916cf 100644 --- a/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/ParameterListSpacingRule.kt +++ b/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/ParameterListSpacingRule.kt @@ -24,7 +24,7 @@ import org.jetbrains.kotlin.com.intellij.psi.impl.source.tree.LeafPsiElement * comma's and colons. However, it does have a more complete view on the higher concept of the parameter-list without * interfering of the parameter-list-wrapping rule. */ -public class ParameterListSpacingRule : Rule("parameter-list-spacing") { +public class ParameterListSpacingRule : Rule("$experimentalRulesetId:parameter-list-spacing") { override fun visit( node: ASTNode, autoCorrect: Boolean, diff --git a/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/SpacingAroundAngleBracketsRule.kt b/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/SpacingAroundAngleBracketsRule.kt index 6278285d19..1a86564d9d 100644 --- a/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/SpacingAroundAngleBracketsRule.kt +++ b/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/SpacingAroundAngleBracketsRule.kt @@ -13,7 +13,7 @@ import com.pinterest.ktlint.core.ast.prevLeaf import org.jetbrains.kotlin.com.intellij.lang.ASTNode import org.jetbrains.kotlin.com.intellij.psi.impl.source.tree.LeafElement -class SpacingAroundAngleBracketsRule : Rule("spacing-around-angle-brackets") { +class SpacingAroundAngleBracketsRule : Rule("$experimentalRulesetId:spacing-around-angle-brackets") { private fun String.trimBeforeLastLine() = this.substring(this.lastIndexOf('\n')) override fun visit( diff --git a/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/SpacingAroundDoubleColonRule.kt b/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/SpacingAroundDoubleColonRule.kt index 9f1fa1ef12..a96dbf9d8f 100644 --- a/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/SpacingAroundDoubleColonRule.kt +++ b/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/SpacingAroundDoubleColonRule.kt @@ -11,8 +11,7 @@ import org.jetbrains.kotlin.com.intellij.lang.ASTNode import org.jetbrains.kotlin.com.intellij.psi.PsiWhiteSpace import org.jetbrains.kotlin.com.intellij.psi.impl.source.tree.LeafPsiElement -class SpacingAroundDoubleColonRule : Rule("double-colon-spacing") { - +class SpacingAroundDoubleColonRule : Rule("$experimentalRulesetId:double-colon-spacing") { override fun visit( node: ASTNode, autoCorrect: Boolean, diff --git a/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/SpacingAroundUnaryOperatorRule.kt b/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/SpacingAroundUnaryOperatorRule.kt index 0c4195e959..dbd11654d9 100644 --- a/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/SpacingAroundUnaryOperatorRule.kt +++ b/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/SpacingAroundUnaryOperatorRule.kt @@ -12,8 +12,7 @@ import org.jetbrains.kotlin.com.intellij.lang.ASTNode * * @see [Kotlin Style Guide](https://kotlinlang.org/docs/reference/coding-conventions.html#horizontal-whitespace) */ -class SpacingAroundUnaryOperatorRule : Rule("unary-op-spacing") { - +class SpacingAroundUnaryOperatorRule : Rule("$experimentalRulesetId:unary-op-spacing") { override fun visit( node: ASTNode, autoCorrect: Boolean, diff --git a/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/SpacingBetweenDeclarationsWithAnnotationsRule.kt b/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/SpacingBetweenDeclarationsWithAnnotationsRule.kt index cc903893da..ebd2c6c7b8 100644 --- a/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/SpacingBetweenDeclarationsWithAnnotationsRule.kt +++ b/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/SpacingBetweenDeclarationsWithAnnotationsRule.kt @@ -17,8 +17,7 @@ import org.jetbrains.kotlin.psi.psiUtil.prevLeafs /** * @see https://youtrack.jetbrains.com/issue/KT-35106 */ -class SpacingBetweenDeclarationsWithAnnotationsRule : Rule("spacing-between-declarations-with-annotations") { - +class SpacingBetweenDeclarationsWithAnnotationsRule : Rule("$experimentalRulesetId:spacing-between-declarations-with-annotations") { override fun visit( node: ASTNode, autoCorrect: Boolean, diff --git a/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/SpacingBetweenDeclarationsWithCommentsRule.kt b/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/SpacingBetweenDeclarationsWithCommentsRule.kt index 0513223141..cf8e60df18 100644 --- a/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/SpacingBetweenDeclarationsWithCommentsRule.kt +++ b/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/SpacingBetweenDeclarationsWithCommentsRule.kt @@ -16,8 +16,7 @@ import org.jetbrains.kotlin.psi.psiUtil.startOffset /** * @see https://youtrack.jetbrains.com/issue/KT-35088 */ -class SpacingBetweenDeclarationsWithCommentsRule : Rule("spacing-between-declarations-with-comments") { - +class SpacingBetweenDeclarationsWithCommentsRule : Rule("$experimentalRulesetId:spacing-between-declarations-with-comments") { override fun visit( node: ASTNode, autoCorrect: Boolean, diff --git a/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/SpacingBetweenFunctionNameAndOpeningParenthesisRule.kt b/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/SpacingBetweenFunctionNameAndOpeningParenthesisRule.kt index ab5dbe71b8..6802b88072 100644 --- a/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/SpacingBetweenFunctionNameAndOpeningParenthesisRule.kt +++ b/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/SpacingBetweenFunctionNameAndOpeningParenthesisRule.kt @@ -6,7 +6,7 @@ import com.pinterest.ktlint.core.ast.ElementType.WHITE_SPACE import com.pinterest.ktlint.core.ast.nextSibling import org.jetbrains.kotlin.com.intellij.lang.ASTNode -public class SpacingBetweenFunctionNameAndOpeningParenthesisRule : Rule("spacing-between-function-name-and-opening-parenthesis") { +public class SpacingBetweenFunctionNameAndOpeningParenthesisRule : Rule("$experimentalRulesetId:spacing-between-function-name-and-opening-parenthesis") { override fun visit( node: ASTNode, autoCorrect: Boolean, diff --git a/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/TypeArgumentListSpacingRule.kt b/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/TypeArgumentListSpacingRule.kt index 01d1747688..26d190102d 100644 --- a/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/TypeArgumentListSpacingRule.kt +++ b/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/TypeArgumentListSpacingRule.kt @@ -22,7 +22,7 @@ import org.jetbrains.kotlin.com.intellij.lang.ASTNode /** * Lints and formats the spacing before and after the angle brackets of a type argument list. */ -public class TypeArgumentListSpacingRule : Rule("type-argument-list-spacing") { +public class TypeArgumentListSpacingRule : Rule("$experimentalRulesetId:type-argument-list-spacing") { override fun visit( node: ASTNode, autoCorrect: Boolean, diff --git a/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/TypeParameterListSpacingRule.kt b/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/TypeParameterListSpacingRule.kt index 47f9502ecf..2ebe62bf18 100644 --- a/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/TypeParameterListSpacingRule.kt +++ b/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/TypeParameterListSpacingRule.kt @@ -24,7 +24,7 @@ import org.jetbrains.kotlin.com.intellij.psi.impl.source.tree.LeafPsiElement /** * Lints and formats the spacing before and after the angle brackets of a type parameter list. */ -public class TypeParameterListSpacingRule : Rule("type-parameter-list-spacing") { +public class TypeParameterListSpacingRule : Rule("$experimentalRulesetId:type-parameter-list-spacing") { override fun visit( node: ASTNode, autoCorrect: Boolean, diff --git a/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/UnnecessaryParenthesesBeforeTrailingLambdaRule.kt b/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/UnnecessaryParenthesesBeforeTrailingLambdaRule.kt index ab0e0e2bd6..a5d71eb8ba 100644 --- a/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/UnnecessaryParenthesesBeforeTrailingLambdaRule.kt +++ b/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/UnnecessaryParenthesesBeforeTrailingLambdaRule.kt @@ -14,7 +14,7 @@ import org.jetbrains.kotlin.com.intellij.lang.ASTNode /** * Ensures there are no unnecessary parentheses before a trailing lambda. */ -class UnnecessaryParenthesesBeforeTrailingLambdaRule : Rule("unnecessary-parentheses-before-trailing-lambda") { +class UnnecessaryParenthesesBeforeTrailingLambdaRule : Rule("$experimentalRulesetId:unnecessary-parentheses-before-trailing-lambda") { override fun visit( node: ASTNode, autoCorrect: Boolean, diff --git a/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/trailingcomma/TrailingCommaRule.kt b/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/trailingcomma/TrailingCommaRule.kt index 8c2d1b31b0..7c80610c65 100644 --- a/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/trailingcomma/TrailingCommaRule.kt +++ b/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/trailingcomma/TrailingCommaRule.kt @@ -10,6 +10,7 @@ import com.pinterest.ktlint.core.ast.containsLineBreakInRange import com.pinterest.ktlint.core.ast.isRoot import com.pinterest.ktlint.core.ast.prevCodeLeaf import com.pinterest.ktlint.core.ast.prevLeaf +import com.pinterest.ktlint.ruleset.experimental.experimentalRulesetId import kotlin.properties.Delegates import org.ec4j.core.model.PropertyType import org.ec4j.core.model.PropertyType.PropertyValueParser @@ -33,7 +34,7 @@ import org.jetbrains.kotlin.utils.addToStdlib.cast @OptIn(FeatureInAlphaState::class) public class TrailingCommaRule : Rule( - id = "trailing-comma", + id = "$experimentalRulesetId:trailing-comma", visitorModifiers = setOf( VisitorModifier.RunAfterRule( ruleId = "standard:indent", diff --git a/ktlint-ruleset-experimental/src/test/kotlin/com/pinterest/ktlint/ruleset/experimental/ArgumentListWrappingRuleTest.kt b/ktlint-ruleset-experimental/src/test/kotlin/com/pinterest/ktlint/ruleset/experimental/ArgumentListWrappingRuleTest.kt index 48e22eab37..3464ad3ff5 100644 --- a/ktlint-ruleset-experimental/src/test/kotlin/com/pinterest/ktlint/ruleset/experimental/ArgumentListWrappingRuleTest.kt +++ b/ktlint-ruleset-experimental/src/test/kotlin/com/pinterest/ktlint/ruleset/experimental/ArgumentListWrappingRuleTest.kt @@ -61,7 +61,7 @@ class ArgumentListWrappingRuleTest { ) """.trimIndent() argumentListWrappingRuleAssertThat(code) - .addAdditionalFormattingRule(IndentationRule()) + .addAdditionalRules(IndentationRule()) .hasLintViolations( LintViolation(2, 9, "Argument should be on a separate line (unless all arguments can fit a single line)"), LintViolation(2, 14, "Argument should be on a separate line (unless all arguments can fit a single line)"), @@ -281,7 +281,7 @@ class ArgumentListWrappingRuleTest { } """.trimIndent() argumentListWrappingRuleAssertThat(code) - .addAdditionalFormattingRule(IndentationRule()) + .addAdditionalRules(IndentationRule()) .hasLintViolations( LintViolation(2, 10, "Argument should be on a separate line (unless all arguments can fit a single line)"), LintViolation(2, 19, "Argument should be on a separate line (unless all arguments can fit a single line)"), diff --git a/ktlint-ruleset-experimental/src/test/kotlin/com/pinterest/ktlint/ruleset/experimental/FunctionSignatureRuleTest.kt b/ktlint-ruleset-experimental/src/test/kotlin/com/pinterest/ktlint/ruleset/experimental/FunctionSignatureRuleTest.kt index f25a1e6aa3..56847ac75e 100644 --- a/ktlint-ruleset-experimental/src/test/kotlin/com/pinterest/ktlint/ruleset/experimental/FunctionSignatureRuleTest.kt +++ b/ktlint-ruleset-experimental/src/test/kotlin/com/pinterest/ktlint/ruleset/experimental/FunctionSignatureRuleTest.kt @@ -56,7 +56,7 @@ class FunctionSignatureRuleTest { """.trimIndent() functionSignatureWrappingRuleAssertThat(code) .setMaxLineLength() - .addAdditionalFormattingRule(FunctionStartOfBodySpacingRule()) + .addAdditionalRules(FunctionStartOfBodySpacingRule()) .hasLintViolation(2, 38, "Expected a single space before body block") .isFormattedAs(formattedCode) } @@ -481,8 +481,8 @@ class FunctionSignatureRuleTest { fun f7(): List? = null """.trimIndent() functionSignatureWrappingRuleAssertThat(code) - .addAdditionalFormattingRule(NullableTypeSpacingRule()) - .hasNoLintViolationsExceptInAdditionalFormattingRules() + .addAdditionalRules(NullableTypeSpacingRule()) + .hasNoLintViolationsExceptInAdditionalRules() .isFormattedAs(formattedCode) } @@ -553,7 +553,7 @@ class FunctionSignatureRuleTest { fun f29(block: (T) -> String) = "some-result" """.trimIndent() functionSignatureWrappingRuleAssertThat(code) - .addAdditionalFormattingRule( + .addAdditionalRules( NoMultipleSpacesRule(), SpacingAroundAngleBracketsRule(), SpacingAroundParensRule(), @@ -603,7 +603,7 @@ class FunctionSignatureRuleTest { fun f11(block: (T) -> String) = "some-result" """.trimIndent() functionSignatureWrappingRuleAssertThat(code) - .addAdditionalFormattingRule( + .addAdditionalRules( TypeParameterListSpacingRule(), FunctionStartOfBodySpacingRule(), FunctionTypeReferenceSpacingRule(), diff --git a/ktlint-ruleset-experimental/src/test/kotlin/com/pinterest/ktlint/ruleset/experimental/MultiLineIfElseRuleTest.kt b/ktlint-ruleset-experimental/src/test/kotlin/com/pinterest/ktlint/ruleset/experimental/MultiLineIfElseRuleTest.kt index c9300d7285..9360a17e55 100644 --- a/ktlint-ruleset-experimental/src/test/kotlin/com/pinterest/ktlint/ruleset/experimental/MultiLineIfElseRuleTest.kt +++ b/ktlint-ruleset-experimental/src/test/kotlin/com/pinterest/ktlint/ruleset/experimental/MultiLineIfElseRuleTest.kt @@ -425,7 +425,7 @@ class MultiLineIfElseRuleTest { } """.trimIndent() multiLineIfElseRuleAssertThat(code) - .addAdditionalFormattingRule(IndentationRule()) + .addAdditionalRules(IndentationRule()) .hasLintViolations( LintViolation(4, 9, "Missing { ... }"), LintViolation(7, 9, "Missing { ... }") @@ -454,7 +454,7 @@ class MultiLineIfElseRuleTest { } """.trimIndent() multiLineIfElseRuleAssertThat(code) - .addAdditionalFormattingRule(IndentationRule()) + .addAdditionalRules(IndentationRule()) .hasLintViolations( LintViolation(3, 9, "Missing { ... }"), LintViolation(5, 9, "Missing { ... }") diff --git a/ktlint-ruleset-experimental/src/test/kotlin/com/pinterest/ktlint/ruleset/experimental/NullableTypeSpacingRuleTest.kt b/ktlint-ruleset-experimental/src/test/kotlin/com/pinterest/ktlint/ruleset/experimental/NullableTypeSpacingRuleTest.kt index fc70587050..4bd0c99188 100644 --- a/ktlint-ruleset-experimental/src/test/kotlin/com/pinterest/ktlint/ruleset/experimental/NullableTypeSpacingRuleTest.kt +++ b/ktlint-ruleset-experimental/src/test/kotlin/com/pinterest/ktlint/ruleset/experimental/NullableTypeSpacingRuleTest.kt @@ -1,10 +1,6 @@ package com.pinterest.ktlint.ruleset.experimental -import com.pinterest.ktlint.core.LintError import com.pinterest.ktlint.test.KtLintAssertThat.Companion.assertThat -import com.pinterest.ktlint.test.format -import com.pinterest.ktlint.test.lint -import org.assertj.core.api.Assertions import org.junit.jupiter.api.Test class NullableTypeSpacingRuleTest { @@ -20,10 +16,9 @@ class NullableTypeSpacingRuleTest { """ val foo : String? = null """.trimIndent() - Assertions.assertThat(NullableTypeSpacingRule().lint(code)).containsExactly( - LintError(1, 17, "nullable-type-spacing", "Unexpected whitespace") - ) - Assertions.assertThat(NullableTypeSpacingRule().format(code)).isEqualTo(formattedCode) + nullableTypeSpacingRuleAssertThat(code) + .hasLintViolation(1, 17, "Unexpected whitespace") + .isFormattedAs(formattedCode) } @Test diff --git a/ktlint-ruleset-experimental/src/test/kotlin/com/pinterest/ktlint/ruleset/experimental/SpacingAroundAngleBracketRuleTest.kt b/ktlint-ruleset-experimental/src/test/kotlin/com/pinterest/ktlint/ruleset/experimental/SpacingAroundAngleBracketRuleTest.kt index de4cc3c8b1..750fab5261 100644 --- a/ktlint-ruleset-experimental/src/test/kotlin/com/pinterest/ktlint/ruleset/experimental/SpacingAroundAngleBracketRuleTest.kt +++ b/ktlint-ruleset-experimental/src/test/kotlin/com/pinterest/ktlint/ruleset/experimental/SpacingAroundAngleBracketRuleTest.kt @@ -60,7 +60,7 @@ class SpacingAroundAngleBracketRuleTest { > = mapOf() """.trimIndent() spacingAroundAngleBracketsRuleAssertThat(code) - .addAdditionalFormattingRule(IndentationRule()) + .addAdditionalRules(IndentationRule()) .hasLintViolations( LintViolation(1, 12, "Unexpected spacing after \"<\""), LintViolation(2, 23, "Unexpected spacing before \">\""), @@ -110,7 +110,7 @@ class SpacingAroundAngleBracketRuleTest { > {} """.trimIndent() spacingAroundAngleBracketsRuleAssertThat(code) - .addAdditionalFormattingRule(IndentationRule()) + .addAdditionalRules(IndentationRule()) .hasLintViolations( LintViolation(2, 19, "Unexpected spacing after \"<\""), LintViolation(3, 31, "Unexpected spacing before \">\""), diff --git a/ktlint-ruleset-experimental/src/test/kotlin/com/pinterest/ktlint/ruleset/experimental/TrailingCommaRuleTest.kt b/ktlint-ruleset-experimental/src/test/kotlin/com/pinterest/ktlint/ruleset/experimental/TrailingCommaRuleTest.kt index a3e58597be..327b28de87 100644 --- a/ktlint-ruleset-experimental/src/test/kotlin/com/pinterest/ktlint/ruleset/experimental/TrailingCommaRuleTest.kt +++ b/ktlint-ruleset-experimental/src/test/kotlin/com/pinterest/ktlint/ruleset/experimental/TrailingCommaRuleTest.kt @@ -4,6 +4,7 @@ import com.pinterest.ktlint.core.api.FeatureInAlphaState import com.pinterest.ktlint.ruleset.experimental.trailingcomma.TrailingCommaRule import com.pinterest.ktlint.ruleset.experimental.trailingcomma.TrailingCommaRule.Companion.allowTrailingCommaOnCallSiteProperty import com.pinterest.ktlint.ruleset.experimental.trailingcomma.TrailingCommaRule.Companion.allowTrailingCommaProperty +import com.pinterest.ktlint.ruleset.standard.IndentationRule import com.pinterest.ktlint.ruleset.standard.NoUnusedImportsRule import com.pinterest.ktlint.test.KtLintAssertThat.Companion.assertThat import com.pinterest.ktlint.test.LintViolation @@ -11,7 +12,13 @@ import org.junit.jupiter.api.Test @OptIn(FeatureInAlphaState::class) class TrailingCommaRuleTest { - private val trailingCommaRuleAssertThat = TrailingCommaRule().assertThat() + private val trailingCommaRuleAssertThat = + TrailingCommaRule() + .assertThat( + // Apply the IndentationRule always as additional rule, so that the formattedCode in the unit test looks + // correct. + IndentationRule() + ) @Test fun `Given property allow trailing comma on call site is not set then remove trailing comma's`() { @@ -124,8 +131,8 @@ class TrailingCommaRuleTest { ) -> Int = when (x) { 1, 2 -> { - foo, - bar /* The comma should be inserted before the comment */ + foo, + bar /* The comma should be inserted before the comment */ -> block( foo * bar, @@ -146,8 +153,8 @@ class TrailingCommaRuleTest { ) -> Int = when (x) { 1, 2, -> { - foo, - bar, /* The comma should be inserted before the comment */ + foo, + bar, /* The comma should be inserted before the comment */ -> block( foo * bar, @@ -164,7 +171,7 @@ class TrailingCommaRuleTest { LintViolation(4, 29, "Missing trailing comma before \")\""), LintViolation(6, 13, "Missing trailing comma before \")\""), LintViolation(8, 9, "Missing trailing comma before \"->\""), - LintViolation(11, 12, "Missing trailing comma before \"->\""), + LintViolation(11, 16, "Missing trailing comma before \"->\""), LintViolation(15, 22, "Missing trailing comma before \")\"") ).isFormattedAs(formattedCode) } @@ -244,28 +251,28 @@ class TrailingCommaRuleTest { """ data class Foo1(val bar: Int,) data class Foo2( - val bar: Int, // The comma before the comment should be removed without removing the comment itself + val bar: Int, // The comma before the comment should be removed without removing the comment itself ) data class Foo3( - val bar: Int, /* The comma before the comment should be removed without removing the comment itself */ + val bar: Int, /* The comma before the comment should be removed without removing the comment itself */ ) """.trimIndent() val formattedCode = """ data class Foo1(val bar: Int) data class Foo2( - val bar: Int // The comma before the comment should be removed without removing the comment itself + val bar: Int // The comma before the comment should be removed without removing the comment itself ) data class Foo3( - val bar: Int /* The comma before the comment should be removed without removing the comment itself */ + val bar: Int /* The comma before the comment should be removed without removing the comment itself */ ) """.trimIndent() trailingCommaRuleAssertThat(code) .withEditorConfigOverride(allowTrailingCommaProperty to false) .hasLintViolations( LintViolation(1, 29, "Unnecessary trailing comma before \")\""), - LintViolation(3, 16, "Unnecessary trailing comma before \")\""), - LintViolation(6, 16, "Unnecessary trailing comma before \")\"") + LintViolation(3, 17, "Unnecessary trailing comma before \")\""), + LintViolation(6, 17, "Unnecessary trailing comma before \")\"") ).isFormattedAs(formattedCode) } @@ -275,27 +282,27 @@ class TrailingCommaRuleTest { """ data class Foo1(val bar: Int) data class Foo2( - val bar: Int // The comma should be inserted before the comment + val bar: Int // The comma should be inserted before the comment ) data class Foo3( - val bar: Int /* The comma should be inserted before the comment */ + val bar: Int /* The comma should be inserted before the comment */ ) """.trimIndent() val formattedCode = """ data class Foo1(val bar: Int) data class Foo2( - val bar: Int, // The comma should be inserted before the comment + val bar: Int, // The comma should be inserted before the comment ) data class Foo3( - val bar: Int, /* The comma should be inserted before the comment */ + val bar: Int, /* The comma should be inserted before the comment */ ) """.trimIndent() trailingCommaRuleAssertThat(code) .withEditorConfigOverride(allowTrailingCommaProperty to true) .hasLintViolations( - LintViolation(3, 16, "Missing trailing comma before \")\""), - LintViolation(6, 16, "Missing trailing comma before \")\"") + LintViolation(3, 17, "Missing trailing comma before \")\""), + LintViolation(6, 17, "Missing trailing comma before \")\"") ).isFormattedAs(formattedCode) } @@ -307,11 +314,11 @@ class TrailingCommaRuleTest { class Foo2< A, B, // The comma before the comment should be removed without removing the comment itself - > {} + > {} class Foo3< A, B, /* The comma before the comment should be removed without removing the comment itself */ - > {} + > {} """.trimIndent() val formattedCode = """ @@ -319,11 +326,11 @@ class TrailingCommaRuleTest { class Foo2< A, B // The comma before the comment should be removed without removing the comment itself - > {} + > {} class Foo3< A, B /* The comma before the comment should be removed without removing the comment itself */ - > {} + > {} """.trimIndent() trailingCommaRuleAssertThat(code) .withEditorConfigOverride(allowTrailingCommaProperty to false) @@ -342,11 +349,11 @@ class TrailingCommaRuleTest { class Foo2< A, B // The comma should be inserted before the comment - > {} + > {} class Foo3< A, B /* The comma should be inserted before the comment */ - > {} + > {} """.trimIndent() val formattedCode = """ @@ -354,11 +361,11 @@ class TrailingCommaRuleTest { class Foo2< A, B, // The comma should be inserted before the comment - > {} + > {} class Foo3< A, B, /* The comma should be inserted before the comment */ - > {} + > {} """.trimIndent() trailingCommaRuleAssertThat(code) .withEditorConfigOverride(allowTrailingCommaProperty to true) @@ -528,13 +535,13 @@ class TrailingCommaRuleTest { """ val fooBar1: (Int, Int) -> Int = { foo, bar, -> foo * bar } val fooBar2: (Int, Int) -> Int = { - foo, - bar, // The comma before the comment should be removed without removing the comment itself + foo, + bar, // The comma before the comment should be removed without removing the comment itself -> foo * bar } val fooBar3: (Int, Int) -> Int = { - foo, - bar, /* The comma before the comment should be removed without removing the comment itself */ + foo, + bar, /* The comma before the comment should be removed without removing the comment itself */ -> foo * bar } """.trimIndent() @@ -542,13 +549,13 @@ class TrailingCommaRuleTest { """ val fooBar1: (Int, Int) -> Int = { foo, bar -> foo * bar } val fooBar2: (Int, Int) -> Int = { - foo, - bar // The comma before the comment should be removed without removing the comment itself + foo, + bar // The comma before the comment should be removed without removing the comment itself -> foo * bar } val fooBar3: (Int, Int) -> Int = { - foo, - bar /* The comma before the comment should be removed without removing the comment itself */ + foo, + bar /* The comma before the comment should be removed without removing the comment itself */ -> foo * bar } """.trimIndent() @@ -556,8 +563,8 @@ class TrailingCommaRuleTest { .withEditorConfigOverride(allowTrailingCommaProperty to false) .hasLintViolations( LintViolation(1, 44, "Unnecessary trailing comma before \"->\""), - LintViolation(4, 8, "Unnecessary trailing comma before \"->\""), - LintViolation(9, 8, "Unnecessary trailing comma before \"->\"") + LintViolation(4, 12, "Unnecessary trailing comma before \"->\""), + LintViolation(9, 12, "Unnecessary trailing comma before \"->\"") ).isFormattedAs(formattedCode) } @@ -567,13 +574,13 @@ class TrailingCommaRuleTest { """ val fooBar1: (Int, Int) -> Int = { foo, bar -> foo * bar } val fooBar2: (Int, Int) -> Int = { - foo, - bar // The comma should be inserted before the comment + foo, + bar // The comma should be inserted before the comment -> foo * bar } val fooBar3: (Int, Int) -> Int = { - foo, - bar /* The comma should be inserted before the comment */ + foo, + bar /* The comma should be inserted before the comment */ -> foo * bar } """.trimIndent() @@ -581,21 +588,21 @@ class TrailingCommaRuleTest { """ val fooBar1: (Int, Int) -> Int = { foo, bar -> foo * bar } val fooBar2: (Int, Int) -> Int = { - foo, - bar, // The comma should be inserted before the comment + foo, + bar, // The comma should be inserted before the comment -> foo * bar } val fooBar3: (Int, Int) -> Int = { - foo, - bar, /* The comma should be inserted before the comment */ + foo, + bar, /* The comma should be inserted before the comment */ -> foo * bar } """.trimIndent() trailingCommaRuleAssertThat(code) .withEditorConfigOverride(allowTrailingCommaProperty to true) .hasLintViolations( - LintViolation(4, 8, "Missing trailing comma before \"->\""), - LintViolation(9, 8, "Missing trailing comma before \"->\"") + LintViolation(4, 12, "Missing trailing comma before \"->\""), + LintViolation(9, 12, "Missing trailing comma before \"->\"") ).isFormattedAs(formattedCode) } @@ -606,20 +613,20 @@ class TrailingCommaRuleTest { val list1: List = emptyList() val list2: List< String, // The comma before the comment should be removed without removing the comment itself - > = emptyList() + > = emptyList() val list3: List< String, /* The comma before the comment should be removed without removing the comment itself */ - > = emptyList() + > = emptyList() """.trimIndent() val formattedCode = """ val list1: List = emptyList() val list2: List< String // The comma before the comment should be removed without removing the comment itself - > = emptyList() + > = emptyList() val list3: List< String /* The comma before the comment should be removed without removing the comment itself */ - > = emptyList() + > = emptyList() """.trimIndent() trailingCommaRuleAssertThat(code) .withEditorConfigOverride(allowTrailingCommaOnCallSiteProperty to false) @@ -637,20 +644,20 @@ class TrailingCommaRuleTest { val list1: List = emptyList() val list2: List< String // The comma should be inserted before the comment - > = emptyList() + > = emptyList() val list3: List< String /* The comma should be inserted before the comment */ - > = emptyList() + > = emptyList() """.trimIndent() val formattedCode = """ val list1: List = emptyList() val list2: List< String, // The comma should be inserted before the comment - > = emptyList() + > = emptyList() val list3: List< String, /* The comma should be inserted before the comment */ - > = emptyList() + > = emptyList() """.trimIndent() trailingCommaRuleAssertThat(code) .withEditorConfigOverride(allowTrailingCommaOnCallSiteProperty to true) @@ -898,9 +905,9 @@ class TrailingCommaRuleTest { val code = """ class Test { - var foo = Bar() - set(value) { - } + var foo = Bar() + set(value) { + } } """.trimIndent() trailingCommaRuleAssertThat(code) @@ -979,7 +986,7 @@ class TrailingCommaRuleTest { // was incorrectly seen as part of the type of variable "bar3" and a reference "EnumThree," (with the // trailing comma was added) which in turn resulted in not recognizing that the import of EnumThree actually // was used. - .addAdditionalFormattingRule(NoUnusedImportsRule()) + .addAdditionalRules(NoUnusedImportsRule()) .withEditorConfigOverride(allowTrailingCommaProperty to true) .hasLintViolation(9, 24, "Missing trailing comma before \")\"") .isFormattedAs(formattedCode) diff --git a/ktlint-ruleset-standard/src/test/kotlin/com/pinterest/ktlint/ruleset/standard/IndentationRuleTest.kt b/ktlint-ruleset-standard/src/test/kotlin/com/pinterest/ktlint/ruleset/standard/IndentationRuleTest.kt index 7149f5d146..a9a9e8e669 100644 --- a/ktlint-ruleset-standard/src/test/kotlin/com/pinterest/ktlint/ruleset/standard/IndentationRuleTest.kt +++ b/ktlint-ruleset-standard/src/test/kotlin/com/pinterest/ktlint/ruleset/standard/IndentationRuleTest.kt @@ -2010,7 +2010,7 @@ internal class IndentationRuleTest { """.trimIndent() .replacePlaceholderWithStringTemplate() indentationRuleAssertThat(code) - .addAdditionalFormattingRule(WrappingRule()) + .addAdditionalRules(WrappingRule()) .hasLintViolations( LintViolation(3, 1, "Unexpected indentation (4) (should be 8)"), LintViolation(4, 1, "Unexpected indentation (4) (should be 8)") @@ -2048,7 +2048,7 @@ internal class IndentationRuleTest { } """.trimIndent() indentationRuleAssertThat(code) - .addAdditionalFormattingRule(WrappingRule()) + .addAdditionalRules(WrappingRule()) .hasLintViolations( LintViolation(5, 1, "Unexpected indent of multiline string closing quotes"), LintViolation(7, 1, "Unexpected indent of multiline string closing quotes") @@ -2088,7 +2088,7 @@ internal class IndentationRuleTest { """.trimIndent() .replacePlaceholderWithStringTemplate() indentationRuleAssertThat(code) - .addAdditionalFormattingRule(WrappingRule()) + .addAdditionalRules(WrappingRule()) .hasLintViolations( LintViolation(3, 1, "Unexpected indentation (0) (should be 8)"), LintViolation(4, 1, "Unexpected indentation (4) (should be 8)"), @@ -2669,7 +2669,7 @@ internal class IndentationRuleTest { } """.trimIndent() indentationRuleAssertThat(code) - .addAdditionalFormattingRule(WrappingRule()) + .addAdditionalRules(WrappingRule()) .hasLintViolations( LintViolation(2, 1, "Unexpected indentation (0) (should be 4)"), LintViolation(6, 1, "Unexpected indent of multiline string closing quotes") @@ -2730,7 +2730,7 @@ internal class IndentationRuleTest { } """.trimIndent() indentationRuleAssertThat(code) - .addAdditionalFormattingRule(WrappingRule()) + .addAdditionalRules(WrappingRule()) .hasLintViolation(6, 1, "Unexpected indent of multiline string closing quotes") .isFormattedAs(formattedCode) } @@ -2900,7 +2900,7 @@ internal class IndentationRuleTest { } """.trimIndent() indentationRuleAssertThat(code) - .addAdditionalFormattingRule(WrappingRule()) + .addAdditionalRules(WrappingRule()) .hasLintViolation(6, 1, "Unexpected indent of multiline string closing quotes") .isFormattedAs(formattedCode) } @@ -3720,6 +3720,34 @@ internal class IndentationRuleTest { indentationRuleAssertThat(code).hasNoLintViolations() } + @Disabled("To be fixed as code as lambda with parameters on multiple line") + @Test + fun `Given a function with lambda parameters on multiple lines then align the parameters`() { + val code = + """ + val fieldExample = + LongNameClass { paramA, + paramB, + paramC -> + ClassB(paramA, paramB, paramC) + } + """.trimIndent() + val formattedCode = + """ + val fieldExample = + LongNameClass { paramA, + paramB, + paramC -> + ClassB(paramA, paramB, paramC) + } + """.trimIndent() + indentationRuleAssertThat(code) + .hasLintViolations( + LintViolation(3, 1, "Unexpected indentation (12) (should be 20)"), + LintViolation(4, 1, "Unexpected indentation (12) (should be 20)") + ).isFormattedAs(formattedCode) + } + private companion object { val INDENT_STYLE_TAB = indentStyleProperty to PropertyType.IndentStyleValue.tab } diff --git a/ktlint-ruleset-standard/src/test/kotlin/com/pinterest/ktlint/ruleset/standard/ParameterListWrappingRuleTest.kt b/ktlint-ruleset-standard/src/test/kotlin/com/pinterest/ktlint/ruleset/standard/ParameterListWrappingRuleTest.kt index a85cc165aa..71b5c245a8 100644 --- a/ktlint-ruleset-standard/src/test/kotlin/com/pinterest/ktlint/ruleset/standard/ParameterListWrappingRuleTest.kt +++ b/ktlint-ruleset-standard/src/test/kotlin/com/pinterest/ktlint/ruleset/standard/ParameterListWrappingRuleTest.kt @@ -11,13 +11,9 @@ class ParameterListWrappingRuleTest { private val parameterListWrappingRuleAssertThat = ParameterListWrappingRule() .assertThat( - additionalFormattingRules = listOf( - // In case a parameter is wrapped to a separate line by the ParameterListWrappingRule() then its - // indentation might still be incorrect until the IndentationRule has fixed it. Apply the - // IndentationRule format after the ParameterListWrappingRule(), so that the formattedCode in the - /* unit test looks correct. Note that the Lint Violations of the rule are suppressed!.*/ - IndentationRule() - ) + // Apply the IndentationRule always as additional rule, so that the formattedCode in the unit test looks + // correct. + IndentationRule() ) @Test @@ -182,13 +178,17 @@ class ParameterListWrappingRuleTest { val code = """ val fieldExample = - LongNameClass { paramA, - paramB, - paramC -> - ClassB(paramA, paramB, paramC) - } + LongNameClass { paramA, + paramB, + paramC -> + ClassB(paramA, paramB, paramC) + } """.trimIndent() - parameterListWrappingRuleAssertThat(code).hasNoLintViolations() + val parameterListWrappingRuleWithoutIndentationRule = ParameterListWrappingRule().assertThat() + parameterListWrappingRuleWithoutIndentationRule(code).hasNoLintViolations() + // IndentationRule does alter the code while the code is accepted by the Default IDEA formatter. So statement + // below would fail! + // parameterListWrappingRuleAssertThat(code).hasNoLintViolations() } @Test @@ -340,11 +340,11 @@ class ParameterListWrappingRuleTest { val code = """ data class A( - /* - * comment - */ - // - var v: String + /* + * comment + */ + // + var v: String ) """.trimIndent() parameterListWrappingRuleAssertThat(code).hasNoLintViolations() diff --git a/ktlint-ruleset-standard/src/test/kotlin/com/pinterest/ktlint/ruleset/standard/StringTemplateRuleTest.kt b/ktlint-ruleset-standard/src/test/kotlin/com/pinterest/ktlint/ruleset/standard/StringTemplateRuleTest.kt index 5c700673f2..30b512430a 100644 --- a/ktlint-ruleset-standard/src/test/kotlin/com/pinterest/ktlint/ruleset/standard/StringTemplateRuleTest.kt +++ b/ktlint-ruleset-standard/src/test/kotlin/com/pinterest/ktlint/ruleset/standard/StringTemplateRuleTest.kt @@ -350,7 +350,7 @@ class StringTemplateRuleTest { } """.trimIndent() stringTemplateRuleAssertThat(code) - .addAdditionalFormattingRule(NoUnusedImportsRule()) + .addAdditionalRules(NoUnusedImportsRule()) .hasLintViolation(3, 21, "Redundant \"toString()\" call in string template") .isFormattedAs(formattedCode) } diff --git a/ktlint-ruleset-standard/src/test/kotlin/com/pinterest/ktlint/ruleset/standard/WrappingRuleTest.kt b/ktlint-ruleset-standard/src/test/kotlin/com/pinterest/ktlint/ruleset/standard/WrappingRuleTest.kt index f707770346..982c87dba6 100644 --- a/ktlint-ruleset-standard/src/test/kotlin/com/pinterest/ktlint/ruleset/standard/WrappingRuleTest.kt +++ b/ktlint-ruleset-standard/src/test/kotlin/com/pinterest/ktlint/ruleset/standard/WrappingRuleTest.kt @@ -42,7 +42,7 @@ internal class WrappingRuleTest { """.trimIndent() .replacePlaceholderWithStringTemplate() wrappingRuleAssertThat(code) - .addAdditionalFormattingRule(IndentationRule()) + .addAdditionalRules(IndentationRule()) .hasLintViolations( LintViolation(2, 13, "Missing newline after \"(\""), LintViolation(4, 6, "Missing newline before \")\"") @@ -80,7 +80,7 @@ internal class WrappingRuleTest { } """.trimIndent() wrappingRuleAssertThat(code) - .addAdditionalFormattingRule(IndentationRule()) + .addAdditionalRules(IndentationRule()) .hasLintViolations( LintViolation(2, 13, "Missing newline after \"(\""), LintViolation(3, 7, "Missing newline before \")\""), @@ -124,7 +124,7 @@ internal class WrappingRuleTest { """.trimIndent() .replacePlaceholderWithStringTemplate() wrappingRuleAssertThat(code) - .addAdditionalFormattingRule(IndentationRule()) + .addAdditionalRules(IndentationRule()) .hasLintViolations( LintViolation(2, 10, "Missing newline after \"(\""), LintViolation(8, 6, "Missing newline before \"\"\""), @@ -158,7 +158,7 @@ internal class WrappingRuleTest { } """.trimIndent() wrappingRuleAssertThat(code) - .addAdditionalFormattingRule(IndentationRule()) + .addAdditionalRules(IndentationRule()) .hasLintViolations( LintViolation(2, 9, "Missing newline after \"(\""), LintViolation(6, 30, "Missing newline before \")\"") @@ -191,7 +191,7 @@ internal class WrappingRuleTest { } """.trimIndent() wrappingRuleAssertThat(code) - .addAdditionalFormattingRule(IndentationRule()) + .addAdditionalRules(IndentationRule()) .hasLintViolations( LintViolation(2, 11, "Missing newline after \"(\""), LintViolation(2, 49, "Missing newline after \",\""), @@ -230,7 +230,7 @@ internal class WrappingRuleTest { } """.trimIndent() wrappingRuleAssertThat(code) - .addAdditionalFormattingRule(IndentationRule()) + .addAdditionalRules(IndentationRule()) .hasLintViolations( LintViolation(1, 10, "Missing newline after \"(\""), LintViolation(1, 33, "Missing newline after \",\""), @@ -272,7 +272,7 @@ internal class WrappingRuleTest { } """.trimIndent() wrappingRuleAssertThat(code) - .addAdditionalFormattingRule(IndentationRule()) + .addAdditionalRules(IndentationRule()) .hasLintViolations( LintViolation(6, 8, "Missing newline after \"(\""), LintViolation(8, 8, "Missing newline before \")\"") diff --git a/ktlint-test/src/main/kotlin/com/pinterest/ktlint/test/KtLintAssertThat.kt b/ktlint-test/src/main/kotlin/com/pinterest/ktlint/test/KtLintAssertThat.kt index 35e7af06dc..4a2c5d6a99 100644 --- a/ktlint-test/src/main/kotlin/com/pinterest/ktlint/test/KtLintAssertThat.kt +++ b/ktlint-test/src/main/kotlin/com/pinterest/ktlint/test/KtLintAssertThat.kt @@ -31,9 +31,19 @@ import org.assertj.core.api.Assertions.assertThat @OptIn(FeatureInAlphaState::class) @Suppress("MemberVisibilityCanBePrivate") public class KtLintAssertThat( + /** + * The rule which is the subject of the test, e.g. the rule for which the AssertThat is created. + */ private val rule: Rule, + /** + * The code which is to be linted and formatted. + */ private val code: String, - private val additionalFormattingRules: MutableSet + /** + * The rules which have to be executed in addition to the main rule when linting/formatting the code. Note that + * lint errors for those rules are suppressed. + */ + private val additionalRules: MutableSet ) { private var filePath: String? = null private var kotlinScript = false @@ -99,11 +109,12 @@ public class KtLintAssertThat( } /** - * Adds a rule to be executed when formatting the code. This can to be used to unit test rules which are best to be - * tested in conjunction, for example wrapping and indenting. This method can be called multiple times if needed. + * Adds a rule to be executed when linting/formatting the code. This can to be used to unit test rules which are + * best to be tested in conjunction, for example wrapping and indenting. This method can be called multiple times if + * needed. */ - public fun addAdditionalFormattingRule(vararg rules: Rule): KtLintAssertThat { - additionalFormattingRules.addAll(rules) + public fun addAdditionalRules(vararg rules: Rule): KtLintAssertThat { + additionalRules.addAll(rules) return this } @@ -120,8 +131,8 @@ public class KtLintAssertThat( * * Note: When linting succeeds without errors, formatting is also checked. */ - public fun hasNoLintViolationsExceptInAdditionalFormattingRules(): KtLintAssertThatAssertable = - ktLintAssertThatAssertable().hasNoLintViolationsExceptInAdditionalFormattingRules() + public fun hasNoLintViolationsExceptInAdditionalRules(): KtLintAssertThatAssertable = + ktLintAssertThatAssertable().hasNoLintViolationsExceptInAdditionalRules() /** * Asserts that the code does contain given [LintViolation] which automatically can be corrected. This is a sugar @@ -172,7 +183,7 @@ public class KtLintAssertThat( filePath = filePath, kotlinScript = kotlinScript, editorConfigOverride = EditorConfigOverride.emptyEditorConfigOverride, - additionalFormattingRules = additionalFormattingRules.toList() + additionalRules = additionalRules.toList() ) } else { KtLintAssertThatAssertable( @@ -181,20 +192,20 @@ public class KtLintAssertThat( filePath = filePath, kotlinScript = kotlinScript, editorConfigOverride = EditorConfigOverride.from(*editorConfigProperties.toTypedArray()), - additionalFormattingRules = additionalFormattingRules.toList() + additionalRules = additionalRules.toList() ) } public companion object { /** * Creates an assertThat assertion function for a given rule. This assertion function has extensions - * specifically for testing KtLint rules. The [additionalFormattingRules] are only executed during the format + * specifically for testing KtLint rules. The [additionalRules] are only executed during the format * phase of the test. This means that the unit test only has to check the lint violations thrown by the rule for * which the assertThat is created. But the code is formatted by both the rule and the - * [additionalFormattingRules] in the order as defined by the rule definitions. + * [additionalRules] in the order as defined by the rule definitions. */ - public fun Rule.assertThat(additionalFormattingRules: List = emptyList()): (String) -> KtLintAssertThat = - { code -> KtLintAssertThat(this, code, additionalFormattingRules.toMutableSet()) } + public fun Rule.assertThat(vararg additionalRules: Rule): (String) -> KtLintAssertThat = + { code -> KtLintAssertThat(this, code, additionalRules.toMutableSet()) } /** * See [setMaxLineLength] for intended usage. @@ -215,14 +226,17 @@ public class KtLintAssertThat( */ @OptIn(FeatureInAlphaState::class) public class KtLintAssertThatAssertable( - /** The rule for which the AssertThat is created. */ + /** The rule which is the subject of the test, e.g. the rule for which the AssertThat is created. */ private val rule: Rule, private val code: String, private val filePath: String?, private val kotlinScript: Boolean, private val editorConfigOverride: EditorConfigOverride = EditorConfigOverride.emptyEditorConfigOverride, - /** The rules which have to be executed in addition to the main rule when formatting the code. */ - private val additionalFormattingRules: List + /** + * The rules which have to be executed in addition to the main rule when linting/formatting the code. Note that + * lint errors for those rules are suppressed. + */ + private val additionalRules: List ) : AbstractAssert(code, KtLintAssertThatAssertable::class.java) { /** @@ -234,7 +248,7 @@ public class KtLintAssertThatAssertable( assertThat(lint()).isEmpty() // Also format the code to be absolutely sure that codes does not get changed - val actualFormattedCode = format(ignoreAdditionalRules = true) + val actualFormattedCode = format() assertThat(actualFormattedCode) .describedAs("Code is changed by format while no lint errors were found") @@ -252,9 +266,9 @@ public class KtLintAssertThatAssertable( * other, a unit test cal still verify that code is formatted correctly even when the rule under test is not * violated. */ - public fun hasNoLintViolationsExceptInAdditionalFormattingRules(): KtLintAssertThatAssertable { - check(additionalFormattingRules.isNotEmpty()) { - "hasNoLintViolationsExceptInAdditionalFormattingRules can only be used when additional formatting rules have been added" + public fun hasNoLintViolationsExceptInAdditionalRules(): KtLintAssertThatAssertable { + check(additionalRules.isNotEmpty()) { + "hasNoLintViolationsExceptInAdditionalRules can only be used when additional rules have been added" } assertThat(lint()).isEmpty() @@ -300,7 +314,7 @@ public class KtLintAssertThatAssertable( "Use '.hasNoLintErrors()' instead of '.isFormattedAs()'" } - val actualFormattedCode = format(false) + val actualFormattedCode = format() assertThat(actualFormattedCode) .describedAs("Code is formatted as") @@ -332,7 +346,7 @@ public class KtLintAssertThatAssertable( public fun hasLintViolationsWithoutAutocorrect(vararg expectedLintViolations: LintViolation) { check(expectedLintViolations.isNotEmpty()) - val actualLintViolationFields = lint(runFormatBeforeLint = true).toLintViolationsFieldsForCurrentRuleOnly() + val actualLintViolationFields = lint().toLintViolationsFieldsForCurrentRuleOnly() assertThat(actualLintViolationFields) .describedAs("Lint errors which can not be automatically corrected") @@ -361,38 +375,31 @@ public class KtLintAssertThatAssertable( ) }.toTypedArray() - private fun lint(runFormatBeforeLint: Boolean = false): List { - // Lint is only done with the rule for which the assertThat is created. In that way the unit test only has to - // check for violations caused by that rule. + private fun lint(): List { return listOf(rule) + // Also run the additional rules as the main rule might have a VisitorModifier which requires one or more of + // the additional rules to be loaded and enabled as well. + .plus(additionalRules) .lint( lintedFilePath = filePath, script = kotlinScript, - text = if (runFormatBeforeLint) { - format(false) - } else { - code - }, + text = code, editorConfigOverride = editorConfigOverride ) + // Remove all lint errors caused by the additional rule so that the unit test is only able to verify the + // lint errors caused by the main rule. + .filter { it.ruleId == rule.id } } - private fun format(ignoreAdditionalRules: Boolean): String { - val formattingRules = - if (ignoreAdditionalRules) { - listOf(rule) - } else { - // Formatting is done on the rule for which the assertThat is created plus the additional rules. In this way it - // is easier to test code which is formatted by closely related rules (for example wrapping and indent). - listOf(rule) + additionalFormattingRules - } - return formattingRules.format( - lintedFilePath = filePath, - script = kotlinScript, - text = code, - editorConfigOverride = editorConfigOverride - ) - } + private fun format(): String = + listOf(rule) + .plus(additionalRules) + .format( + lintedFilePath = filePath, + script = kotlinScript, + text = code, + editorConfigOverride = editorConfigOverride + ) /* Representation of the field of the [LintError] that should be identical. Note that no comparison can be made * against the original [LintError] as the [canBeAutoCorrected] flag is excluded from the hashcode. diff --git a/ktlint-test/src/main/kotlin/com/pinterest/ktlint/test/RuleExtension.kt b/ktlint-test/src/main/kotlin/com/pinterest/ktlint/test/RuleExtension.kt index 99d1694d9e..d7c0daf397 100644 --- a/ktlint-test/src/main/kotlin/com/pinterest/ktlint/test/RuleExtension.kt +++ b/ktlint-test/src/main/kotlin/com/pinterest/ktlint/test/RuleExtension.kt @@ -61,16 +61,10 @@ private fun List.toRuleSets(): List { ) ) } - return listOfNotNull( - dumpAstRuleSet, - RuleSet( - // RuleSet id is always set to "standard" as this has the side effect that the ruleset id will - // be excluded from the ruleId in the LintError which makes the unit tests of the experimental - // rules easier to maintain as they will not contain the reference to the ruleset id. - "standard", - *toTypedArray() - ) - ) + return this + .groupBy { it.id.substringBefore(":", "standard") } + .map { (ruleSetId, rules) -> RuleSet(ruleSetId, *rules.toTypedArray()) } + .plus(listOfNotNull(dumpAstRuleSet)) } /** @@ -233,10 +227,7 @@ public fun List.lint( experimentalParams, VisitorProvider( ruleSets = experimentalParams.ruleSets, - debug = experimentalParams.debug, - // When running unit tests, some VisitorModifiers have to be ignored. For example the RunAfterRule modifier - // should not be checked, if other that rule can only be tested together with the rule on which it depends. - isUnitTestContext = true + debug = experimentalParams.debug ) ) return res @@ -399,10 +390,7 @@ public fun List.format( experimentalParams, VisitorProvider( ruleSets = experimentalParams.ruleSets, - debug = experimentalParams.debug, - // When running unit tests, some VisitorModifiers have to be ignored. For example the RunAfterRule modifier - // should not be checked, if other that rule can only be tested together with the rule on which it depends. - isUnitTestContext = true + debug = experimentalParams.debug ) ) }