Files
SwiftLint/Tests/BuiltInRulesTests/PatternMatchingKeywordsRuleTests.swift
2026-05-24 19:23:51 -04:00

157 lines
5.5 KiB
Swift

@testable import SwiftLintBuiltInRules
import TestHelpers
import XCTest
final class PatternMatchingKeywordsRuleTests: SwiftLintTestCase {
func testViolationReasonForTuples() throws {
let config = try XCTUnwrap(makeConfig(nil, PatternMatchingKeywordsRule.identifier))
let example = Example("switch foo { case (let x, let y): break }")
let violations = violations(example, config: config)
XCTAssertEqual(violations.count, 2)
XCTAssertEqual(
violations.first?.reason,
PatternMatchingKeywordsRule.Reason.tuples
)
}
func testViolationReasonForEnumAssociatedValues() throws {
let config = try XCTUnwrap(makeConfig(nil, PatternMatchingKeywordsRule.identifier))
let example = Example("switch foo { case .bar(let x, let y): break }")
let violations = violations(example, config: config)
XCTAssertEqual(violations.count, 2)
XCTAssertEqual(
violations.first?.reason,
PatternMatchingKeywordsRule.Reason.enumAssociatedValues
)
}
func testRegressionExamples() {
let triggering = [
"switch foo { case (.yamlParsing(↓let x), .yamlParsing(↓let y)): break }",
"switch foo { case (.yamlParsing(↓var x), (.yamlParsing(↓var y), _)): break }",
"""
do {} catch Foo.outer(.inner(↓let x), .inner(↓let y)) {}
""",
]
let nonTriggering = [
"switch foo { case (.yamlParsing(var x), (.yamlParsing(var y), z)): break }",
"switch foo { case (foo, let x): break }",
"if case (foo, let x) = value {}",
]
verifyRule(
PatternMatchingKeywordsRule.description.with(
nonTriggeringExamples: nonTriggering.map { Example($0) },
triggeringExamples: triggering.map { Example($0) }
)
)
}
func testLabeledAssociatedValues() {
let triggering = [
"switch foo { case .foo(bar: ↓let lhs, baz: ↓let rhs): break }",
"switch foo { case .foo(bar: ↓var lhs, baz: ↓var rhs): break }",
"do {} catch .foo(bar: ↓let x, baz: ↓let y) {}",
]
let nonTriggering = [
"switch foo { case let .foo(bar: lhs, baz: rhs): break }",
"switch foo { case var .foo(bar: lhs, baz: rhs): break }",
"switch foo { case .foo(bar: existingValue, baz: let x): break }",
"switch foo { case .foo(bar: let x, baz: existingValue): break }",
"do {} catch let .foo(bar: x, baz: y) {}",
]
verifyRule(
PatternMatchingKeywordsRule.description.with(
nonTriggeringExamples: nonTriggering.map { Example($0) },
triggeringExamples: triggering.map { Example($0) }
)
)
}
func testSingleBindingDoesNotTrigger() {
let examples = [
"switch foo { case (let x, y): break }",
"switch foo { case .foo(let x, y): break }",
"switch foo { case (.foo(let x), y): break }",
]
verifyRule(
PatternMatchingKeywordsRule.description.with(
nonTriggeringExamples: examples.map { Example($0) }
)
)
}
func testNeutralElementsDoNotBlockLift() {
let examples = [
"switch foo { case (↓let x, ↓let y, _): break }",
"switch foo { case (↓let x, ↓let y, 1): break }",
"switch foo { case (↓let x, ↓let y, .foo): break }",
"switch foo { case (↓let x, ↓let y, s.t): break }",
"switch foo { case .foo(↓let x, ↓let y, _): break }",
"switch foo { case .foo(.bar(↓let x), .bar(↓let y), .baz): break }",
]
verifyRule(
PatternMatchingKeywordsRule.description.with(
triggeringExamples: examples.map { Example($0) }
)
)
}
func testThreeAlternativeMultiPatternCase() {
let triggering = [
"switch foo { case .foo(↓let x, ↓let y), .bar(↓let x, ↓let y), .baz(↓let x, ↓let y): break }",
]
let nonTriggering = [
"switch foo { case let .foo(x, y), let .bar(x, y), let .baz(x, y): break }",
]
verifyRule(
PatternMatchingKeywordsRule.description.with(
nonTriggeringExamples: nonTriggering.map { Example($0) },
triggeringExamples: triggering.map { Example($0) }
)
)
}
func testForCaseWithEnumAssociatedValues() {
let triggering = [
"for case .foo(↓let x, ↓let y) in values {}",
]
let nonTriggering = [
"for case let .foo(x, y) in values {}",
"for case .foo(existingValue, let x) in values {}",
]
verifyRule(
PatternMatchingKeywordsRule.description.with(
nonTriggeringExamples: nonTriggering.map { Example($0) },
triggeringExamples: triggering.map { Example($0) }
)
)
}
func testSanityChecksForNonInterestingPatterns() {
let examples = [
"switch foo { case _: break }",
"switch foo { case .foo: break }",
"switch foo { case 42: break }",
"switch foo { case existingValue: break }",
]
verifyRule(
PatternMatchingKeywordsRule.description.with(
nonTriggeringExamples: examples.map { Example($0) }
)
)
}
}