Files
SwiftLint/Tests/BuiltInRulesTests/NestingRuleTests.swift
Danny Mösch 15b285527a Separate built-in rule tests from framework tests (#5924)
* Short names for test modules
* Lint plugins and `Package.swift` in integration tests
* Simplify and merge file groups in Bazel
* Move common functions to `TestHelpers`
2024-12-30 12:26:46 +01:00

559 lines
19 KiB
Swift

@testable import SwiftLintBuiltInRules
import TestHelpers
// swiftlint:disable file_length
private let detectingTypes = ["actor", "class", "struct", "enum"]
// swiftlint:disable:next type_body_length
final class NestingRuleTests: SwiftLintTestCase {
// swiftlint:disable:next function_body_length
func testNestingWithAlwaysAllowOneTypeInFunctions() {
var nonTriggeringExamples = NestingRule.description.nonTriggeringExamples
nonTriggeringExamples.append(contentsOf: detectingTypes.flatMap { type -> [Example] in
[
.init("""
\(type) Example_0 {
\(type) Example_1 {
func f_0() {
\(type) Example_2 {}
}
}
}
"""),
.init("""
\(type) Example_0 {
\(type) Example_1 {
func f_0() {
\(type) Example_2 {
func f_1() {
\(type) Example_3 {}
}
}
}
}
}
"""),
.init("""
func f_0() {
\(type) Example_0 {
\(type) Example_1 {}
}
}
"""),
]
})
nonTriggeringExamples.append(contentsOf: detectingTypes.flatMap { type -> [Example] in
[
.init("""
exampleFunc(closure: {
\(type) Example_0 {
\(type) Example_1 {
func f_0() {
\(type) Example_2 {}
}
}
}
func f_0() {
\(type) Example_0 {
func f_1() {
\(type) Example_1 {
func f_2() {
\(type) Example_2 {}
}
}
}
}
}
})
"""),
.init("""
switch example {
case .exampleCase:
\(type) Example_0 {
\(type) Example_1 {
func f_0() {
\(type) Example_2 {}
}
}
}
default:
func f_0() {
\(type) Example_0 {
func f_1() {
\(type) Example_1 {
func f_2() {
\(type) Example_2 {}
}
}
}
}
}
}
"""),
]
})
var triggeringExamples = detectingTypes.flatMap { type -> [Example] in
[
.init("""
\(type) Example_0 {
\(type) Example_1 {
func f_0() {
\(type) Example_2 {
\(type) Example_3 {}
}
}
}
}
"""),
.init("""
\(type) Example_0 {
\(type) Example_1 {
func f_0() {
\(type) Example_2 {
func f_1() {
\(type) Example_3 {
\(type) Example_4 {}
}
}
}
}
}
}
"""),
.init("""
func f_0() {
\(type) Example_0 {
\(type) Example_1 {
\(type) Example_2 {}
}
}
}
"""),
]
}
// swiftlint:disable:next closure_body_length
triggeringExamples.append(contentsOf: detectingTypes.flatMap { type -> [Example] in
[
.init("""
exampleFunc(closure: {
\(type) Example_0 {
\(type) Example_1 {
func f_0() {
\(type) Example_2 {
\(type) Example_3 {}
}
}
}
}
func f_0() {
\(type) Example_0 {
func f_1() {
\(type) Example_1 {
func f_2() {
\(type) Example_2 {
\(type) Example_3 {}
}
}
}
}
}
}
})
"""),
.init("""
switch example {
case .exampleCase:
\(type) Example_0 {
\(type) Example_1 {
func f_0() {
\(type) Example_2 {
\(type) Example_3 {}
}
}
}
}
default:
func f_0() {
\(type) Example_0 {
func f_1() {
\(type) Example_1 {
func f_2() {
\(type) Example_2 {
\(type) Example_3 {}
}
}
}
}
}
}
}
"""),
]
})
let description = RuleDescription(
identifier: NestingRule.identifier,
name: NestingRule.description.name,
description: NestingRule.description.description,
kind: .metrics,
nonTriggeringExamples: nonTriggeringExamples,
triggeringExamples: triggeringExamples
)
verifyRule(description, ruleConfiguration: ["always_allow_one_type_in_functions": true])
}
// swiftlint:disable:next function_body_length
func testNestingWithoutCheckNestingInClosuresAndStatements() {
var nonTriggeringExamples = NestingRule.description.nonTriggeringExamples
// swiftlint:disable:next closure_body_length
nonTriggeringExamples.append(contentsOf: detectingTypes.flatMap { type -> [Example] in
[
.init("""
exampleFunc(closure: {
\(type) Example_0 {
\(type) Example_1 {
\(type) Example_2 {}
}
}
func f_0() {
func f_1() {
func f_2() {
func f_3() {}
}
}
}
})
"""),
.init("""
switch example {
case .exampleCase:
\(type) Example_0 {
\(type) Example_1 {
\(type) Example 2 {}
}
}
default:
func f_0() {
func f_1() {
func f_2() {
func f_3() {}
}
}
}
}
"""),
.init("""
for i in indicies {
\(type) Example_0 {
\(type) Example_1 {
\(type) Example 2 {}
}
}
func f_0() {
func f_1() {
func f_2() {
func f_3() {}
}
}
}
}
"""),
.init("""
while true {
\(type) Example_0 {
\(type) Example_1 {
\(type) Example 2 {}
}
}
func f_0() {
func f_1() {
func f_2() {
func f_3() {}
}
}
}
}
"""),
.init("""
repeat {
\(type) Example_0 {
\(type) Example_1 {
\(type) Example 2 {}
}
}
func f_0() {
func f_1() {
func f_2() {
func f_3() {}
}
}
}
} while true
"""),
.init("""
if flag {
\(type) Example_0 {
\(type) Example_1 {
\(type) Example 2 {}
}
}
func f_0() {
func f_1() {
func f_2() {
func f_3() {}
}
}
}
}
"""),
.init("""
guard flag else {
\(type) Example_0 {
\(type) Example_1 {
\(type) Example 2 {}
}
}
func f_0() {
func f_1() {
func f_2() {
func f_3() {}
}
}
}
return
}
"""),
.init("""
defer {
\(type) Example_0 {
\(type) Example_1 {
\(type) Example 2 {}
}
}
func f_0() {
func f_1() {
func f_2() {
func f_3() {}
}
}
}
}
"""),
.init("""
do {
\(type) Example_0 {
\(type) Example_1 {
\(type) Example 2 {}
}
}
func f_0() {
func f_1() {
func f_2() {
func f_3() {}
}
}
}
} catch {
\(type) Example_0 {
\(type) Example_1 {
\(type) Example 2 {}
}
}
func f_0() {
func f_1() {
func f_2() {
func f_3() {}
}
}
}
}
"""),
]
})
// swiftlint:disable:next closure_body_length
var triggeringExamples = detectingTypes.flatMap { type -> [Example] in
[
.init("""
\(type) Example_0 {
\(type) Example_1 {
\(type) Example_2 {}
}
}
"""),
.init("""
var example: Int {
\(type) Example_0 {
\(type) Example_1 {
\(type) Example_2 {}
}
}
return 5
}
"""),
.init("""
var example: Int = 5 {
didSet {
\(type) Example_0 {
\(type) Example_1 {
\(type) Example_2 {}
}
}
}
}
"""),
.init("""
extension Example_0 {
\(type) Example_1 {
\(type) Example_2 {}
}
}
"""),
.init("""
\(type) Example_0 {
func f_0() {
\(type) Example_1 {
func f_1() {
func f_2() {
\(type) Example_2 {}
↓func f_3() {}
}
}
}
}
}
"""),
]
}
triggeringExamples.append(contentsOf: [
.init("""
func f_0() {
func f_1() {
func f_2() {
↓func f_3() {}
}
}
}
"""),
.init("""
var example: Int {
func f_0() {
func f_1() {
func f_2() {
↓func f_3() {}
}
}
}
return 5
}
"""),
.init("""
var example: Int = 5 {
didSet {
func f_0() {
func f_1() {
func f_2() {
↓func f_3() {}
}
}
}
}
}
"""),
.init("""
extension Example_0 {
func f_0() {
func f_1() {
func f_2() {
↓func f_3() {}
}
}
}
}
"""),
])
let description = RuleDescription(
identifier: NestingRule.identifier,
name: NestingRule.description.name,
description: NestingRule.description.description,
kind: .metrics,
nonTriggeringExamples: nonTriggeringExamples,
triggeringExamples: triggeringExamples
)
verifyRule(description, ruleConfiguration: ["check_nesting_in_closures_and_statements": false])
}
func testNestingWithoutTypealiasAndAssociatedtype() {
var nonTriggeringExamples = NestingRule.description.nonTriggeringExamples
nonTriggeringExamples.append(contentsOf: detectingTypes.flatMap { type -> [Example] in
[
.init("""
\(type) Example_0 {
\(type) Example_1 {
typealias Example_2_Type = Example_2.Type
}
\(type) Example_2 {}
}
"""),
.init("""
protocol Example_Protcol {
associatedtype AssociatedType
}
\(type) Example_1 {
\(type) Example_2: Example_Protcol {
typealias AssociatedType = Int
}
}
"""),
.init("""
protocol Example_Protcol {
associatedtype AssociatedType
}
\(type) Example_1 {
\(type) Example_2: SomeProtcol {
typealias Example_2_Type = Example_2.Type
}
\(type) Example_3: Example_Protcol {
typealias AssociatedType = Int
}
}
"""),
]
})
let description = NestingRule.description.with(nonTriggeringExamples: nonTriggeringExamples)
verifyRule(description, ruleConfiguration: ["ignore_typealiases_and_associatedtypes": true])
}
}