mirror of
https://github.com/realm/SwiftLint.git
synced 2026-05-07 20:12:49 +00:00
Adopt Swift Testing
This commit is contained in:
@@ -9,6 +9,7 @@ build:macos --crosstool_top=@local_config_apple_cc//:toolchain
|
||||
build:macos --host_crosstool_top=@local_config_apple_cc//:toolchain
|
||||
|
||||
build --macos_minimum_os=13.5 --host_macos_minimum_os=13.5
|
||||
test --macos_minimum_os=14.8 --host_macos_minimum_os=14.8 # Swift Testing libraries are compiled for macOS 14+.
|
||||
build --disk_cache=~/.bazel_cache
|
||||
build --experimental_remote_cache_compression
|
||||
build --remote_build_event_upload=minimal
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"indentation" : {
|
||||
"spaces" : 4
|
||||
},
|
||||
"lineLength": 120,
|
||||
"rules" : {
|
||||
"NoAccessLevelOnExtensionDeclaration": false
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
6.2
|
||||
@@ -73,6 +73,7 @@ file_name:
|
||||
- RuleConfigurationMacros.swift
|
||||
- SwiftSyntax+SwiftLint.swift
|
||||
- TestHelpers.swift
|
||||
- Traits.swift
|
||||
excluded_paths:
|
||||
- Tests/GeneratedTests/GeneratedTests_\d\d\.swift
|
||||
- Tests/FileSystemAccessTests/.+\.swift
|
||||
|
||||
@@ -78,13 +78,13 @@ public macro SwiftSyntaxRule(foldExpressions: Bool = false,
|
||||
)
|
||||
|
||||
@attached(body)
|
||||
macro TemporaryDirectory() = #externalMacro(
|
||||
package macro TemporaryDirectory() = #externalMacro(
|
||||
module: "SwiftLintCoreMacros",
|
||||
type: "TemporaryDirectory"
|
||||
)
|
||||
|
||||
@attached(body)
|
||||
macro WorkingDirectory(path: String) = #externalMacro(
|
||||
package macro WorkingDirectory(path: String) = #externalMacro(
|
||||
module: "SwiftLintCoreMacros",
|
||||
type: "WorkingDirectory"
|
||||
)
|
||||
|
||||
@@ -21,7 +21,7 @@ enum DisabledWithoutSourceKit: ExtensionMacro {
|
||||
try ExtensionDeclSyntax("""
|
||||
extension \(type) {
|
||||
private static let postMessage: Void = {
|
||||
Issue.genericWarning(\(raw: message)).print()
|
||||
SwiftLintCore.Issue.genericWarning(\(raw: message)).print()
|
||||
}()
|
||||
|
||||
func notifyRuleDisabledOnce() {
|
||||
|
||||
@@ -49,7 +49,7 @@ enum AutoConfigParser: MemberMacro {
|
||||
}
|
||||
}
|
||||
return [
|
||||
DeclSyntax(try FunctionDeclSyntax("mutating func apply(configuration: Any) throws(Issue)") {
|
||||
DeclSyntax(try FunctionDeclSyntax("mutating func apply(configuration: Any) throws(SwiftLintCore.Issue)") {
|
||||
for option in nonInlinedOptions {
|
||||
"""
|
||||
if $\(raw: option).key.isEmpty {
|
||||
@@ -61,7 +61,7 @@ enum AutoConfigParser: MemberMacro {
|
||||
"""
|
||||
do {
|
||||
try \(raw: option).apply(configuration, ruleID: Parent.identifier)
|
||||
} catch let issue where issue == Issue.nothingApplied(ruleID: Parent.identifier) {
|
||||
} catch let issue where issue == SwiftLintCore.Issue.nothingApplied(ruleID: Parent.identifier) {
|
||||
// Acceptable. Continue.
|
||||
}
|
||||
"""
|
||||
@@ -83,7 +83,10 @@ enum AutoConfigParser: MemberMacro {
|
||||
"""
|
||||
if !supportedKeys.isSuperset(of: configuration.keys) {
|
||||
let unknownKeys = Set(configuration.keys).subtracting(supportedKeys)
|
||||
Issue.invalidConfigurationKeys(ruleID: Parent.identifier, keys: unknownKeys).print()
|
||||
SwiftLintCore.Issue.invalidConfigurationKeys(
|
||||
ruleID: Parent.identifier,
|
||||
keys: unknownKeys
|
||||
).print()
|
||||
}
|
||||
"""
|
||||
"""
|
||||
@@ -115,7 +118,7 @@ enum AcceptableByConfigurationElement: ExtensionMacro {
|
||||
try ExtensionDeclSyntax("""
|
||||
extension \(type): AcceptableByConfigurationElement {
|
||||
\(raw: accessLevel)func asOption() -> OptionType { .symbol(rawValue) }
|
||||
\(raw: accessLevel)init(fromAny value: Any, context ruleID: String) throws(Issue) {
|
||||
\(raw: accessLevel)init(fromAny value: Any, context ruleID: String) throws(SwiftLintCore.Issue) {
|
||||
if let value = value as? String, let newSelf = Self(rawValue: value) {
|
||||
self = newSelf
|
||||
} else {
|
||||
|
||||
@@ -125,6 +125,12 @@ package struct LintOrAnalyzeOptions {
|
||||
package struct LintOrAnalyzeCommand {
|
||||
package static func run(_ options: LintOrAnalyzeOptions) async throws {
|
||||
if let workingDirectory = options.workingDirectory {
|
||||
let currentDirectory = FileManager.default.currentDirectoryPath
|
||||
defer {
|
||||
if !FileManager.default.changeCurrentDirectoryPath(currentDirectory) {
|
||||
queuedFatalError("Could not change back to the original directory '\(currentDirectory)'.")
|
||||
}
|
||||
}
|
||||
if !FileManager.default.changeCurrentDirectoryPath(workingDirectory) {
|
||||
throw SwiftLintError.usageError(
|
||||
description: """
|
||||
|
||||
@@ -134,9 +134,11 @@ private extension SwiftLintDev.Rules.Register {
|
||||
// swiftlint:disable:next blanket_disable_command superfluous_disable_command
|
||||
// swiftlint:disable single_test_class type_name
|
||||
|
||||
import TestHelpers
|
||||
import Testing
|
||||
|
||||
@testable import SwiftLintBuiltInRules
|
||||
@testable import SwiftLintCore
|
||||
import TestHelpers
|
||||
|
||||
\(testClassesString)
|
||||
|
||||
@@ -189,8 +191,10 @@ private extension SwiftLintDev.Rules.Register {
|
||||
let shardRules = rulesContext.shardRules(forIndex: shardIndex)
|
||||
|
||||
let testClasses = shardRules.map { testName in """
|
||||
final class \(testName)GeneratedTests: SwiftLintTestCase {
|
||||
func testWithDefaultConfiguration() {
|
||||
@Suite(.rulesRegistered)
|
||||
struct \(testName)GeneratedTests {
|
||||
@Test
|
||||
func withDefaultConfiguration() {
|
||||
verifyRule(\(testName).description)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,22 +1,28 @@
|
||||
@testable import SwiftLintBuiltInRules
|
||||
import TestHelpers
|
||||
import Testing
|
||||
|
||||
final class AttributesRuleTests: SwiftLintTestCase {
|
||||
func testAttributesWithAlwaysOnSameLine() {
|
||||
@testable import SwiftLintBuiltInRules
|
||||
|
||||
@Suite(.rulesRegistered)
|
||||
struct AttributesRuleTests {
|
||||
@Test
|
||||
func attributesWithAlwaysOnSameLine() {
|
||||
// Test with custom `always_on_same_line`
|
||||
let nonTriggeringExamples = [
|
||||
Example("@objc var x: String"),
|
||||
Example("@objc func foo()"),
|
||||
Example("@nonobjc\n func foo()"),
|
||||
Example("""
|
||||
class Foo {
|
||||
@objc private var object: RLMWeakObjectHandle?
|
||||
@objc private var property: RLMProperty?
|
||||
}
|
||||
"""),
|
||||
Example("""
|
||||
@objc(XYZFoo) class Foo: NSObject {}
|
||||
"""),
|
||||
Example(
|
||||
"""
|
||||
class Foo {
|
||||
@objc private var object: RLMWeakObjectHandle?
|
||||
@objc private var property: RLMProperty?
|
||||
}
|
||||
"""),
|
||||
Example(
|
||||
"""
|
||||
@objc(XYZFoo) class Foo: NSObject {}
|
||||
"""),
|
||||
]
|
||||
let triggeringExamples = [
|
||||
Example("@objc\n ↓var x: String"),
|
||||
@@ -28,11 +34,13 @@ final class AttributesRuleTests: SwiftLintTestCase {
|
||||
.with(triggeringExamples: triggeringExamples)
|
||||
.with(nonTriggeringExamples: nonTriggeringExamples)
|
||||
|
||||
verifyRule(alwaysOnSameLineDescription,
|
||||
ruleConfiguration: ["always_on_same_line": ["@objc"]])
|
||||
verifyRule(
|
||||
alwaysOnSameLineDescription,
|
||||
ruleConfiguration: ["always_on_same_line": ["@objc"]])
|
||||
}
|
||||
|
||||
func testAttributesWithAlwaysOnLineAbove() {
|
||||
@Test
|
||||
func attributesWithAlwaysOnLineAbove() {
|
||||
// Test with custom `always_on_line_above`
|
||||
let nonTriggeringExamples = [
|
||||
Example("@objc\n var x: String"),
|
||||
@@ -49,43 +57,49 @@ final class AttributesRuleTests: SwiftLintTestCase {
|
||||
.with(triggeringExamples: triggeringExamples)
|
||||
.with(nonTriggeringExamples: nonTriggeringExamples)
|
||||
|
||||
verifyRule(alwaysOnNewLineDescription,
|
||||
ruleConfiguration: ["always_on_line_above": ["@objc"]])
|
||||
verifyRule(
|
||||
alwaysOnNewLineDescription,
|
||||
ruleConfiguration: ["always_on_line_above": ["@objc"]])
|
||||
}
|
||||
|
||||
func testAttributesWithAttributesOnLineAboveButOnOtherDeclaration() {
|
||||
@Test
|
||||
func attributesWithAttributesOnLineAboveButOnOtherDeclaration() {
|
||||
let nonTriggeringExamples = [
|
||||
Example("""
|
||||
@IBDesignable open class TagListView: UIView {
|
||||
@IBInspectable open dynamic var textColor: UIColor = UIColor.white {
|
||||
didSet {}
|
||||
Example(
|
||||
"""
|
||||
@IBDesignable open class TagListView: UIView {
|
||||
@IBInspectable open dynamic var textColor: UIColor = UIColor.white {
|
||||
didSet {}
|
||||
}
|
||||
}
|
||||
}
|
||||
"""),
|
||||
Example("""
|
||||
@objc public protocol TagListViewDelegate {
|
||||
@objc optional func tagDidSelect(_ title: String, sender: TagListView)
|
||||
@objc optional func tagDidDeselect(_ title: String, sender: TagListView)
|
||||
}
|
||||
"""),
|
||||
"""),
|
||||
Example(
|
||||
"""
|
||||
@objc public protocol TagListViewDelegate {
|
||||
@objc optional func tagDidSelect(_ title: String, sender: TagListView)
|
||||
@objc optional func tagDidDeselect(_ title: String, sender: TagListView)
|
||||
}
|
||||
"""),
|
||||
]
|
||||
|
||||
let triggeringExamples = [
|
||||
Example("""
|
||||
@IBDesignable open class TagListView: UIView {
|
||||
@IBInspectable
|
||||
open dynamic ↓var textColor: UIColor = UIColor.white {
|
||||
didSet {}
|
||||
Example(
|
||||
"""
|
||||
@IBDesignable open class TagListView: UIView {
|
||||
@IBInspectable
|
||||
open dynamic ↓var textColor: UIColor = UIColor.white {
|
||||
didSet {}
|
||||
}
|
||||
}
|
||||
}
|
||||
"""),
|
||||
Example("""
|
||||
@objc public protocol TagListViewDelegate {
|
||||
@objc
|
||||
optional ↓func tagDidSelect(_ title: String, sender: TagListView)
|
||||
@objc optional func tagDidDeselect(_ title: String, sender: TagListView)
|
||||
}
|
||||
"""),
|
||||
"""),
|
||||
Example(
|
||||
"""
|
||||
@objc public protocol TagListViewDelegate {
|
||||
@objc
|
||||
optional ↓func tagDidSelect(_ title: String, sender: TagListView)
|
||||
@objc optional func tagDidDeselect(_ title: String, sender: TagListView)
|
||||
}
|
||||
"""),
|
||||
]
|
||||
|
||||
let alwaysOnNewLineDescription = AttributesRule.description
|
||||
@@ -102,26 +116,29 @@ final class AttributesRuleTests: SwiftLintTestCase {
|
||||
)
|
||||
}
|
||||
|
||||
func testAttributesWithArgumentsAlwaysOnLineAboveFalse() {
|
||||
@Test
|
||||
func attributesWithArgumentsAlwaysOnLineAboveFalse() {
|
||||
let nonTriggeringExamples = [
|
||||
Example("@Environment(\\.presentationMode) private var presentationMode")
|
||||
]
|
||||
let triggeringExamples = [
|
||||
Example("""
|
||||
@Environment(\\.presentationMode)
|
||||
private ↓var presentationMode
|
||||
"""),
|
||||
@Environment(\\.presentationMode)
|
||||
private ↓var presentationMode
|
||||
"""),
|
||||
]
|
||||
|
||||
let argumentsAlwaysOnLineDescription = AttributesRule.description
|
||||
.with(triggeringExamples: triggeringExamples)
|
||||
.with(nonTriggeringExamples: nonTriggeringExamples)
|
||||
|
||||
verifyRule(argumentsAlwaysOnLineDescription,
|
||||
ruleConfiguration: ["attributes_with_arguments_always_on_line_above": false])
|
||||
verifyRule(
|
||||
argumentsAlwaysOnLineDescription,
|
||||
ruleConfiguration: ["attributes_with_arguments_always_on_line_above": false])
|
||||
}
|
||||
|
||||
func testAttributesWithArgumentsAlwaysOnLineAboveTrue() {
|
||||
@Test
|
||||
func attributesWithArgumentsAlwaysOnLineAboveTrue() {
|
||||
let nonTriggeringExamples = [
|
||||
Example("@Environment(\\.presentationMode)\nprivate var presentationMode")
|
||||
]
|
||||
@@ -133,7 +150,8 @@ final class AttributesRuleTests: SwiftLintTestCase {
|
||||
.with(triggeringExamples: triggeringExamples)
|
||||
.with(nonTriggeringExamples: nonTriggeringExamples)
|
||||
|
||||
verifyRule(argumentsAlwaysOnLineDescription,
|
||||
ruleConfiguration: ["attributes_with_arguments_always_on_line_above": true])
|
||||
verifyRule(
|
||||
argumentsAlwaysOnLineDescription,
|
||||
ruleConfiguration: ["attributes_with_arguments_always_on_line_above": true])
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,15 +1,18 @@
|
||||
@testable import SwiftLintBuiltInRules
|
||||
import TestHelpers
|
||||
import XCTest
|
||||
import Testing
|
||||
|
||||
final class BlanketDisableCommandRuleTests: SwiftLintTestCase {
|
||||
private lazy var emptyDescription = BlanketDisableCommandRule.description
|
||||
@testable import SwiftLintBuiltInRules
|
||||
|
||||
@Suite(.rulesRegistered)
|
||||
struct BlanketDisableCommandRuleTests {
|
||||
private static let emptyDescription = BlanketDisableCommandRule.description
|
||||
.with(triggeringExamples: [])
|
||||
.with(nonTriggeringExamples: [])
|
||||
|
||||
func testAlwaysBlanketDisable() {
|
||||
@Test
|
||||
func alwaysBlanketDisable() {
|
||||
let nonTriggeringExamples = [Example("// swiftlint:disable file_length\n// swiftlint:enable file_length")]
|
||||
verifyRule(emptyDescription.with(nonTriggeringExamples: nonTriggeringExamples))
|
||||
verifyRule(Self.emptyDescription.with(nonTriggeringExamples: nonTriggeringExamples))
|
||||
|
||||
let triggeringExamples = [
|
||||
Example("// swiftlint:disable file_length\n// swiftlint:enable ↓file_length"),
|
||||
@@ -17,23 +20,27 @@ final class BlanketDisableCommandRuleTests: SwiftLintTestCase {
|
||||
Example("// swiftlint:disable:this ↓file_length"),
|
||||
Example("// swiftlint:disable:next ↓file_length"),
|
||||
]
|
||||
verifyRule(emptyDescription.with(triggeringExamples: triggeringExamples),
|
||||
ruleConfiguration: ["always_blanket_disable": ["file_length"]],
|
||||
skipCommentTests: true, skipDisableCommandTests: true)
|
||||
verifyRule(
|
||||
Self.emptyDescription.with(triggeringExamples: triggeringExamples),
|
||||
ruleConfiguration: ["always_blanket_disable": ["file_length"]],
|
||||
skipCommentTests: true, skipDisableCommandTests: true)
|
||||
}
|
||||
|
||||
func testAlwaysBlanketDisabledAreAllowed() {
|
||||
@Test
|
||||
func alwaysBlanketDisabledAreAllowed() {
|
||||
let nonTriggeringExamples = [Example("// swiftlint:disable identifier_name\n")]
|
||||
verifyRule(emptyDescription.with(nonTriggeringExamples: nonTriggeringExamples),
|
||||
ruleConfiguration: ["always_blanket_disable": ["identifier_name"], "allowed_rules": []],
|
||||
skipDisableCommandTests: true)
|
||||
verifyRule(
|
||||
Self.emptyDescription.with(nonTriggeringExamples: nonTriggeringExamples),
|
||||
ruleConfiguration: ["always_blanket_disable": ["identifier_name"], "allowed_rules": []],
|
||||
skipDisableCommandTests: true)
|
||||
}
|
||||
|
||||
func testAllowedRules() {
|
||||
@Test
|
||||
func allowedRules() {
|
||||
let nonTriggeringExamples = [
|
||||
Example("// swiftlint:disable file_length"),
|
||||
Example("// swiftlint:disable single_test_class"),
|
||||
]
|
||||
verifyRule(emptyDescription.with(nonTriggeringExamples: nonTriggeringExamples))
|
||||
verifyRule(Self.emptyDescription.with(nonTriggeringExamples: nonTriggeringExamples))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,33 +1,42 @@
|
||||
@testable import SwiftLintBuiltInRules
|
||||
import TestHelpers
|
||||
import XCTest
|
||||
import Testing
|
||||
|
||||
final class ChildOptionSeverityConfigurationTests: SwiftLintTestCase {
|
||||
@testable import SwiftLintBuiltInRules
|
||||
|
||||
@Suite(.rulesRegistered)
|
||||
struct ChildOptionSeverityConfigurationTests {
|
||||
typealias TesteeType = ChildOptionSeverityConfiguration<RuleMock>
|
||||
|
||||
func testSeverity() {
|
||||
XCTAssertNil(TesteeType.off.severity)
|
||||
XCTAssertEqual(TesteeType.warning.severity, .warning)
|
||||
XCTAssertEqual(TesteeType.error.severity, .error)
|
||||
@Test
|
||||
func severity() {
|
||||
#expect(TesteeType.off.severity == nil)
|
||||
#expect(TesteeType.warning.severity == .warning)
|
||||
#expect(TesteeType.error.severity == .error)
|
||||
}
|
||||
|
||||
func testFromConfig() throws {
|
||||
@Test
|
||||
func fromConfig() throws {
|
||||
var testee = TesteeType.off
|
||||
|
||||
try testee.apply(configuration: "warning")
|
||||
XCTAssertEqual(testee, .warning)
|
||||
#expect(testee == .warning)
|
||||
|
||||
try testee.apply(configuration: "error")
|
||||
XCTAssertEqual(testee, .error)
|
||||
#expect(testee == .error)
|
||||
|
||||
try testee.apply(configuration: "off")
|
||||
XCTAssertEqual(testee, .off)
|
||||
#expect(testee == .off)
|
||||
}
|
||||
|
||||
func testInvalidConfig() {
|
||||
@Test
|
||||
func invalidConfig() {
|
||||
var testee = TesteeType.off
|
||||
|
||||
XCTAssertThrowsError(try testee.apply(configuration: "no"))
|
||||
XCTAssertThrowsError(try testee.apply(configuration: 1))
|
||||
#expect(throws: (any Error).self) {
|
||||
try testee.apply(configuration: "no")
|
||||
}
|
||||
#expect(throws: (any Error).self) {
|
||||
try testee.apply(configuration: 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
@testable import SwiftLintBuiltInRules
|
||||
import TestHelpers
|
||||
import Testing
|
||||
|
||||
final class CollectionAlignmentRuleTests: SwiftLintTestCase {
|
||||
func testCollectionAlignmentWithAlignLeft() {
|
||||
@testable import SwiftLintBuiltInRules
|
||||
|
||||
@Suite(.rulesRegistered)
|
||||
struct CollectionAlignmentRuleTests {
|
||||
@Test
|
||||
func collectionAlignmentWithAlignLeft() {
|
||||
let baseDescription = CollectionAlignmentRule.description
|
||||
let examples = CollectionAlignmentRule.Examples(alignColons: false)
|
||||
|
||||
@@ -12,7 +16,8 @@ final class CollectionAlignmentRuleTests: SwiftLintTestCase {
|
||||
verifyRule(description)
|
||||
}
|
||||
|
||||
func testCollectionAlignmentWithAlignColons() {
|
||||
@Test
|
||||
func collectionAlignmentWithAlignColons() {
|
||||
let baseDescription = CollectionAlignmentRule.description
|
||||
let examples = CollectionAlignmentRule.Examples(alignColons: true)
|
||||
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
@testable import SwiftLintBuiltInRules
|
||||
import TestHelpers
|
||||
import Testing
|
||||
|
||||
final class ColonRuleTests: SwiftLintTestCase {
|
||||
func testColonWithFlexibleRightSpace() {
|
||||
@testable import SwiftLintBuiltInRules
|
||||
|
||||
@Suite(.rulesRegistered)
|
||||
struct ColonRuleTests {
|
||||
@Test
|
||||
func colonWithFlexibleRightSpace() {
|
||||
// Verify Colon rule with test values for when flexible_right_spacing
|
||||
// is true.
|
||||
let nonTriggeringExamples = ColonRule.description.nonTriggeringExamples + [
|
||||
@@ -68,7 +72,8 @@ final class ColonRuleTests: SwiftLintTestCase {
|
||||
verifyRule(description, ruleConfiguration: ["flexible_right_spacing": true])
|
||||
}
|
||||
|
||||
func testColonWithoutApplyToDictionaries() {
|
||||
@Test
|
||||
func colonWithoutApplyToDictionaries() {
|
||||
let nonTriggeringExamples = ColonRule.description.nonTriggeringExamples + [
|
||||
Example("let abc = [Void:Void]()\n"),
|
||||
Example("let abc = [Void : Void]()\n"),
|
||||
|
||||
@@ -1,22 +1,20 @@
|
||||
@testable import SwiftLintBuiltInRules
|
||||
import TestHelpers
|
||||
import XCTest
|
||||
import Testing
|
||||
|
||||
final class CompilerProtocolInitRuleTests: SwiftLintTestCase {
|
||||
@testable import SwiftLintBuiltInRules
|
||||
|
||||
@Suite(.rulesRegistered)
|
||||
struct CompilerProtocolInitRuleTests {
|
||||
private let ruleID = CompilerProtocolInitRule.identifier
|
||||
|
||||
func testViolationMessageForExpressibleByIntegerLiteral() throws {
|
||||
let config = try XCTUnwrap(makeConfig(nil, ruleID))
|
||||
@Test
|
||||
func violationMessageForExpressibleByIntegerLiteral() throws {
|
||||
let config = try #require(makeConfig(nil, ruleID))
|
||||
let allViolations = violations(Example("let a = NSNumber(integerLiteral: 1)"), config: config)
|
||||
|
||||
let compilerProtocolInitViolation = allViolations.first { $0.ruleIdentifier == ruleID }
|
||||
let violation = try XCTUnwrap(
|
||||
compilerProtocolInitViolation,
|
||||
"A compiler protocol init violation should have been triggered!"
|
||||
)
|
||||
XCTAssertEqual(
|
||||
violation.reason,
|
||||
"Initializers declared in compiler protocol ExpressibleByIntegerLiteral shouldn't be called directly"
|
||||
let violation = try #require(allViolations.first { $0.ruleIdentifier == ruleID })
|
||||
#expect(
|
||||
violation.reason
|
||||
== "Initializers declared in compiler protocol ExpressibleByIntegerLiteral shouldn't be called directly"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
@testable import SwiftLintBuiltInRules
|
||||
import TestHelpers
|
||||
import XCTest
|
||||
import Testing
|
||||
|
||||
final class ComputedAccessorsOrderRuleTests: SwiftLintTestCase {
|
||||
func testSetGetConfiguration() {
|
||||
@testable import SwiftLintBuiltInRules
|
||||
|
||||
@Suite(.rulesRegistered)
|
||||
struct ComputedAccessorsOrderRuleTests {
|
||||
@Test
|
||||
func setGetConfiguration() {
|
||||
let nonTriggeringExamples = [
|
||||
Example("""
|
||||
class Foo {
|
||||
@@ -40,7 +43,8 @@ final class ComputedAccessorsOrderRuleTests: SwiftLintTestCase {
|
||||
verifyRule(description, ruleConfiguration: ["order": "set_get"])
|
||||
}
|
||||
|
||||
func testGetSetPropertyReason() {
|
||||
@Test
|
||||
func getSetPropertyReason() {
|
||||
let example = Example("""
|
||||
class Foo {
|
||||
var foo: Int {
|
||||
@@ -54,13 +58,14 @@ final class ComputedAccessorsOrderRuleTests: SwiftLintTestCase {
|
||||
}
|
||||
""")
|
||||
|
||||
XCTAssertEqual(
|
||||
ruleViolations(example).first?.reason,
|
||||
"Computed properties should first declare the getter and then the setter"
|
||||
#expect(
|
||||
ruleViolations(example).first?.reason
|
||||
== "Computed properties should first declare the getter and then the setter"
|
||||
)
|
||||
}
|
||||
|
||||
func testGetSetSubscriptReason() {
|
||||
@Test
|
||||
func getSetSubscriptReason() {
|
||||
let example = Example("""
|
||||
class Foo {
|
||||
subscript(i: Int) -> Int {
|
||||
@@ -74,13 +79,14 @@ final class ComputedAccessorsOrderRuleTests: SwiftLintTestCase {
|
||||
}
|
||||
""")
|
||||
|
||||
XCTAssertEqual(
|
||||
ruleViolations(example).first?.reason,
|
||||
"Computed subscripts should first declare the getter and then the setter"
|
||||
#expect(
|
||||
ruleViolations(example).first?.reason
|
||||
== "Computed subscripts should first declare the getter and then the setter"
|
||||
)
|
||||
}
|
||||
|
||||
func testSetGetPropertyReason() {
|
||||
@Test
|
||||
func setGetPropertyReason() {
|
||||
let example = Example("""
|
||||
class Foo {
|
||||
var foo: Int {
|
||||
@@ -94,13 +100,14 @@ final class ComputedAccessorsOrderRuleTests: SwiftLintTestCase {
|
||||
}
|
||||
""")
|
||||
|
||||
XCTAssertEqual(
|
||||
ruleViolations(example, ruleConfiguration: ["order": "set_get"]).first?.reason,
|
||||
"Computed properties should first declare the setter and then the getter"
|
||||
#expect(
|
||||
ruleViolations(example, ruleConfiguration: ["order": "set_get"]).first?.reason
|
||||
== "Computed properties should first declare the setter and then the getter"
|
||||
)
|
||||
}
|
||||
|
||||
func testSetGetSubscriptReason() {
|
||||
@Test
|
||||
func setGetSubscriptReason() {
|
||||
let example = Example("""
|
||||
class Foo {
|
||||
subscript(i: Int) -> Int {
|
||||
@@ -114,9 +121,9 @@ final class ComputedAccessorsOrderRuleTests: SwiftLintTestCase {
|
||||
}
|
||||
""")
|
||||
|
||||
XCTAssertEqual(
|
||||
ruleViolations(example, ruleConfiguration: ["order": "set_get"]).first?.reason,
|
||||
"Computed subscripts should first declare the setter and then the getter"
|
||||
#expect(
|
||||
ruleViolations(example, ruleConfiguration: ["order": "set_get"]).first?.reason
|
||||
== "Computed subscripts should first declare the setter and then the getter"
|
||||
)
|
||||
}
|
||||
|
||||
@@ -124,7 +131,6 @@ final class ComputedAccessorsOrderRuleTests: SwiftLintTestCase {
|
||||
guard let config = makeConfig(ruleConfiguration, ComputedAccessorsOrderRule.identifier) else {
|
||||
return []
|
||||
}
|
||||
|
||||
return violations(example, config: config)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
@testable import SwiftLintBuiltInRules
|
||||
import TestHelpers
|
||||
import Testing
|
||||
|
||||
final class ConditionalReturnsOnNewlineRuleTests: SwiftLintTestCase {
|
||||
func testConditionalReturnsOnNewlineWithIfOnly() {
|
||||
@testable import SwiftLintBuiltInRules
|
||||
|
||||
@Suite(.rulesRegistered)
|
||||
struct ConditionalReturnsOnNewlineRuleTests {
|
||||
@Test
|
||||
func conditionalReturnsOnNewlineWithIfOnly() {
|
||||
// Test with `if_only` set to true
|
||||
let nonTriggeringExamples = [
|
||||
Example("guard true else {\n return true\n}"),
|
||||
|
||||
@@ -1,22 +1,26 @@
|
||||
@testable import SwiftLintBuiltInRules
|
||||
import TestHelpers
|
||||
import XCTest
|
||||
import Testing
|
||||
|
||||
final class ContainsOverFirstNotNilRuleTests: SwiftLintTestCase {
|
||||
func testFirstReason() {
|
||||
@testable import SwiftLintBuiltInRules
|
||||
|
||||
@Suite(.rulesRegistered)
|
||||
struct ContainsOverFirstNotNilRuleTests {
|
||||
@Test
|
||||
func firstReason() {
|
||||
let example = Example("↓myList.first { $0 % 2 == 0 } != nil")
|
||||
let violations = self.violations(example)
|
||||
|
||||
XCTAssertEqual(violations.count, 1)
|
||||
XCTAssertEqual(violations.first?.reason, "Prefer `contains` over `first(where:) != nil`")
|
||||
#expect(violations.count == 1)
|
||||
#expect(violations.first?.reason == "Prefer `contains` over `first(where:) != nil`")
|
||||
}
|
||||
|
||||
func testFirstIndexReason() {
|
||||
@Test
|
||||
func firstIndexReason() {
|
||||
let example = Example("↓myList.firstIndex { $0 % 2 == 0 } != nil")
|
||||
let violations = self.violations(example)
|
||||
|
||||
XCTAssertEqual(violations.count, 1)
|
||||
XCTAssertEqual(violations.first?.reason, "Prefer `contains` over `firstIndex(where:) != nil`")
|
||||
#expect(violations.count == 1)
|
||||
#expect(violations.first?.reason == "Prefer `contains` over `firstIndex(where:) != nil`")
|
||||
}
|
||||
|
||||
// MARK: - Private
|
||||
@@ -25,7 +29,6 @@ final class ContainsOverFirstNotNilRuleTests: SwiftLintTestCase {
|
||||
guard let config = makeConfig(config, ContainsOverFirstNotNilRule.identifier) else {
|
||||
return []
|
||||
}
|
||||
|
||||
return TestHelpers.violations(example, config: config)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,34 +1,39 @@
|
||||
@testable import SwiftLintBuiltInRules
|
||||
import TestHelpers
|
||||
import XCTest
|
||||
import Testing
|
||||
|
||||
final class CyclomaticComplexityConfigurationTests: SwiftLintTestCase {
|
||||
func testCyclomaticComplexityConfigurationInitializerSetsLevels() {
|
||||
@testable import SwiftLintBuiltInRules
|
||||
|
||||
@Suite(.rulesRegistered)
|
||||
struct CyclomaticComplexityConfigurationTests {
|
||||
@Test
|
||||
func cyclomaticComplexityConfigurationInitializerSetsLevels() {
|
||||
let warning = 10
|
||||
let error = 30
|
||||
let level = SeverityLevelsConfiguration<CyclomaticComplexityRule>(warning: warning, error: error)
|
||||
let configuration1 = CyclomaticComplexityConfiguration(length: level)
|
||||
XCTAssertEqual(configuration1.length, level)
|
||||
#expect(configuration1.length == level)
|
||||
|
||||
let length2 = SeverityLevelsConfiguration<CyclomaticComplexityRule>(warning: warning, error: nil)
|
||||
let configuration2 = CyclomaticComplexityConfiguration(length: length2)
|
||||
XCTAssertEqual(configuration2.length, length2)
|
||||
#expect(configuration2.length == length2)
|
||||
}
|
||||
|
||||
func testCyclomaticComplexityConfigurationInitializerSetsIgnoresCaseStatements() {
|
||||
@Test
|
||||
func cyclomaticComplexityConfigurationInitializerSetsIgnoresCaseStatements() {
|
||||
let configuration1 = CyclomaticComplexityConfiguration(
|
||||
length: SeverityLevelsConfiguration(warning: 10, error: 30),
|
||||
ignoresCaseStatements: true
|
||||
)
|
||||
XCTAssertTrue(configuration1.ignoresCaseStatements)
|
||||
#expect(configuration1.ignoresCaseStatements)
|
||||
|
||||
let configuration2 = CyclomaticComplexityConfiguration(
|
||||
length: SeverityLevelsConfiguration(warning: 10, error: 30)
|
||||
)
|
||||
XCTAssertFalse(configuration2.ignoresCaseStatements)
|
||||
#expect(!configuration2.ignoresCaseStatements)
|
||||
}
|
||||
|
||||
func testCyclomaticComplexityConfigurationApplyConfigurationWithDictionary() throws {
|
||||
@Test
|
||||
func cyclomaticComplexityConfigurationApplyConfigurationWithDictionary() throws {
|
||||
var configuration = CyclomaticComplexityConfiguration(
|
||||
length: SeverityLevelsConfiguration(warning: 0, error: 0)
|
||||
)
|
||||
@@ -49,19 +54,20 @@ final class CyclomaticComplexityConfigurationTests: SwiftLintTestCase {
|
||||
let config3: [String: Bool] = ["ignores_case_statements": false]
|
||||
|
||||
try configuration.apply(configuration: config1)
|
||||
XCTAssertEqual(configuration.length, length1)
|
||||
XCTAssertTrue(configuration.ignoresCaseStatements)
|
||||
#expect(configuration.length == length1)
|
||||
#expect(configuration.ignoresCaseStatements)
|
||||
|
||||
try configuration.apply(configuration: config2)
|
||||
XCTAssertEqual(configuration.length, length2)
|
||||
XCTAssertTrue(configuration.ignoresCaseStatements)
|
||||
#expect(configuration.length == length2)
|
||||
#expect(configuration.ignoresCaseStatements)
|
||||
|
||||
try configuration.apply(configuration: config3)
|
||||
XCTAssertEqual(configuration.length, length2)
|
||||
XCTAssertFalse(configuration.ignoresCaseStatements)
|
||||
#expect(configuration.length == length2)
|
||||
#expect(!configuration.ignoresCaseStatements)
|
||||
}
|
||||
|
||||
func testCyclomaticComplexityConfigurationThrowsOnBadConfigValues() {
|
||||
@Test
|
||||
func cyclomaticComplexityConfigurationThrowsOnBadConfigValues() {
|
||||
let badConfigs: [[String: Any]] = [
|
||||
["warning": true],
|
||||
["ignores_case_statements": 300],
|
||||
@@ -77,7 +83,8 @@ final class CyclomaticComplexityConfigurationTests: SwiftLintTestCase {
|
||||
}
|
||||
}
|
||||
|
||||
func testCyclomaticComplexityConfigurationCompares() {
|
||||
@Test
|
||||
func cyclomaticComplexityConfigurationCompares() {
|
||||
let config1 = CyclomaticComplexityConfiguration(
|
||||
length: SeverityLevelsConfiguration(warning: 10, error: 30)
|
||||
)
|
||||
@@ -95,9 +102,9 @@ final class CyclomaticComplexityConfigurationTests: SwiftLintTestCase {
|
||||
let config5 = CyclomaticComplexityConfiguration(
|
||||
length: SeverityLevelsConfiguration(warning: 20, error: 30)
|
||||
)
|
||||
XCTAssertNotEqual(config1, config2)
|
||||
XCTAssertEqual(config1, config3)
|
||||
XCTAssertNotEqual(config1, config4)
|
||||
XCTAssertNotEqual(config1, config5)
|
||||
#expect(config1 != config2)
|
||||
#expect(config1 == config3)
|
||||
#expect(config1 != config4)
|
||||
#expect(config1 != config5)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
@testable import SwiftLintBuiltInRules
|
||||
import TestHelpers
|
||||
import Testing
|
||||
|
||||
final class CyclomaticComplexityRuleTests: SwiftLintTestCase {
|
||||
private lazy var complexSwitchExample: Example = {
|
||||
@testable import SwiftLintBuiltInRules
|
||||
|
||||
@Suite(.rulesRegistered)
|
||||
struct CyclomaticComplexityRuleTests {
|
||||
private static let complexSwitchExample: Example = {
|
||||
var example = "func switcheroo() {\n"
|
||||
example += " switch foo {\n"
|
||||
for index in (0...30) {
|
||||
@@ -13,7 +16,7 @@ final class CyclomaticComplexityRuleTests: SwiftLintTestCase {
|
||||
return Example(example)
|
||||
}()
|
||||
|
||||
private lazy var complexSwitchInitExample: Example = {
|
||||
private static let complexSwitchInitExample: Example = {
|
||||
var example = "init() {\n"
|
||||
example += " switch foo {\n"
|
||||
for index in (0...30) {
|
||||
@@ -24,7 +27,7 @@ final class CyclomaticComplexityRuleTests: SwiftLintTestCase {
|
||||
return Example(example)
|
||||
}()
|
||||
|
||||
private lazy var complexIfExample: Example = {
|
||||
private static let complexIfExample: Example = {
|
||||
let nest = 22
|
||||
var example = "func nestThoseIfs() {\n"
|
||||
for index in (0...nest) {
|
||||
@@ -41,14 +44,16 @@ final class CyclomaticComplexityRuleTests: SwiftLintTestCase {
|
||||
return Example(example)
|
||||
}()
|
||||
|
||||
func testCyclomaticComplexity() {
|
||||
@Test
|
||||
func cyclomaticComplexity() {
|
||||
verifyRule(CyclomaticComplexityRule.description, commentDoesntViolate: true, stringDoesntViolate: true)
|
||||
}
|
||||
|
||||
func testIgnoresCaseStatementsConfigurationEnabled() {
|
||||
@Test
|
||||
func ignoresCaseStatementsConfigurationEnabled() {
|
||||
let baseDescription = CyclomaticComplexityRule.description
|
||||
let triggeringExamples = [complexIfExample]
|
||||
let nonTriggeringExamples = baseDescription.nonTriggeringExamples + [complexSwitchExample]
|
||||
let triggeringExamples = [Self.complexIfExample]
|
||||
let nonTriggeringExamples = baseDescription.nonTriggeringExamples + [Self.complexSwitchExample]
|
||||
|
||||
let description = baseDescription.with(nonTriggeringExamples: nonTriggeringExamples)
|
||||
.with(triggeringExamples: triggeringExamples)
|
||||
@@ -57,9 +62,13 @@ final class CyclomaticComplexityRuleTests: SwiftLintTestCase {
|
||||
commentDoesntViolate: true, stringDoesntViolate: true)
|
||||
}
|
||||
|
||||
func testIgnoresCaseStatementsConfigurationDisabled() {
|
||||
@Test
|
||||
func ignoresCaseStatementsConfigurationDisabled() {
|
||||
let baseDescription = CyclomaticComplexityRule.description
|
||||
let triggeringExamples = baseDescription.triggeringExamples + [complexSwitchExample, complexSwitchInitExample]
|
||||
let triggeringExamples = baseDescription.triggeringExamples + [
|
||||
Self.complexSwitchExample,
|
||||
Self.complexSwitchInitExample,
|
||||
]
|
||||
let nonTriggeringExamples = baseDescription.nonTriggeringExamples
|
||||
|
||||
let description = baseDescription.with(nonTriggeringExamples: nonTriggeringExamples)
|
||||
|
||||
@@ -1,92 +1,70 @@
|
||||
@testable import SwiftLintBuiltInRules
|
||||
import TestHelpers
|
||||
import XCTest
|
||||
import Testing
|
||||
|
||||
final class DeploymentTargetConfigurationTests: SwiftLintTestCase {
|
||||
@testable import SwiftLintBuiltInRules
|
||||
|
||||
@Suite(.rulesRegistered)
|
||||
struct DeploymentTargetConfigurationTests {
|
||||
private typealias Version = DeploymentTargetConfiguration.Version
|
||||
|
||||
// swiftlint:disable:next function_body_length
|
||||
func testAppliesConfigurationFromDictionary() throws {
|
||||
@Test
|
||||
func appliesConfigurationFromDictionary() throws { // swiftlint:disable:this function_body_length
|
||||
var configuration = DeploymentTargetConfiguration()
|
||||
|
||||
try configuration.apply(configuration: ["iOS_deployment_target": "10.1", "severity": "error"])
|
||||
XCTAssertEqual(
|
||||
configuration.iOSDeploymentTarget,
|
||||
Version(platform: .iOS, major: 10, minor: 1)
|
||||
#expect(configuration.iOSDeploymentTarget == Version(platform: .iOS, major: 10, minor: 1))
|
||||
#expect(
|
||||
configuration.iOSAppExtensionDeploymentTarget
|
||||
== Version(platform: .iOSApplicationExtension, major: 10, minor: 1)
|
||||
)
|
||||
XCTAssertEqual(
|
||||
configuration.iOSAppExtensionDeploymentTarget,
|
||||
Version(platform: .iOSApplicationExtension, major: 10, minor: 1)
|
||||
)
|
||||
XCTAssertEqual(configuration.severityConfiguration.severity, .error)
|
||||
#expect(configuration.severityConfiguration.severity == .error)
|
||||
|
||||
try configuration.apply(configuration: ["iOSApplicationExtension_deployment_target": "13.0"])
|
||||
XCTAssertEqual(
|
||||
configuration.iOSDeploymentTarget,
|
||||
Version(platform: .iOS, major: 10, minor: 1)
|
||||
#expect(configuration.iOSDeploymentTarget == Version(platform: .iOS, major: 10, minor: 1))
|
||||
#expect(
|
||||
configuration.iOSAppExtensionDeploymentTarget
|
||||
== Version(platform: .iOSApplicationExtension, major: 13, minor: 0)
|
||||
)
|
||||
XCTAssertEqual(
|
||||
configuration.iOSAppExtensionDeploymentTarget,
|
||||
Version(platform: .iOSApplicationExtension, major: 13, minor: 0)
|
||||
)
|
||||
XCTAssertEqual(configuration.severityConfiguration.severity, .error)
|
||||
#expect(configuration.severityConfiguration.severity == .error)
|
||||
|
||||
try configuration.apply(configuration: ["macOS_deployment_target": "10.11.3"])
|
||||
XCTAssertEqual(
|
||||
configuration.iOSDeploymentTarget,
|
||||
Version(platform: .iOS, major: 10, minor: 1)
|
||||
#expect(configuration.iOSDeploymentTarget == Version(platform: .iOS, major: 10, minor: 1))
|
||||
#expect(
|
||||
configuration.iOSAppExtensionDeploymentTarget
|
||||
== Version(platform: .iOSApplicationExtension, major: 13, minor: 0)
|
||||
)
|
||||
XCTAssertEqual(
|
||||
configuration.iOSAppExtensionDeploymentTarget,
|
||||
Version(platform: .iOSApplicationExtension, major: 13, minor: 0)
|
||||
#expect(configuration.macOSDeploymentTarget == Version(platform: .macOS, major: 10, minor: 11, patch: 3))
|
||||
#expect(
|
||||
configuration.macOSAppExtensionDeploymentTarget
|
||||
== Version(platform: .macOSApplicationExtension, major: 10, minor: 11, patch: 3)
|
||||
)
|
||||
XCTAssertEqual(
|
||||
configuration.macOSDeploymentTarget,
|
||||
Version(platform: .macOS, major: 10, minor: 11, patch: 3)
|
||||
)
|
||||
XCTAssertEqual(
|
||||
configuration.macOSAppExtensionDeploymentTarget,
|
||||
Version(platform: .macOSApplicationExtension, major: 10, minor: 11, patch: 3)
|
||||
)
|
||||
XCTAssertEqual(configuration.severityConfiguration.severity, .error)
|
||||
#expect(configuration.severityConfiguration.severity == .error)
|
||||
|
||||
try configuration.apply(configuration: ["macOSApplicationExtension_deployment_target": "12.4"])
|
||||
XCTAssertEqual(
|
||||
configuration.iOSDeploymentTarget,
|
||||
Version(platform: .iOS, major: 10, minor: 1)
|
||||
#expect(configuration.iOSDeploymentTarget == Version(platform: .iOS, major: 10, minor: 1))
|
||||
#expect(
|
||||
configuration.iOSAppExtensionDeploymentTarget
|
||||
== Version(platform: .iOSApplicationExtension, major: 13, minor: 0)
|
||||
)
|
||||
XCTAssertEqual(
|
||||
configuration.iOSAppExtensionDeploymentTarget,
|
||||
Version(platform: .iOSApplicationExtension, major: 13, minor: 0)
|
||||
#expect(configuration.macOSDeploymentTarget == Version(platform: .macOS, major: 10, minor: 11, patch: 3))
|
||||
#expect(
|
||||
configuration.macOSAppExtensionDeploymentTarget
|
||||
== Version(platform: .macOSApplicationExtension, major: 12, minor: 4)
|
||||
)
|
||||
XCTAssertEqual(
|
||||
configuration.macOSDeploymentTarget,
|
||||
Version(platform: .macOS, major: 10, minor: 11, patch: 3)
|
||||
)
|
||||
XCTAssertEqual(
|
||||
configuration.macOSAppExtensionDeploymentTarget,
|
||||
Version(platform: .macOSApplicationExtension, major: 12, minor: 4)
|
||||
)
|
||||
XCTAssertEqual(configuration.severityConfiguration.severity, .error)
|
||||
#expect(configuration.severityConfiguration.severity == .error)
|
||||
|
||||
try configuration.apply(configuration: ["severity": "warning"])
|
||||
XCTAssertEqual(
|
||||
configuration.iOSDeploymentTarget,
|
||||
Version(platform: .iOS, major: 10, minor: 1)
|
||||
#expect(configuration.iOSDeploymentTarget == Version(platform: .iOS, major: 10, minor: 1))
|
||||
#expect(
|
||||
configuration.iOSAppExtensionDeploymentTarget
|
||||
== Version(platform: .iOSApplicationExtension, major: 13, minor: 0)
|
||||
)
|
||||
XCTAssertEqual(
|
||||
configuration.iOSAppExtensionDeploymentTarget,
|
||||
Version(platform: .iOSApplicationExtension, major: 13, minor: 0)
|
||||
#expect(configuration.macOSDeploymentTarget == Version(platform: .macOS, major: 10, minor: 11, patch: 3))
|
||||
#expect(
|
||||
configuration.macOSAppExtensionDeploymentTarget
|
||||
== Version(platform: .macOSApplicationExtension, major: 12, minor: 4)
|
||||
)
|
||||
XCTAssertEqual(
|
||||
configuration.macOSDeploymentTarget,
|
||||
Version(platform: .macOS, major: 10, minor: 11, patch: 3)
|
||||
)
|
||||
XCTAssertEqual(
|
||||
configuration.macOSAppExtensionDeploymentTarget,
|
||||
Version(platform: .macOSApplicationExtension, major: 12, minor: 4)
|
||||
)
|
||||
XCTAssertEqual(configuration.severityConfiguration.severity, .warning)
|
||||
#expect(configuration.severityConfiguration.severity == .warning)
|
||||
|
||||
try configuration.apply(configuration: [
|
||||
"tvOS_deployment_target": 10.2,
|
||||
@@ -94,42 +72,31 @@ final class DeploymentTargetConfigurationTests: SwiftLintTestCase {
|
||||
"watchOS_deployment_target": 5,
|
||||
"watchOSApplicationExtension_deployment_target": 2.2,
|
||||
])
|
||||
XCTAssertEqual(
|
||||
configuration.iOSDeploymentTarget,
|
||||
Version(platform: .iOS, major: 10, minor: 1)
|
||||
#expect(configuration.iOSDeploymentTarget == Version(platform: .iOS, major: 10, minor: 1))
|
||||
#expect(
|
||||
configuration.iOSAppExtensionDeploymentTarget
|
||||
== Version(platform: .iOSApplicationExtension, major: 13, minor: 0)
|
||||
)
|
||||
XCTAssertEqual(
|
||||
configuration.iOSAppExtensionDeploymentTarget,
|
||||
Version(platform: .iOSApplicationExtension, major: 13, minor: 0)
|
||||
#expect(configuration.macOSDeploymentTarget == Version(platform: .macOS, major: 10, minor: 11, patch: 3))
|
||||
#expect(
|
||||
configuration.macOSAppExtensionDeploymentTarget
|
||||
== Version(platform: .macOSApplicationExtension, major: 12, minor: 4)
|
||||
)
|
||||
XCTAssertEqual(
|
||||
configuration.macOSDeploymentTarget,
|
||||
Version(platform: .macOS, major: 10, minor: 11, patch: 3)
|
||||
#expect(configuration.tvOSDeploymentTarget == Version(platform: .tvOS, major: 10, minor: 2))
|
||||
#expect(
|
||||
configuration.tvOSAppExtensionDeploymentTarget
|
||||
== Version(platform: .tvOSApplicationExtension, major: 9, minor: 1)
|
||||
)
|
||||
XCTAssertEqual(
|
||||
configuration.macOSAppExtensionDeploymentTarget,
|
||||
Version(platform: .macOSApplicationExtension, major: 12, minor: 4)
|
||||
#expect(configuration.watchOSDeploymentTarget == Version(platform: .watchOS, major: 5))
|
||||
#expect(
|
||||
configuration.watchOSAppExtensionDeploymentTarget
|
||||
== Version(platform: .watchOSApplicationExtension, major: 2, minor: 2)
|
||||
)
|
||||
XCTAssertEqual(
|
||||
configuration.tvOSDeploymentTarget,
|
||||
Version(platform: .tvOS, major: 10, minor: 2)
|
||||
)
|
||||
XCTAssertEqual(
|
||||
configuration.tvOSAppExtensionDeploymentTarget,
|
||||
Version(platform: .tvOSApplicationExtension, major: 9, minor: 1)
|
||||
)
|
||||
XCTAssertEqual(
|
||||
configuration.watchOSDeploymentTarget,
|
||||
Version(platform: .watchOS, major: 5)
|
||||
)
|
||||
XCTAssertEqual(
|
||||
configuration.watchOSAppExtensionDeploymentTarget,
|
||||
Version(platform: .watchOSApplicationExtension, major: 2, minor: 2)
|
||||
)
|
||||
XCTAssertEqual(configuration.severityConfiguration.severity, .warning)
|
||||
#expect(configuration.severityConfiguration.severity == .warning)
|
||||
}
|
||||
|
||||
func testThrowsOnBadConfig() {
|
||||
@Test
|
||||
func throwsOnBadConfig() {
|
||||
let badConfigs: [[String: Any]] = [
|
||||
["iOS_deployment_target": "foo"],
|
||||
["iOS_deployment_target": ""],
|
||||
|
||||
@@ -1,45 +1,53 @@
|
||||
@testable import SwiftLintBuiltInRules
|
||||
import TestHelpers
|
||||
import XCTest
|
||||
import Testing
|
||||
|
||||
final class DeploymentTargetRuleTests: SwiftLintTestCase {
|
||||
func testMacOSAttributeReason() {
|
||||
@testable import SwiftLintBuiltInRules
|
||||
|
||||
@Suite(.rulesRegistered)
|
||||
struct DeploymentTargetRuleTests {
|
||||
@Test
|
||||
func macOSAttributeReason() {
|
||||
let example = Example("@available(macOS 10.11, *)\nclass A {}")
|
||||
let violations = self.violations(example, config: ["macOS_deployment_target": "10.14.0"])
|
||||
|
||||
let expectedMessage = "Availability attribute is using a version (10.11) that is satisfied by " +
|
||||
"the deployment target (10.14) for platform macOS"
|
||||
XCTAssertEqual(violations.count, 1)
|
||||
XCTAssertEqual(violations.first?.reason, expectedMessage)
|
||||
let expectedMessage = """
|
||||
Availability attribute is using a version (10.11) that is satisfied by \
|
||||
the deployment target (10.14) for platform macOS
|
||||
"""
|
||||
#expect(violations.count == 1)
|
||||
#expect(violations.first?.reason == expectedMessage)
|
||||
}
|
||||
|
||||
func testWatchOSConditionReason() {
|
||||
@Test
|
||||
func watchOSConditionReason() {
|
||||
let example = Example("if #available(watchOS 4, *) {}")
|
||||
let violations = self.violations(example, config: ["watchOS_deployment_target": "5.0.1"])
|
||||
|
||||
let expectedMessage = "Availability condition is using a version (4) that is satisfied by " +
|
||||
"the deployment target (5.0.1) for platform watchOS"
|
||||
XCTAssertEqual(violations.count, 1)
|
||||
XCTAssertEqual(violations.first?.reason, expectedMessage)
|
||||
let expectedMessage = """
|
||||
Availability condition is using a version (4) that is satisfied by \
|
||||
the deployment target (5.0.1) for platform watchOS
|
||||
"""
|
||||
#expect(violations.count == 1)
|
||||
#expect(violations.first?.reason == expectedMessage)
|
||||
}
|
||||
|
||||
func testiOSNegativeAttributeReason() throws {
|
||||
try XCTSkipUnless(SwiftVersion.current >= .fiveDotSix)
|
||||
|
||||
@Test(.enabled(if: SwiftVersion.current >= .fiveDotSix))
|
||||
func iOSNegativeAttributeReason() throws {
|
||||
let example = Example("if #unavailable(iOS 14) { legacyImplementation() }")
|
||||
let violations = self.violations(example, config: ["iOS_deployment_target": "15.0"])
|
||||
|
||||
let expectedMessage = "Availability negative condition is using a version (14) that is satisfied by " +
|
||||
"the deployment target (15.0) for platform iOS"
|
||||
XCTAssertEqual(violations.count, 1)
|
||||
XCTAssertEqual(violations.first?.reason, expectedMessage)
|
||||
let expectedMessage = """
|
||||
Availability negative condition is using a version (14) that is satisfied by \
|
||||
the deployment target (15.0) for platform iOS
|
||||
"""
|
||||
#expect(violations.count == 1)
|
||||
#expect(violations.first?.reason == expectedMessage)
|
||||
}
|
||||
|
||||
private func violations(_ example: Example, config: Any?) -> [StyleViolation] {
|
||||
guard let config = makeConfig(config, DeploymentTargetRule.identifier) else {
|
||||
return []
|
||||
}
|
||||
|
||||
return TestHelpers.violations(example, config: config)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +1,19 @@
|
||||
@testable import SwiftLintBuiltInRules
|
||||
import TestHelpers
|
||||
import Testing
|
||||
|
||||
final class DiscouragedDirectInitRuleTests: SwiftLintTestCase {
|
||||
@testable import SwiftLintBuiltInRules
|
||||
|
||||
@Suite(.rulesRegistered)
|
||||
struct DiscouragedDirectInitRuleTests {
|
||||
private let baseDescription = DiscouragedDirectInitRule.description
|
||||
|
||||
func testDiscouragedDirectInitWithConfiguredSeverity() {
|
||||
@Test
|
||||
func discouragedDirectInitWithConfiguredSeverity() {
|
||||
verifyRule(baseDescription, ruleConfiguration: ["severity": "error"])
|
||||
}
|
||||
|
||||
func testDiscouragedDirectInitWithNewIncludedTypes() {
|
||||
@Test
|
||||
func discouragedDirectInitWithNewIncludedTypes() {
|
||||
let triggeringExamples = [
|
||||
Example("let foo = ↓Foo()"),
|
||||
Example("let bar = ↓Bar()"),
|
||||
@@ -26,7 +31,8 @@ final class DiscouragedDirectInitRuleTests: SwiftLintTestCase {
|
||||
verifyRule(description, ruleConfiguration: ["types": ["Foo", "Bar"]])
|
||||
}
|
||||
|
||||
func testDiscouragedDirectInitWithReplacedTypes() {
|
||||
@Test
|
||||
func discouragedDirectInitWithReplacedTypes() {
|
||||
let triggeringExamples = [
|
||||
Example("let bundle = ↓Bundle()")
|
||||
]
|
||||
|
||||
@@ -1,33 +1,44 @@
|
||||
@testable import SwiftLintBuiltInRules
|
||||
import TestHelpers
|
||||
import Testing
|
||||
|
||||
final class DiscouragedObjectLiteralRuleTests: SwiftLintTestCase {
|
||||
func testWithImageLiteral() {
|
||||
@testable import SwiftLintBuiltInRules
|
||||
|
||||
@Suite(.rulesRegistered)
|
||||
struct DiscouragedObjectLiteralRuleTests {
|
||||
@Test
|
||||
func withImageLiteral() {
|
||||
let baseDescription = DiscouragedObjectLiteralRule.description
|
||||
let nonTriggeringExamples = baseDescription.nonTriggeringExamples + [
|
||||
Example("let color = #colorLiteral(red: 0.9607843161, green: 0.7058823705, blue: 0.200000003, alpha: 1)")
|
||||
]
|
||||
let nonTriggeringExamples =
|
||||
baseDescription.nonTriggeringExamples + [
|
||||
Example("""
|
||||
let color = #colorLiteral(red: 0.9607843161, green: 0.7058823705, blue: 0.200000003, alpha: 1)
|
||||
"""),
|
||||
]
|
||||
let triggeringExamples = [
|
||||
Example("let image = ↓#imageLiteral(resourceName: \"image.jpg\")")
|
||||
]
|
||||
|
||||
let description = baseDescription.with(nonTriggeringExamples: nonTriggeringExamples,
|
||||
triggeringExamples: triggeringExamples)
|
||||
let description = baseDescription.with(
|
||||
nonTriggeringExamples: nonTriggeringExamples,
|
||||
triggeringExamples: triggeringExamples)
|
||||
|
||||
verifyRule(description, ruleConfiguration: ["image_literal": true, "color_literal": false])
|
||||
}
|
||||
|
||||
func testWithColorLiteral() {
|
||||
@Test
|
||||
func withColorLiteral() {
|
||||
let baseDescription = DiscouragedObjectLiteralRule.description
|
||||
let nonTriggeringExamples = baseDescription.nonTriggeringExamples + [
|
||||
Example("let image = #imageLiteral(resourceName: \"image.jpg\")")
|
||||
]
|
||||
let nonTriggeringExamples =
|
||||
baseDescription.nonTriggeringExamples + [
|
||||
Example("let image = #imageLiteral(resourceName: \"image.jpg\")")
|
||||
]
|
||||
let triggeringExamples = [
|
||||
Example("let color = ↓#colorLiteral(red: 0.9607843161, green: 0.7058823705, blue: 0.200000003, alpha: 1)")
|
||||
]
|
||||
|
||||
let description = baseDescription.with(nonTriggeringExamples: nonTriggeringExamples,
|
||||
triggeringExamples: triggeringExamples)
|
||||
let description = baseDescription.with(
|
||||
nonTriggeringExamples: nonTriggeringExamples,
|
||||
triggeringExamples: triggeringExamples)
|
||||
|
||||
verifyRule(description, ruleConfiguration: ["image_literal": false, "color_literal": true])
|
||||
}
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
@testable import SwiftLintBuiltInRules
|
||||
import XCTest
|
||||
import Testing
|
||||
|
||||
final class DuplicateImportsRuleTests: XCTestCase {
|
||||
func testDisableCommand() {
|
||||
@testable import SwiftLintBuiltInRules
|
||||
|
||||
@Suite(.rulesRegistered)
|
||||
struct DuplicateImportsRuleTests {
|
||||
@Test
|
||||
func disableCommand() {
|
||||
let content = """
|
||||
import InspireAPI
|
||||
// swiftlint:disable:next duplicate_imports
|
||||
@@ -12,6 +15,6 @@ final class DuplicateImportsRuleTests: XCTestCase {
|
||||
|
||||
_ = DuplicateImportsRule().correct(file: file)
|
||||
|
||||
XCTAssertEqual(file.contents, content)
|
||||
#expect(file.contents == content)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
@testable import SwiftLintBuiltInRules
|
||||
import TestHelpers
|
||||
import Testing
|
||||
|
||||
final class EmptyCountRuleTests: SwiftLintTestCase {
|
||||
func testEmptyCountWithOnlyAfterDot() {
|
||||
@testable import SwiftLintBuiltInRules
|
||||
|
||||
@Suite(.rulesRegistered)
|
||||
struct EmptyCountRuleTests {
|
||||
@Test
|
||||
func emptyCountWithOnlyAfterDot() {
|
||||
// Test with `only_after_dot` set to true
|
||||
let nonTriggeringExamples = [
|
||||
Example("var count = 0\n"),
|
||||
|
||||
@@ -1,49 +1,59 @@
|
||||
@testable import SwiftLintBuiltInRules
|
||||
import Foundation
|
||||
import TestHelpers
|
||||
import XCTest
|
||||
import Testing
|
||||
|
||||
final class ExpiringTodoRuleTests: SwiftLintTestCase {
|
||||
func testExpiringTodo() {
|
||||
@testable import SwiftLintBuiltInRules
|
||||
|
||||
@Suite(.rulesRegistered)
|
||||
struct ExpiringTodoRuleTests {
|
||||
@Test
|
||||
func expiringTodo() {
|
||||
verifyRule(ExpiringTodoRule.description, commentDoesntViolate: false)
|
||||
}
|
||||
|
||||
func testExpiredTodo() {
|
||||
@Test
|
||||
func expiredTodo() {
|
||||
let example = Example("fatalError() // TODO: [\(dateString(for: .expired))] Implement")
|
||||
let violations = self.violations(example)
|
||||
XCTAssertEqual(violations.count, 1)
|
||||
XCTAssertEqual(violations.first!.reason, "TODO/FIXME has expired and must be resolved")
|
||||
#expect(violations.count == 1)
|
||||
#expect(violations.first?.reason == "TODO/FIXME has expired and must be resolved")
|
||||
}
|
||||
|
||||
func testExpiredFixMe() {
|
||||
@Test
|
||||
func expiredFixMe() {
|
||||
let example = Example("fatalError() // FIXME: [\(dateString(for: .expired))] Implement")
|
||||
let violations = self.violations(example)
|
||||
XCTAssertEqual(violations.count, 1)
|
||||
XCTAssertEqual(violations.first!.reason, "TODO/FIXME has expired and must be resolved")
|
||||
#expect(violations.count == 1)
|
||||
#expect(violations.first?.reason == "TODO/FIXME has expired and must be resolved")
|
||||
}
|
||||
|
||||
func testApproachingExpiryTodo() {
|
||||
@Test
|
||||
func approachingExpiryTodo() {
|
||||
let example = Example("fatalError() // TODO: [\(dateString(for: .approachingExpiry))] Implement")
|
||||
let violations = self.violations(example)
|
||||
XCTAssertEqual(violations.count, 1)
|
||||
XCTAssertEqual(violations.first!.reason, "TODO/FIXME is approaching its expiry and should be resolved soon")
|
||||
#expect(violations.count == 1)
|
||||
#expect(violations.first?.reason == "TODO/FIXME is approaching its expiry and should be resolved soon")
|
||||
}
|
||||
|
||||
func testNonExpiredTodo() {
|
||||
@Test
|
||||
func nonExpiredTodo() {
|
||||
let example = Example("fatalError() // TODO: [\(dateString(for: .badFormatting))] Implement")
|
||||
XCTAssertEqual(violations(example).count, 0)
|
||||
#expect(violations(example).isEmpty)
|
||||
}
|
||||
|
||||
func testExpiredCustomDelimiters() {
|
||||
@Test
|
||||
func expiredCustomDelimiters() {
|
||||
let ruleConfig = ExpiringTodoConfiguration(
|
||||
dateDelimiters: .init(opening: "<", closing: ">")
|
||||
)
|
||||
let example = Example("fatalError() // TODO: <\(dateString(for: .expired))> Implement")
|
||||
let violations = self.violations(example, ruleConfig)
|
||||
XCTAssertEqual(violations.count, 1)
|
||||
XCTAssertEqual(violations.first!.reason, "TODO/FIXME has expired and must be resolved")
|
||||
#expect(violations.count == 1)
|
||||
#expect(violations.first?.reason == "TODO/FIXME has expired and must be resolved")
|
||||
}
|
||||
|
||||
func testExpiredCustomSeparator() {
|
||||
@Test
|
||||
func expiredCustomSeparator() {
|
||||
let ruleConfig = ExpiringTodoConfiguration(
|
||||
dateFormat: "MM-dd-yyyy",
|
||||
dateSeparator: "-"
|
||||
@@ -52,21 +62,23 @@ final class ExpiringTodoRuleTests: SwiftLintTestCase {
|
||||
"fatalError() // TODO: [\(dateString(for: .expired, format: ruleConfig.dateFormat))] Implement"
|
||||
)
|
||||
let violations = self.violations(example, ruleConfig)
|
||||
XCTAssertEqual(violations.count, 1)
|
||||
XCTAssertEqual(violations.first!.reason, "TODO/FIXME has expired and must be resolved")
|
||||
#expect(violations.count == 1)
|
||||
#expect(violations.first?.reason == "TODO/FIXME has expired and must be resolved")
|
||||
}
|
||||
|
||||
func testExpiredCustomFormat() {
|
||||
@Test
|
||||
func expiredCustomFormat() {
|
||||
let ruleConfig = ExpiringTodoConfiguration(dateFormat: "yyyy/MM/dd")
|
||||
let example = Example(
|
||||
"fatalError() // TODO: [\(dateString(for: .expired, format: ruleConfig.dateFormat))] Implement"
|
||||
)
|
||||
let violations = self.violations(example, ruleConfig)
|
||||
XCTAssertEqual(violations.count, 1)
|
||||
XCTAssertEqual(violations.first!.reason, "TODO/FIXME has expired and must be resolved")
|
||||
#expect(violations.count == 1)
|
||||
#expect(violations.first?.reason == "TODO/FIXME has expired and must be resolved")
|
||||
}
|
||||
|
||||
func testMultipleExpiredTodos() {
|
||||
@Test
|
||||
func multipleExpiredTodos() throws {
|
||||
let example = Example(
|
||||
"""
|
||||
fatalError() // TODO: [\(dateString(for: .expired))] Implement one
|
||||
@@ -74,14 +86,15 @@ final class ExpiringTodoRuleTests: SwiftLintTestCase {
|
||||
"""
|
||||
)
|
||||
let violations = self.violations(example)
|
||||
XCTAssertEqual(violations.count, 2)
|
||||
XCTAssertEqual(violations[0].reason, "TODO/FIXME has expired and must be resolved")
|
||||
XCTAssertEqual(violations[0].location.line, 1)
|
||||
XCTAssertEqual(violations[1].reason, "TODO/FIXME has expired and must be resolved")
|
||||
XCTAssertEqual(violations[1].location.line, 2)
|
||||
try #require(violations.count == 2)
|
||||
#expect(violations[0].reason == "TODO/FIXME has expired and must be resolved")
|
||||
#expect(violations[0].location.line == 1)
|
||||
#expect(violations[1].reason == "TODO/FIXME has expired and must be resolved")
|
||||
#expect(violations[1].location.line == 2)
|
||||
}
|
||||
|
||||
func testTodoAndExpiredTodo() {
|
||||
@Test
|
||||
func todoAndExpiredTodo() {
|
||||
let example = Example(
|
||||
"""
|
||||
// TODO: Implement one - without deadline
|
||||
@@ -90,12 +103,13 @@ final class ExpiringTodoRuleTests: SwiftLintTestCase {
|
||||
"""
|
||||
)
|
||||
let violations = self.violations(example)
|
||||
XCTAssertEqual(violations.count, 1)
|
||||
XCTAssertEqual(violations[0].reason, "TODO/FIXME has expired and must be resolved")
|
||||
XCTAssertEqual(violations[0].location.line, 3)
|
||||
#expect(violations.count == 1)
|
||||
#expect(violations.first?.reason == "TODO/FIXME has expired and must be resolved")
|
||||
#expect(violations.first?.location.line == 3)
|
||||
}
|
||||
|
||||
func testMultilineExpiredTodo() {
|
||||
@Test
|
||||
func multilineExpiredTodo() {
|
||||
let example = Example(
|
||||
"""
|
||||
// TODO: Multi-line task
|
||||
@@ -105,12 +119,13 @@ final class ExpiringTodoRuleTests: SwiftLintTestCase {
|
||||
"""
|
||||
)
|
||||
let violations = self.violations(example)
|
||||
XCTAssertEqual(violations.count, 1)
|
||||
XCTAssertEqual(violations[0].reason, "TODO/FIXME has expired and must be resolved")
|
||||
XCTAssertEqual(violations[0].location.line, 3)
|
||||
#expect(violations.count == 1)
|
||||
#expect(violations.first?.reason == "TODO/FIXME has expired and must be resolved")
|
||||
#expect(violations.first?.location.line == 3)
|
||||
}
|
||||
|
||||
func testTodoFunctionAndExpiredTodo() {
|
||||
@Test
|
||||
func todoFunctionAndExpiredTodo() {
|
||||
let example = Example(
|
||||
"""
|
||||
TODO()
|
||||
@@ -118,19 +133,20 @@ final class ExpiringTodoRuleTests: SwiftLintTestCase {
|
||||
"""
|
||||
)
|
||||
let violations = self.violations(example)
|
||||
XCTAssertEqual(violations.count, 1)
|
||||
XCTAssertEqual(violations[0].reason, "TODO/FIXME has expired and must be resolved")
|
||||
XCTAssertEqual(violations[0].location.line, 2)
|
||||
#expect(violations.count == 1)
|
||||
#expect(violations.first?.reason == "TODO/FIXME has expired and must be resolved")
|
||||
#expect(violations.first?.location.line == 2)
|
||||
}
|
||||
|
||||
func testBadExpiryTodoFormat() throws {
|
||||
@Test
|
||||
func badExpiryTodoFormat() throws {
|
||||
let ruleConfig = ExpiringTodoConfiguration(
|
||||
dateFormat: "dd/yyyy/MM"
|
||||
)
|
||||
let example = Example("fatalError() // TODO: [31/01/2020] Implement")
|
||||
let violations = self.violations(example, ruleConfig)
|
||||
XCTAssertEqual(violations.count, 1)
|
||||
XCTAssertEqual(violations.first?.reason, "Expiring TODO/FIXME is incorrectly formatted")
|
||||
#expect(violations.count == 1)
|
||||
#expect(violations.first?.reason == "Expiring TODO/FIXME is incorrectly formatted")
|
||||
}
|
||||
|
||||
private func violations(_ example: Example, _ config: ExpiringTodoConfiguration? = nil) -> [StyleViolation] {
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
@testable import SwiftLintBuiltInRules
|
||||
import TestHelpers
|
||||
import Testing
|
||||
|
||||
final class ExplicitInitRuleTests: SwiftLintTestCase {
|
||||
func testIncludeBareInit() {
|
||||
@testable import SwiftLintBuiltInRules
|
||||
|
||||
@Suite(.rulesRegistered)
|
||||
struct ExplicitInitRuleTests {
|
||||
@Test
|
||||
func includeBareInit() {
|
||||
let nonTriggeringExamples = [
|
||||
Example("let foo = Foo()"),
|
||||
Example("let foo = init()"),
|
||||
|
||||
@@ -1,16 +1,20 @@
|
||||
import TestHelpers
|
||||
import Testing
|
||||
|
||||
@testable import SwiftLintBuiltInRules
|
||||
@testable import SwiftLintCore
|
||||
import TestHelpers
|
||||
import XCTest
|
||||
|
||||
final class ExplicitTypeInterfaceConfigurationTests: SwiftLintTestCase {
|
||||
func testDefaultConfiguration() {
|
||||
@Suite(.rulesRegistered)
|
||||
struct ExplicitTypeInterfaceConfigurationTests {
|
||||
@Test
|
||||
func defaultConfiguration() {
|
||||
let config = ExplicitTypeInterfaceConfiguration()
|
||||
XCTAssertEqual(config.severityConfiguration.severity, .warning)
|
||||
XCTAssertEqual(config.allowedKinds, Set([.instance, .class, .static, .local]))
|
||||
#expect(config.severityConfiguration.severity == .warning)
|
||||
#expect(config.allowedKinds == Set([.instance, .class, .static, .local]))
|
||||
}
|
||||
|
||||
func testApplyingCustomConfiguration() throws {
|
||||
@Test
|
||||
func applyingCustomConfiguration() throws {
|
||||
var config = ExplicitTypeInterfaceConfiguration()
|
||||
try config.apply(
|
||||
configuration: [
|
||||
@@ -19,42 +23,46 @@ final class ExplicitTypeInterfaceConfigurationTests: SwiftLintTestCase {
|
||||
"allow_redundancy": true,
|
||||
] as [String: any Sendable]
|
||||
)
|
||||
XCTAssertEqual(config.severityConfiguration.severity, .error)
|
||||
XCTAssertEqual(config.allowedKinds, Set([.instance, .class, .static]))
|
||||
XCTAssertTrue(config.allowRedundancy)
|
||||
#expect(config.severityConfiguration.severity == .error)
|
||||
#expect(config.allowedKinds == Set([.instance, .class, .static]))
|
||||
#expect(config.allowRedundancy)
|
||||
}
|
||||
|
||||
func testInvalidKeyInCustomConfiguration() async throws {
|
||||
@Test
|
||||
func invalidKeyInCustomConfiguration() async throws {
|
||||
let console = try await Issue.captureConsole {
|
||||
var config = ExplicitTypeInterfaceConfiguration()
|
||||
try config.apply(configuration: ["invalidKey": "error"])
|
||||
}
|
||||
XCTAssertEqual(
|
||||
console,
|
||||
"warning: Configuration for 'explicit_type_interface' rule contains the invalid key(s) 'invalidKey'."
|
||||
#expect(
|
||||
console
|
||||
== "warning: Configuration for 'explicit_type_interface' rule contains the invalid key(s) 'invalidKey'."
|
||||
)
|
||||
}
|
||||
|
||||
func testInvalidTypeOfCustomConfiguration() {
|
||||
@Test
|
||||
func invalidTypeOfCustomConfiguration() {
|
||||
var config = ExplicitTypeInterfaceConfiguration()
|
||||
checkError(Issue.invalidConfiguration(ruleID: ExplicitTypeInterfaceRule.identifier)) {
|
||||
try config.apply(configuration: "invalidKey")
|
||||
}
|
||||
}
|
||||
|
||||
func testInvalidTypeOfValueInCustomConfiguration() {
|
||||
@Test
|
||||
func invalidTypeOfValueInCustomConfiguration() {
|
||||
var config = ExplicitTypeInterfaceConfiguration()
|
||||
checkError(Issue.invalidConfiguration(ruleID: ExplicitTypeInterfaceRule.identifier)) {
|
||||
try config.apply(configuration: ["severity": "foo"])
|
||||
}
|
||||
}
|
||||
|
||||
func testConsoleDescription() throws {
|
||||
@Test
|
||||
func consoleDescription() throws {
|
||||
var config = ExplicitTypeInterfaceConfiguration()
|
||||
try config.apply(configuration: ["excluded": ["class", "instance"]])
|
||||
XCTAssertEqual(
|
||||
RuleConfigurationDescription.from(configuration: config).oneLiner(),
|
||||
"severity: warning; excluded: [class, instance]; allow_redundancy: false"
|
||||
#expect(
|
||||
RuleConfigurationDescription.from(configuration: config).oneLiner()
|
||||
== "severity: warning; excluded: [class, instance]; allow_redundancy: false"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
@testable import SwiftLintBuiltInRules
|
||||
import TestHelpers
|
||||
import Testing
|
||||
|
||||
final class ExplicitTypeInterfaceRuleTests: SwiftLintTestCase {
|
||||
func testLocalVars() {
|
||||
@testable import SwiftLintBuiltInRules
|
||||
|
||||
@Suite(.rulesRegistered)
|
||||
struct ExplicitTypeInterfaceRuleTests {
|
||||
@Test
|
||||
func localVars() {
|
||||
let nonTriggeringExamples = [
|
||||
Example("func foo() {\nlet intVal: Int = 1\n}"),
|
||||
Example("""
|
||||
@@ -30,7 +34,8 @@ final class ExplicitTypeInterfaceRuleTests: SwiftLintTestCase {
|
||||
verifyRule(description)
|
||||
}
|
||||
|
||||
func testExcludeLocalVars() {
|
||||
@Test
|
||||
func excludeLocalVars() {
|
||||
let nonTriggeringExamples = ExplicitTypeInterfaceRule.description.nonTriggeringExamples + [
|
||||
Example("func foo() {\nlet intVal = 1\n}")
|
||||
]
|
||||
@@ -42,7 +47,8 @@ final class ExplicitTypeInterfaceRuleTests: SwiftLintTestCase {
|
||||
verifyRule(description, ruleConfiguration: ["excluded": ["local"]])
|
||||
}
|
||||
|
||||
func testExcludeClassVars() {
|
||||
@Test
|
||||
func excludeClassVars() {
|
||||
let nonTriggeringExamples = ExplicitTypeInterfaceRule.description.nonTriggeringExamples + [
|
||||
Example("class Foo {\n static var myStaticVar = 0\n}\n"),
|
||||
Example("class Foo {\n static let myStaticLet = 0\n}\n"),
|
||||
@@ -59,7 +65,8 @@ final class ExplicitTypeInterfaceRuleTests: SwiftLintTestCase {
|
||||
verifyRule(description, ruleConfiguration: ["excluded": ["static"]])
|
||||
}
|
||||
|
||||
func testAllowRedundancy() {
|
||||
@Test
|
||||
func allowRedundancy() {
|
||||
let nonTriggeringExamples: [Example] = [
|
||||
Example("class Foo {\n var myVar: Int? = 0\n}\n"),
|
||||
Example("class Foo {\n let myVar: Int? = 0\n}\n"),
|
||||
@@ -90,7 +97,8 @@ final class ExplicitTypeInterfaceRuleTests: SwiftLintTestCase {
|
||||
verifyRule(description, ruleConfiguration: ["allow_redundancy": true])
|
||||
}
|
||||
|
||||
func testEmbeddedInStatements() {
|
||||
@Test
|
||||
func embeddedInStatements() {
|
||||
let nonTriggeringExamples = [
|
||||
Example("""
|
||||
func foo() {
|
||||
@@ -117,7 +125,8 @@ final class ExplicitTypeInterfaceRuleTests: SwiftLintTestCase {
|
||||
verifyRule(description)
|
||||
}
|
||||
|
||||
func testCaptureGroup() {
|
||||
@Test
|
||||
func captureGroup() {
|
||||
let nonTriggeringExamples = [
|
||||
Example("""
|
||||
var k: Int = 0
|
||||
@@ -150,7 +159,8 @@ final class ExplicitTypeInterfaceRuleTests: SwiftLintTestCase {
|
||||
verifyRule(description)
|
||||
}
|
||||
|
||||
func testFastEnumerationDeclaration() {
|
||||
@Test
|
||||
func fastEnumerationDeclaration() {
|
||||
let nonTriggeringExamples = [
|
||||
Example("""
|
||||
func foo() {
|
||||
@@ -173,7 +183,8 @@ final class ExplicitTypeInterfaceRuleTests: SwiftLintTestCase {
|
||||
verifyRule(description)
|
||||
}
|
||||
|
||||
func testSwitchCaseDeclarations() {
|
||||
@Test
|
||||
func switchCaseDeclarations() {
|
||||
let nonTriggeringExamples = [
|
||||
Example("""
|
||||
enum Foo {
|
||||
|
||||
@@ -1,21 +1,25 @@
|
||||
@testable import SwiftLintBuiltInRules
|
||||
import TestHelpers
|
||||
import XCTest
|
||||
import Testing
|
||||
|
||||
@testable import SwiftLintBuiltInRules
|
||||
|
||||
private let fixturesDirectory = "\(TestResources.path())/FileHeaderRuleFixtures"
|
||||
|
||||
final class FileHeaderRuleTests: SwiftLintTestCase {
|
||||
@Suite(.rulesRegistered)
|
||||
struct FileHeaderRuleTests {
|
||||
private func validate(fileName: String, using configuration: Any) throws -> [StyleViolation] {
|
||||
let file = SwiftLintFile(path: fixturesDirectory.stringByAppendingPathComponent(fileName))!
|
||||
let rule = try FileHeaderRule(configuration: configuration)
|
||||
return rule.validate(file: file)
|
||||
}
|
||||
|
||||
func testFileHeaderWithDefaultConfiguration() {
|
||||
@Test
|
||||
func fileHeaderWithDefaultConfiguration() {
|
||||
verifyRule(FileHeaderRule.description, skipCommentTests: true)
|
||||
}
|
||||
|
||||
func testFileHeaderWithRequiredString() {
|
||||
@Test
|
||||
func fileHeaderWithRequiredString() {
|
||||
let nonTriggeringExamples = [
|
||||
Example("// **Header"),
|
||||
Example("//\n// **Header"),
|
||||
@@ -37,7 +41,8 @@ final class FileHeaderRuleTests: SwiftLintTestCase {
|
||||
testShebang: false)
|
||||
}
|
||||
|
||||
func testFileHeaderWithRequiredPattern() {
|
||||
@Test
|
||||
func fileHeaderWithRequiredPattern() {
|
||||
let nonTriggeringExamples = [
|
||||
Example("// Copyright © 2016 Realm"),
|
||||
Example("//\n// Copyright © 2016 Realm)"),
|
||||
@@ -56,7 +61,8 @@ final class FileHeaderRuleTests: SwiftLintTestCase {
|
||||
testMultiByteOffsets: false)
|
||||
}
|
||||
|
||||
func testFileHeaderWithRequiredStringAndURLComment() {
|
||||
@Test
|
||||
func fileHeaderWithRequiredStringAndURLComment() {
|
||||
let nonTriggeringExamples = [
|
||||
Example("/* Check this url: https://github.com/realm/SwiftLint */")
|
||||
]
|
||||
@@ -73,7 +79,8 @@ final class FileHeaderRuleTests: SwiftLintTestCase {
|
||||
testMultiByteOffsets: false)
|
||||
}
|
||||
|
||||
func testFileHeaderWithForbiddenString() {
|
||||
@Test
|
||||
func fileHeaderWithForbiddenString() {
|
||||
let nonTriggeringExamples = [
|
||||
Example("// Copyright\n"),
|
||||
Example("let foo = \"**All rights reserved.\""),
|
||||
@@ -93,7 +100,8 @@ final class FileHeaderRuleTests: SwiftLintTestCase {
|
||||
skipCommentTests: true)
|
||||
}
|
||||
|
||||
func testFileHeaderWithForbiddenPattern() {
|
||||
@Test
|
||||
func fileHeaderWithForbiddenPattern() {
|
||||
let nonTriggeringExamples = [
|
||||
Example("// Copyright\n"),
|
||||
Example("// FileHeaderRuleTests.m\n"),
|
||||
@@ -113,7 +121,8 @@ final class FileHeaderRuleTests: SwiftLintTestCase {
|
||||
skipCommentTests: true)
|
||||
}
|
||||
|
||||
func testFileHeaderWithForbiddenPatternAndDocComment() {
|
||||
@Test
|
||||
func fileHeaderWithForbiddenPatternAndDocComment() {
|
||||
let nonTriggeringExamples = [
|
||||
Example("/// This is great tool with tests.\nclass GreatTool {}"),
|
||||
Example("class GreatTool {}"),
|
||||
@@ -130,78 +139,84 @@ final class FileHeaderRuleTests: SwiftLintTestCase {
|
||||
skipCommentTests: true, testMultiByteOffsets: false)
|
||||
}
|
||||
|
||||
func testFileHeaderWithRequiredStringUsingFilenamePlaceholder() {
|
||||
@Test
|
||||
func fileHeaderWithRequiredStringUsingFilenamePlaceholder() throws {
|
||||
let configuration = ["required_string": "// SWIFTLINT_CURRENT_FILENAME"]
|
||||
|
||||
// Non triggering tests
|
||||
XCTAssert(try validate(fileName: "FileNameMatchingSimple.swift", using: configuration).isEmpty)
|
||||
try #expect(validate(fileName: "FileNameMatchingSimple.swift", using: configuration).isEmpty)
|
||||
|
||||
// Triggering tests
|
||||
XCTAssertEqual(try validate(fileName: "FileNameCaseMismatch.swift", using: configuration).count, 1)
|
||||
XCTAssertEqual(try validate(fileName: "FileNameMismatch.swift", using: configuration).count, 1)
|
||||
XCTAssertEqual(try validate(fileName: "FileNameMissing.swift", using: configuration).count, 1)
|
||||
try #expect(validate(fileName: "FileNameCaseMismatch.swift", using: configuration).count == 1)
|
||||
try #expect(validate(fileName: "FileNameMismatch.swift", using: configuration).count == 1)
|
||||
try #expect(validate(fileName: "FileNameMissing.swift", using: configuration).count == 1)
|
||||
}
|
||||
|
||||
func testFileHeaderWithForbiddenStringUsingFilenamePlaceholder() {
|
||||
@Test
|
||||
func fileHeaderWithForbiddenStringUsingFilenamePlaceholder() throws {
|
||||
let configuration = ["forbidden_string": "// SWIFTLINT_CURRENT_FILENAME"]
|
||||
|
||||
// Non triggering tests
|
||||
XCTAssert(try validate(fileName: "FileNameCaseMismatch.swift", using: configuration).isEmpty)
|
||||
XCTAssert(try validate(fileName: "FileNameMismatch.swift", using: configuration).isEmpty)
|
||||
XCTAssert(try validate(fileName: "FileNameMissing.swift", using: configuration).isEmpty)
|
||||
try #expect(validate(fileName: "FileNameCaseMismatch.swift", using: configuration).isEmpty)
|
||||
try #expect(validate(fileName: "FileNameMismatch.swift", using: configuration).isEmpty)
|
||||
try #expect(validate(fileName: "FileNameMissing.swift", using: configuration).isEmpty)
|
||||
|
||||
// Triggering tests
|
||||
XCTAssertEqual(try validate(fileName: "FileNameMatchingSimple.swift", using: configuration).count, 1)
|
||||
#expect(try validate(fileName: "FileNameMatchingSimple.swift", using: configuration).count == 1)
|
||||
}
|
||||
|
||||
func testFileHeaderWithRequiredPatternUsingFilenamePlaceholder() {
|
||||
@Test
|
||||
func fileHeaderWithRequiredPatternUsingFilenamePlaceholder() throws {
|
||||
let configuration1 = ["required_pattern": "// SWIFTLINT_CURRENT_FILENAME\n.*\\d{4}"]
|
||||
let configuration2 = [
|
||||
"required_pattern": "// Copyright © \\d{4}\n// File: \"SWIFTLINT_CURRENT_FILENAME\"",
|
||||
"required_pattern": "// Copyright © \\d{4}\n// File: \"SWIFTLINT_CURRENT_FILENAME\""
|
||||
]
|
||||
|
||||
// Non triggering tests
|
||||
XCTAssert(try validate(fileName: "FileNameMatchingSimple.swift", using: configuration1).isEmpty)
|
||||
XCTAssert(try validate(fileName: "FileNameMatchingComplex.swift", using: configuration2).isEmpty)
|
||||
try #expect(validate(fileName: "FileNameMatchingSimple.swift", using: configuration1).isEmpty)
|
||||
try #expect(validate(fileName: "FileNameMatchingComplex.swift", using: configuration2).isEmpty)
|
||||
|
||||
// Triggering tests
|
||||
XCTAssertEqual(try validate(fileName: "FileNameCaseMismatch.swift", using: configuration1).count, 1)
|
||||
XCTAssertEqual(try validate(fileName: "FileNameMismatch.swift", using: configuration1).count, 1)
|
||||
XCTAssertEqual(try validate(fileName: "FileNameMissing.swift", using: configuration1).count, 1)
|
||||
try #expect(validate(fileName: "FileNameCaseMismatch.swift", using: configuration1).count == 1)
|
||||
try #expect(validate(fileName: "FileNameMismatch.swift", using: configuration1).count == 1)
|
||||
try #expect(validate(fileName: "FileNameMissing.swift", using: configuration1).count == 1)
|
||||
}
|
||||
|
||||
func testFileHeaderWithForbiddenPatternUsingFilenamePlaceholder() {
|
||||
@Test
|
||||
func fileHeaderWithForbiddenPatternUsingFilenamePlaceholder() throws {
|
||||
let configuration1 = ["forbidden_pattern": "// SWIFTLINT_CURRENT_FILENAME\n.*\\d{4}"]
|
||||
let configuration2 = ["forbidden_pattern": "//.*(\\s|\")SWIFTLINT_CURRENT_FILENAME(\\s|\").*"]
|
||||
|
||||
// Non triggering tests
|
||||
XCTAssert(try validate(fileName: "FileNameCaseMismatch.swift", using: configuration1).isEmpty)
|
||||
XCTAssert(try validate(fileName: "FileNameMismatch.swift", using: configuration1).isEmpty)
|
||||
XCTAssert(try validate(fileName: "FileNameMissing.swift", using: configuration1).isEmpty)
|
||||
try #expect(validate(fileName: "FileNameCaseMismatch.swift", using: configuration1).isEmpty)
|
||||
try #expect(validate(fileName: "FileNameMismatch.swift", using: configuration1).isEmpty)
|
||||
try #expect(validate(fileName: "FileNameMissing.swift", using: configuration1).isEmpty)
|
||||
|
||||
XCTAssert(try validate(fileName: "FileNameCaseMismatch.swift", using: configuration2).isEmpty)
|
||||
XCTAssert(try validate(fileName: "FileNameMismatch.swift", using: configuration2).isEmpty)
|
||||
XCTAssert(try validate(fileName: "FileNameMissing.swift", using: configuration2).isEmpty)
|
||||
try #expect(validate(fileName: "FileNameCaseMismatch.swift", using: configuration2).isEmpty)
|
||||
try #expect(validate(fileName: "FileNameMismatch.swift", using: configuration2).isEmpty)
|
||||
try #expect(validate(fileName: "FileNameMissing.swift", using: configuration2).isEmpty)
|
||||
|
||||
// Triggering tests
|
||||
XCTAssertEqual(try validate(fileName: "FileNameMatchingSimple.swift", using: configuration1).count, 1)
|
||||
XCTAssertEqual(try validate(fileName: "FileNameMatchingComplex.swift", using: configuration2).count, 1)
|
||||
try #expect(validate(fileName: "FileNameMatchingSimple.swift", using: configuration1).count == 1)
|
||||
try #expect(validate(fileName: "FileNameMatchingComplex.swift", using: configuration2).count == 1)
|
||||
}
|
||||
|
||||
func testFileHeaderShouldBeEmpty() {
|
||||
@Test
|
||||
func fileHeaderShouldBeEmpty() throws {
|
||||
let configuration = ["forbidden_pattern": "."]
|
||||
|
||||
// Non triggering tests
|
||||
XCTAssert(try validate(fileName: "FileHeaderEmpty.swift", using: configuration).isEmpty)
|
||||
XCTAssert(try validate(fileName: "DocumentedType.swift", using: configuration).isEmpty)
|
||||
try #expect(validate(fileName: "FileHeaderEmpty.swift", using: configuration).isEmpty)
|
||||
try #expect(validate(fileName: "DocumentedType.swift", using: configuration).isEmpty)
|
||||
|
||||
// Triggering tests
|
||||
XCTAssertEqual(try validate(fileName: "FileNameCaseMismatch.swift", using: configuration).count, 1)
|
||||
XCTAssertEqual(try validate(fileName: "FileNameMismatch.swift", using: configuration).count, 1)
|
||||
XCTAssertEqual(try validate(fileName: "FileNameMissing.swift", using: configuration).count, 1)
|
||||
try #expect(validate(fileName: "FileNameCaseMismatch.swift", using: configuration).count == 1)
|
||||
try #expect(validate(fileName: "FileNameMismatch.swift", using: configuration).count == 1)
|
||||
try #expect(validate(fileName: "FileNameMissing.swift", using: configuration).count == 1)
|
||||
}
|
||||
|
||||
func testSimplePattern() {
|
||||
@Test
|
||||
func simplePattern() {
|
||||
let description = FileHeaderRule.description
|
||||
.with(nonTriggeringExamples: [
|
||||
Example("""
|
||||
@@ -232,7 +247,8 @@ final class FileHeaderRuleTests: SwiftLintTestCase {
|
||||
)
|
||||
}
|
||||
|
||||
func testPattern() {
|
||||
@Test
|
||||
func pattern() {
|
||||
let description = FileHeaderRule.description
|
||||
.with(nonTriggeringExamples: [
|
||||
Example("""
|
||||
|
||||
@@ -1,13 +1,18 @@
|
||||
@testable import SwiftLintBuiltInRules
|
||||
import TestHelpers
|
||||
import Testing
|
||||
|
||||
final class FileLengthRuleTests: SwiftLintTestCase {
|
||||
func testFileLengthWithDefaultConfiguration() {
|
||||
@testable import SwiftLintBuiltInRules
|
||||
|
||||
@Suite(.rulesRegistered)
|
||||
struct FileLengthRuleTests {
|
||||
@Test
|
||||
func fileLengthWithDefaultConfiguration() {
|
||||
verifyRule(FileLengthRule.description, commentDoesntViolate: false,
|
||||
testMultiByteOffsets: false, testShebang: false)
|
||||
}
|
||||
|
||||
func testFileLengthIgnoringLinesWithOnlyComments() {
|
||||
@Test
|
||||
func fileLengthIgnoringLinesWithOnlyComments() {
|
||||
let triggeringExamples = [
|
||||
Example(repeatElement("print(\"swiftlint\")\n", count: 401).joined())
|
||||
]
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
import SourceKittenFramework
|
||||
@testable import SwiftLintBuiltInRules
|
||||
import TestHelpers
|
||||
import XCTest
|
||||
import Testing
|
||||
|
||||
@testable import SwiftLintBuiltInRules
|
||||
|
||||
private let fixturesDirectory = "\(TestResources.path())/FileNameNoSpaceRuleFixtures"
|
||||
|
||||
final class FileNameNoSpaceRuleTests: SwiftLintTestCase {
|
||||
@Suite(.rulesRegistered)
|
||||
struct FileNameNoSpaceRuleTests {
|
||||
private func validate(fileName: String, excludedOverride: [String]? = nil) throws -> [StyleViolation] {
|
||||
let file = SwiftLintFile(path: fixturesDirectory.stringByAppendingPathComponent(fileName))!
|
||||
let rule: FileNameNoSpaceRule
|
||||
@@ -18,24 +20,33 @@ final class FileNameNoSpaceRuleTests: SwiftLintTestCase {
|
||||
return rule.validate(file: file)
|
||||
}
|
||||
|
||||
func testFileNameDoesntTrigger() {
|
||||
XCTAssert(try validate(fileName: "File.swift").isEmpty)
|
||||
@Test
|
||||
func fileNameDoesntTrigger() throws {
|
||||
try #expect(validate(fileName: "File.swift").isEmpty)
|
||||
}
|
||||
|
||||
func testFileWithSpaceDoesTrigger() {
|
||||
XCTAssertEqual(try validate(fileName: "File Name.swift").count, 1)
|
||||
@Test
|
||||
func fileWithSpaceDoesTrigger() throws {
|
||||
try #expect(validate(fileName: "File Name.swift").count == 1)
|
||||
}
|
||||
|
||||
func testExtensionNameDoesntTrigger() {
|
||||
XCTAssert(try validate(fileName: "File+Extension.swift").isEmpty)
|
||||
@Test
|
||||
func extensionNameDoesntTrigger() throws {
|
||||
try #expect(validate(fileName: "File+Extension.swift").isEmpty)
|
||||
}
|
||||
|
||||
func testExtensionWithSpaceDoesTrigger() {
|
||||
XCTAssertEqual(try validate(fileName: "File+Test Extension.swift").count, 1)
|
||||
@Test
|
||||
func extensionWithSpaceDoesTrigger() throws {
|
||||
try #expect(validate(fileName: "File+Test Extension.swift").count == 1)
|
||||
}
|
||||
|
||||
func testCustomExcludedList() {
|
||||
XCTAssert(try validate(fileName: "File+Test Extension.swift",
|
||||
excludedOverride: ["File+Test Extension.swift"]).isEmpty)
|
||||
@Test
|
||||
func customExcludedList() throws {
|
||||
try #expect(
|
||||
validate(
|
||||
fileName: "File+Test Extension.swift",
|
||||
excludedOverride: ["File+Test Extension.swift"]
|
||||
).isEmpty
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
@testable import SwiftLintBuiltInRules
|
||||
import TestHelpers
|
||||
import XCTest
|
||||
import Testing
|
||||
|
||||
@testable import SwiftLintBuiltInRules
|
||||
|
||||
private let fixturesDirectory = "\(TestResources.path())/FileNameRuleFixtures"
|
||||
|
||||
final class FileNameRuleTests: SwiftLintTestCase {
|
||||
@Suite(.rulesRegistered)
|
||||
struct FileNameRuleTests {
|
||||
private func validate(fileName: String,
|
||||
excluded: [String]? = nil,
|
||||
excludedPaths: [String]? = nil,
|
||||
@@ -40,94 +42,113 @@ final class FileNameRuleTests: SwiftLintTestCase {
|
||||
return rule.validate(file: file)
|
||||
}
|
||||
|
||||
func testMainDoesntTrigger() {
|
||||
XCTAssert(try validate(fileName: "main.swift").isEmpty)
|
||||
@Test
|
||||
func mainDoesntTrigger() throws {
|
||||
try #expect(validate(fileName: "main.swift").isEmpty)
|
||||
}
|
||||
|
||||
func testLinuxMainDoesntTrigger() {
|
||||
XCTAssert(try validate(fileName: "LinuxMain.swift").isEmpty)
|
||||
@Test
|
||||
func linuxMainDoesntTrigger() throws {
|
||||
try #expect(validate(fileName: "LinuxMain.swift").isEmpty)
|
||||
}
|
||||
|
||||
func testClassNameDoesntTrigger() {
|
||||
XCTAssert(try validate(fileName: "MyClass.swift").isEmpty)
|
||||
@Test
|
||||
func classNameDoesntTrigger() throws {
|
||||
try #expect(validate(fileName: "MyClass.swift").isEmpty)
|
||||
}
|
||||
|
||||
func testStructNameDoesntTrigger() {
|
||||
XCTAssert(try validate(fileName: "MyStruct.swift").isEmpty)
|
||||
@Test
|
||||
func structNameDoesntTrigger() throws {
|
||||
try #expect(validate(fileName: "MyStruct.swift").isEmpty)
|
||||
}
|
||||
|
||||
func testMacroNameDoesntTrigger() {
|
||||
XCTAssert(try validate(fileName: "MyMacro.swift").isEmpty)
|
||||
@Test
|
||||
func macroNameDoesntTrigger() throws {
|
||||
try #expect(validate(fileName: "MyMacro.swift").isEmpty)
|
||||
}
|
||||
|
||||
func testExtensionNameDoesntTrigger() {
|
||||
XCTAssert(try validate(fileName: "NSString+Extension.swift").isEmpty)
|
||||
@Test
|
||||
func extensionNameDoesntTrigger() throws {
|
||||
try #expect(validate(fileName: "NSString+Extension.swift").isEmpty)
|
||||
}
|
||||
|
||||
func testNestedExtensionDoesntTrigger() {
|
||||
XCTAssert(try validate(fileName: "Notification.Name+Extension.swift").isEmpty)
|
||||
@Test
|
||||
func nestedExtensionDoesntTrigger() throws {
|
||||
try #expect(validate(fileName: "Notification.Name+Extension.swift").isEmpty)
|
||||
}
|
||||
|
||||
func testNestedTypeDoesntTrigger() {
|
||||
XCTAssert(try validate(fileName: "Nested.MyType.swift").isEmpty)
|
||||
@Test
|
||||
func nestedTypeDoesntTrigger() throws {
|
||||
try #expect(validate(fileName: "Nested.MyType.swift").isEmpty)
|
||||
}
|
||||
|
||||
func testMultipleLevelsDeeplyNestedTypeDoesntTrigger() {
|
||||
XCTAssert(try validate(fileName: "Multiple.Levels.Deeply.Nested.MyType.swift").isEmpty)
|
||||
@Test
|
||||
func multipleLevelsDeeplyNestedTypeDoesntTrigger() throws {
|
||||
try #expect(validate(fileName: "Multiple.Levels.Deeply.Nested.MyType.swift").isEmpty)
|
||||
}
|
||||
|
||||
func testNestedTypeNotFullyQualifiedDoesntTrigger() {
|
||||
XCTAssert(try validate(fileName: "MyType.swift").isEmpty)
|
||||
@Test
|
||||
func nestedTypeNotFullyQualifiedDoesntTrigger() throws {
|
||||
try #expect(validate(fileName: "MyType.swift").isEmpty)
|
||||
}
|
||||
|
||||
func testNestedTypeNotFullyQualifiedDoesTriggerWithOverride() {
|
||||
XCTAssert(try validate(fileName: "MyType.swift", requireFullyQualifiedNames: true).isNotEmpty)
|
||||
@Test
|
||||
func nestedTypeNotFullyQualifiedDoesTriggerWithOverride() throws {
|
||||
try #expect(validate(fileName: "MyType.swift", requireFullyQualifiedNames: true).isNotEmpty)
|
||||
}
|
||||
|
||||
func testNestedTypeSeparatorDoesntTrigger() {
|
||||
XCTAssert(try validate(fileName: "NotificationName+Extension.swift", nestedTypeSeparator: "").isEmpty)
|
||||
XCTAssert(try validate(fileName: "Notification__Name+Extension.swift", nestedTypeSeparator: "__").isEmpty)
|
||||
@Test
|
||||
func nestedTypeSeparatorDoesntTrigger() throws {
|
||||
try #expect(validate(fileName: "NotificationName+Extension.swift", nestedTypeSeparator: "").isEmpty)
|
||||
try #expect(validate(fileName: "Notification__Name+Extension.swift", nestedTypeSeparator: "__").isEmpty)
|
||||
}
|
||||
|
||||
func testWrongNestedTypeSeparatorDoesTrigger() {
|
||||
XCTAssert(try validate(fileName: "Notification__Name+Extension.swift", nestedTypeSeparator: ".").isNotEmpty)
|
||||
XCTAssert(try validate(fileName: "NotificationName+Extension.swift", nestedTypeSeparator: "__").isNotEmpty)
|
||||
@Test
|
||||
func wrongNestedTypeSeparatorDoesTrigger() throws {
|
||||
try #expect(validate(fileName: "Notification__Name+Extension.swift", nestedTypeSeparator: ".").isNotEmpty)
|
||||
try #expect(validate(fileName: "NotificationName+Extension.swift", nestedTypeSeparator: "__").isNotEmpty)
|
||||
}
|
||||
|
||||
func testMisspelledNameDoesTrigger() {
|
||||
XCTAssertEqual(try validate(fileName: "MyStructf.swift").count, 1)
|
||||
@Test
|
||||
func misspelledNameDoesTrigger() throws {
|
||||
try #expect(validate(fileName: "MyStructf.swift").count == 1)
|
||||
}
|
||||
|
||||
func testMisspelledNameDoesntTriggerWithOverride() {
|
||||
XCTAssert(try validate(fileName: "MyStructf.swift", excluded: ["MyStructf.swift"]).isEmpty)
|
||||
@Test
|
||||
func misspelledNameDoesntTriggerWithOverride() throws {
|
||||
try #expect(validate(fileName: "MyStructf.swift", excluded: ["MyStructf.swift"]).isEmpty)
|
||||
}
|
||||
|
||||
func testMainDoesTriggerWithoutOverride() {
|
||||
XCTAssertEqual(try validate(fileName: "main.swift", excluded: []).count, 1)
|
||||
@Test
|
||||
func mainDoesTriggerWithoutOverride() throws {
|
||||
try #expect(validate(fileName: "main.swift", excluded: []).count == 1)
|
||||
}
|
||||
|
||||
func testCustomSuffixPattern() {
|
||||
XCTAssert(try validate(fileName: "BoolExtension.swift", suffixPattern: "Extensions?").isEmpty)
|
||||
XCTAssert(try validate(fileName: "BoolExtensions.swift", suffixPattern: "Extensions?").isEmpty)
|
||||
XCTAssert(try validate(fileName: "BoolExtensionTests.swift", suffixPattern: "Extensions?|\\+.*").isEmpty)
|
||||
@Test
|
||||
func customSuffixPattern() throws {
|
||||
try #expect(validate(fileName: "BoolExtension.swift", suffixPattern: "Extensions?").isEmpty)
|
||||
try #expect(validate(fileName: "BoolExtensions.swift", suffixPattern: "Extensions?").isEmpty)
|
||||
try #expect(validate(fileName: "BoolExtensionTests.swift", suffixPattern: "Extensions?|\\+.*").isEmpty)
|
||||
}
|
||||
|
||||
func testCustomPrefixPattern() {
|
||||
XCTAssert(try validate(fileName: "ExtensionBool.swift", prefixPattern: "Extensions?").isEmpty)
|
||||
XCTAssert(try validate(fileName: "ExtensionsBool.swift", prefixPattern: "Extensions?").isEmpty)
|
||||
@Test
|
||||
func customPrefixPattern() throws {
|
||||
try #expect(validate(fileName: "ExtensionBool.swift", prefixPattern: "Extensions?").isEmpty)
|
||||
try #expect(validate(fileName: "ExtensionsBool.swift", prefixPattern: "Extensions?").isEmpty)
|
||||
}
|
||||
|
||||
func testCustomPrefixAndSuffixPatterns() {
|
||||
XCTAssert(
|
||||
try validate(
|
||||
@Test
|
||||
func customPrefixAndSuffixPatterns() throws {
|
||||
try #expect(
|
||||
validate(
|
||||
fileName: "SLBoolExtension.swift",
|
||||
prefixPattern: "SL",
|
||||
suffixPattern: "Extensions?|\\+.*"
|
||||
).isEmpty
|
||||
)
|
||||
|
||||
XCTAssert(
|
||||
try validate(
|
||||
try #expect(
|
||||
validate(
|
||||
fileName: "ExtensionBool+SwiftLint.swift",
|
||||
prefixPattern: "Extensions?",
|
||||
suffixPattern: "Extensions?|\\+.*"
|
||||
@@ -135,34 +156,36 @@ final class FileNameRuleTests: SwiftLintTestCase {
|
||||
)
|
||||
}
|
||||
|
||||
func testExcludedDoesntSupportRegex() {
|
||||
XCTAssert(
|
||||
try validate(
|
||||
@Test
|
||||
func excludedDoesntSupportRegex() throws {
|
||||
try #expect(
|
||||
validate(
|
||||
fileName: "main.swift",
|
||||
excluded: [".*"]
|
||||
).isNotEmpty
|
||||
)
|
||||
}
|
||||
|
||||
func testExcludedPathPatternsSupportRegex() {
|
||||
XCTAssert(
|
||||
try validate(
|
||||
@Test
|
||||
func excludedPathPatternsSupportRegex() throws {
|
||||
try #expect(
|
||||
validate(
|
||||
fileName: "main.swift",
|
||||
excluded: [],
|
||||
excludedPaths: [".*"]
|
||||
).isEmpty
|
||||
)
|
||||
|
||||
XCTAssert(
|
||||
try validate(
|
||||
try #expect(
|
||||
validate(
|
||||
fileName: "main.swift",
|
||||
excluded: [],
|
||||
excludedPaths: [".*.swift"]
|
||||
).isEmpty
|
||||
)
|
||||
|
||||
XCTAssert(
|
||||
try validate(
|
||||
try #expect(
|
||||
validate(
|
||||
fileName: "main.swift",
|
||||
excluded: [],
|
||||
excludedPaths: [".*/FileNameRuleFixtures/.*"]
|
||||
@@ -170,9 +193,10 @@ final class FileNameRuleTests: SwiftLintTestCase {
|
||||
)
|
||||
}
|
||||
|
||||
func testExcludedPathPatternsWithRegexDoesntMatch() {
|
||||
XCTAssert(
|
||||
try validate(
|
||||
@Test
|
||||
func excludedPathPatternsWithRegexDoesntMatch() throws {
|
||||
try #expect(
|
||||
validate(
|
||||
fileName: "main.swift",
|
||||
excluded: [],
|
||||
excludedPaths: [".*/OtherFolder/.*", "MAIN\\.swift"]
|
||||
@@ -180,8 +204,9 @@ final class FileNameRuleTests: SwiftLintTestCase {
|
||||
)
|
||||
}
|
||||
|
||||
func testInvalidRegex() {
|
||||
XCTAssertThrowsError(
|
||||
@Test
|
||||
func invalidRegex() throws {
|
||||
#expect(throws: (any Error).self) {
|
||||
try validate(
|
||||
fileName: "NSString+Extension.swift",
|
||||
excluded: [],
|
||||
@@ -189,24 +214,24 @@ final class FileNameRuleTests: SwiftLintTestCase {
|
||||
prefixPattern: "",
|
||||
suffixPattern: ""
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
func testExcludedPathPatternsWithMultipleRegexs() {
|
||||
XCTAssertThrowsError(
|
||||
@Test
|
||||
func excludedPathPatternsWithMultipleRegexs() throws {
|
||||
#expect(throws: (any Error).self) {
|
||||
try validate(
|
||||
fileName: "main.swift",
|
||||
excluded: [],
|
||||
excludedPaths: ["/FileNameRuleFixtures/.*", "("]
|
||||
)
|
||||
)
|
||||
|
||||
XCTAssertThrowsError(
|
||||
}
|
||||
#expect(throws: (any Error).self) {
|
||||
try validate(
|
||||
fileName: "main.swift",
|
||||
excluded: [],
|
||||
excludedPaths: ["/FileNameRuleFixtures/.*", "(", ".*.swift"]
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
@testable import SwiftLintBuiltInRules
|
||||
import TestHelpers
|
||||
import Testing
|
||||
|
||||
final class FileTypesOrderRuleTests: SwiftLintTestCase {
|
||||
// swiftlint:disable:next function_body_length
|
||||
func testFileTypesOrderReversedOrder() {
|
||||
@testable import SwiftLintBuiltInRules
|
||||
|
||||
@Suite(.rulesRegistered)
|
||||
struct FileTypesOrderRuleTests {
|
||||
@Test
|
||||
func fileTypesOrderReversedOrder() { // swiftlint:disable:this function_body_length
|
||||
// Test with reversed `order` entries
|
||||
let nonTriggeringExamples = [
|
||||
Example(FileTypesOrderRuleExamples.defaultOrderParts.reversed().joined(separator: "\n\n"))
|
||||
@@ -82,7 +85,8 @@ final class FileTypesOrderRuleTests: SwiftLintTestCase {
|
||||
)
|
||||
}
|
||||
|
||||
func testFileTypesOrderGroupedOrder() {
|
||||
@Test
|
||||
func fileTypesOrderGroupedOrder() {
|
||||
// Test with grouped `order` entries
|
||||
let nonTriggeringExamples = [
|
||||
Example("""
|
||||
|
||||
@@ -1,10 +1,14 @@
|
||||
@testable import SwiftLintBuiltInRules
|
||||
import TestHelpers
|
||||
import XCTest
|
||||
import Testing
|
||||
|
||||
final class FunctionBodyLengthRuleTests: SwiftLintTestCase {
|
||||
func testWarning() {
|
||||
let example = Example("""
|
||||
@testable import SwiftLintBuiltInRules
|
||||
|
||||
@Suite(.rulesRegistered)
|
||||
struct FunctionBodyLengthRuleTests {
|
||||
@Test
|
||||
func warning() {
|
||||
let example = Example(
|
||||
"""
|
||||
func f() {
|
||||
let x = 0
|
||||
let y = 1
|
||||
@@ -12,9 +16,8 @@ final class FunctionBodyLengthRuleTests: SwiftLintTestCase {
|
||||
}
|
||||
""")
|
||||
|
||||
XCTAssertEqual(
|
||||
self.violations(example, configuration: ["warning": 2, "error": 4]),
|
||||
[
|
||||
#expect(
|
||||
self.violations(example, configuration: ["warning": 2, "error": 4]) == [
|
||||
StyleViolation(
|
||||
ruleDescription: FunctionBodyLengthRule.description,
|
||||
severity: .warning,
|
||||
@@ -28,7 +31,8 @@ final class FunctionBodyLengthRuleTests: SwiftLintTestCase {
|
||||
)
|
||||
}
|
||||
|
||||
func testError() {
|
||||
@Test
|
||||
func error() {
|
||||
let example = Example("""
|
||||
func f() {
|
||||
let x = 0
|
||||
@@ -37,9 +41,8 @@ final class FunctionBodyLengthRuleTests: SwiftLintTestCase {
|
||||
}
|
||||
""")
|
||||
|
||||
XCTAssertEqual(
|
||||
self.violations(example, configuration: ["warning": 1, "error": 2]),
|
||||
[
|
||||
#expect(
|
||||
self.violations(example, configuration: ["warning": 1, "error": 2]) == [
|
||||
StyleViolation(
|
||||
ruleDescription: FunctionBodyLengthRule.description,
|
||||
severity: .error,
|
||||
@@ -53,16 +56,16 @@ final class FunctionBodyLengthRuleTests: SwiftLintTestCase {
|
||||
)
|
||||
}
|
||||
|
||||
func testViolationMessages() {
|
||||
@Test
|
||||
func violationMessages() {
|
||||
let types = FunctionBodyLengthRule.description.triggeringExamples.flatMap {
|
||||
self.violations($0, configuration: ["warning": 2])
|
||||
violations($0, configuration: ["warning": 2])
|
||||
}.compactMap {
|
||||
$0.reason.split(separator: " ", maxSplits: 1).first
|
||||
}
|
||||
|
||||
XCTAssertEqual(
|
||||
types,
|
||||
["Function", "Deinitializer", "Initializer", "Subscript", "Accessor", "Accessor", "Accessor"]
|
||||
#expect(
|
||||
types == ["Function", "Deinitializer", "Initializer", "Subscript", "Accessor", "Accessor", "Accessor"]
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
@testable import SwiftLintBuiltInRules
|
||||
import TestHelpers
|
||||
import XCTest
|
||||
import Testing
|
||||
|
||||
final class FunctionNameWhitespaceRuleTests: SwiftLintTestCase {
|
||||
@testable import SwiftLintBuiltInRules
|
||||
|
||||
@Suite(.rulesRegistered)
|
||||
struct FunctionNameWhitespaceRuleTests {
|
||||
private typealias GenericSpacingType = FunctionNameWhitespaceConfiguration.GenericSpacingType
|
||||
|
||||
private static let operatorWhitespaceViolationReason =
|
||||
@@ -16,7 +18,7 @@ final class FunctionNameWhitespaceRuleTests: SwiftLintTestCase {
|
||||
_ source: String,
|
||||
configuration: [String: String]? = nil,
|
||||
expected: String,
|
||||
file: StaticString = #filePath,
|
||||
file: String = #filePath,
|
||||
line: UInt = #line
|
||||
) {
|
||||
let example = configuration == nil
|
||||
@@ -24,7 +26,10 @@ final class FunctionNameWhitespaceRuleTests: SwiftLintTestCase {
|
||||
: Example(source, configuration: configuration!)
|
||||
|
||||
let violations = ruleViolations(example)
|
||||
XCTAssertEqual(violations.first?.reason, expected, file: file, line: line)
|
||||
#expect(
|
||||
violations.first?.reason == expected,
|
||||
sourceLocation: SourceLocation(fileID: #fileID, filePath: file, line: Int(line), column: 1)
|
||||
)
|
||||
}
|
||||
|
||||
private func ruleViolations(
|
||||
@@ -39,7 +44,8 @@ final class FunctionNameWhitespaceRuleTests: SwiftLintTestCase {
|
||||
|
||||
// MARK: - func keyword spacing
|
||||
|
||||
func testSpaceBetweenFuncKeywordAndName_ShouldReportReason() {
|
||||
@Test
|
||||
func spaceBetweenFuncKeywordAndName_ShouldReportReason() {
|
||||
assertReason(
|
||||
"func abc(lhs: Int, rhs: Int) -> Int {}",
|
||||
expected: Self.funcKeywordSpacingViolationReason
|
||||
@@ -48,35 +54,40 @@ final class FunctionNameWhitespaceRuleTests: SwiftLintTestCase {
|
||||
|
||||
// MARK: - operator functions
|
||||
|
||||
func testOperatorFunctionSpacing_WhenNoSpaceAfterOperator_ShouldReportOperatorMessage() {
|
||||
@Test
|
||||
func operatorFunctionSpacing_WhenNoSpaceAfterOperator_ShouldReportOperatorMessage() {
|
||||
assertReason(
|
||||
"func <|(lhs: Int, rhs: Int) -> Int {}",
|
||||
expected: Self.operatorWhitespaceViolationReason
|
||||
)
|
||||
}
|
||||
|
||||
func testOperatorFunctionSpacing_WhenTooManySpacesAfterOperator_ShouldReportOperatorMessage() {
|
||||
@Test
|
||||
func operatorFunctionSpacing_WhenTooManySpacesAfterOperator_ShouldReportOperatorMessage() {
|
||||
assertReason(
|
||||
"func <| (lhs: Int, rhs: Int) -> Int {}",
|
||||
expected: Self.operatorWhitespaceViolationReason
|
||||
)
|
||||
}
|
||||
|
||||
func testOperatorFunctionWithGenerics_WhenNoSpaceAfterOperator_ShouldReportOperatorMessage() {
|
||||
@Test
|
||||
func operatorFunctionWithGenerics_WhenNoSpaceAfterOperator_ShouldReportOperatorMessage() {
|
||||
assertReason(
|
||||
"func <|<<A>(lhs: A, rhs: A) -> A {}",
|
||||
expected: Self.operatorWhitespaceViolationReason
|
||||
)
|
||||
}
|
||||
|
||||
func testOperatorFunctionSpacing_WhenMultipleViolations_ShouldReportOperatorMessage() {
|
||||
@Test
|
||||
func operatorFunctionSpacing_WhenMultipleViolations_ShouldReportOperatorMessage() {
|
||||
assertReason(
|
||||
"func <| (lhs: Int, rhs: Int) -> Int {}",
|
||||
expected: Self.operatorWhitespaceViolationReason
|
||||
)
|
||||
}
|
||||
|
||||
func testOperatorFunctionSpacing_WhenTooManySpacesBeforeAndAfter_ShouldReportOperatorMessage() {
|
||||
@Test
|
||||
func operatorFunctionSpacing_WhenTooManySpacesBeforeAndAfter_ShouldReportOperatorMessage() {
|
||||
assertReason(
|
||||
"func <| (lhs: Int, rhs: Int) -> Int {}",
|
||||
expected: Self.operatorWhitespaceViolationReason
|
||||
@@ -85,7 +96,8 @@ final class FunctionNameWhitespaceRuleTests: SwiftLintTestCase {
|
||||
|
||||
// MARK: - generic_spacing = no_space
|
||||
|
||||
func testSpaceAfterFuncName_WhenNoSpaceConfigured_ShouldReport() {
|
||||
@Test
|
||||
func spaceAfterFuncName_WhenNoSpaceConfigured_ShouldReport() {
|
||||
assertReason(
|
||||
"func abc (lhs: Int) {}",
|
||||
configuration: ["generic_spacing": "no_space"],
|
||||
@@ -93,7 +105,8 @@ final class FunctionNameWhitespaceRuleTests: SwiftLintTestCase {
|
||||
)
|
||||
}
|
||||
|
||||
func testSpaceAfterGeneric_WhenNoSpaceConfigured_ShouldReport() {
|
||||
@Test
|
||||
func spaceAfterGeneric_WhenNoSpaceConfigured_ShouldReport() {
|
||||
assertReason(
|
||||
"func abc<T> (lhs: Int) {}",
|
||||
configuration: ["generic_spacing": "no_space"],
|
||||
@@ -103,7 +116,8 @@ final class FunctionNameWhitespaceRuleTests: SwiftLintTestCase {
|
||||
|
||||
// MARK: - generic_spacing = leading_space
|
||||
|
||||
func testSpaceAfterFuncName_WhenLeadingSpaceConfigured_ShouldReport() {
|
||||
@Test
|
||||
func spaceAfterFuncName_WhenLeadingSpaceConfigured_ShouldReport() {
|
||||
assertReason(
|
||||
"func abc(lhs: Int) {}",
|
||||
configuration: ["generic_spacing": "leading_space"],
|
||||
@@ -111,7 +125,8 @@ final class FunctionNameWhitespaceRuleTests: SwiftLintTestCase {
|
||||
)
|
||||
}
|
||||
|
||||
func testSpaceBeforeGeneric_WhenLeadingSpaceConfigured_ShouldReport() {
|
||||
@Test
|
||||
func spaceBeforeGeneric_WhenLeadingSpaceConfigured_ShouldReport() {
|
||||
assertReason(
|
||||
"func abc<T>(lhs: Int) {}",
|
||||
configuration: ["generic_spacing": "leading_space"],
|
||||
@@ -121,7 +136,8 @@ final class FunctionNameWhitespaceRuleTests: SwiftLintTestCase {
|
||||
|
||||
// MARK: - generic_spacing = trailing_space
|
||||
|
||||
func testSpaceAfterFuncName_WhenTrailingSpaceConfigured_ShouldReport() {
|
||||
@Test
|
||||
func spaceAfterFuncName_WhenTrailingSpaceConfigured_ShouldReport() {
|
||||
assertReason(
|
||||
"func abc (lhs: Int) {}",
|
||||
configuration: ["generic_spacing": "trailing_space"],
|
||||
@@ -129,7 +145,8 @@ final class FunctionNameWhitespaceRuleTests: SwiftLintTestCase {
|
||||
)
|
||||
}
|
||||
|
||||
func testSpaceAfterGeneric_WhenTrailingSpaceConfigured_ShouldReport() {
|
||||
@Test
|
||||
func spaceAfterGeneric_WhenTrailingSpaceConfigured_ShouldReport() {
|
||||
assertReason(
|
||||
"func abc<T>(lhs: Int) {}",
|
||||
configuration: ["generic_spacing": "trailing_space"],
|
||||
@@ -139,7 +156,8 @@ final class FunctionNameWhitespaceRuleTests: SwiftLintTestCase {
|
||||
|
||||
// MARK: - generic_spacing = leading_trailing_space
|
||||
|
||||
func testSpaceAfterFuncName_WhenLeadingTrailingSpaceConfigured_ShouldReport() {
|
||||
@Test
|
||||
func spaceAfterFuncName_WhenLeadingTrailingSpaceConfigured_ShouldReport() {
|
||||
assertReason(
|
||||
"func abc(lhs: Int) {}",
|
||||
configuration: ["generic_spacing": "leading_trailing_space"],
|
||||
@@ -147,7 +165,8 @@ final class FunctionNameWhitespaceRuleTests: SwiftLintTestCase {
|
||||
)
|
||||
}
|
||||
|
||||
func testSpaceBeforeGeneric_WhenLeadingTrailingSpaceConfigured_ShouldReport() {
|
||||
@Test
|
||||
func spaceBeforeGeneric_WhenLeadingTrailingSpaceConfigured_ShouldReport() {
|
||||
assertReason(
|
||||
"func abc<T>(lhs: Int) {}",
|
||||
configuration: ["generic_spacing": "leading_trailing_space"],
|
||||
@@ -155,7 +174,8 @@ final class FunctionNameWhitespaceRuleTests: SwiftLintTestCase {
|
||||
)
|
||||
}
|
||||
|
||||
func testSpaceAfterGeneric_WhenLeadingTrailingSpaceConfigured_ShouldReport() {
|
||||
@Test
|
||||
func spaceAfterGeneric_WhenLeadingTrailingSpaceConfigured_ShouldReport() {
|
||||
assertReason(
|
||||
"func abc <T>(lhs: Int) {}",
|
||||
configuration: ["generic_spacing": "leading_trailing_space"],
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
@testable import SwiftLintBuiltInRules
|
||||
import TestHelpers
|
||||
import Testing
|
||||
|
||||
@testable import SwiftLintBuiltInRules
|
||||
|
||||
private func funcWithParameters(_ parameters: String,
|
||||
violates: Bool = false,
|
||||
@@ -10,8 +12,10 @@ private func funcWithParameters(_ parameters: String,
|
||||
return Example("func \(marker)abc(\(parameters)) {}\n", file: file, line: line)
|
||||
}
|
||||
|
||||
final class FunctionParameterCountRuleTests: SwiftLintTestCase {
|
||||
func testFunctionParameterCount() {
|
||||
@Suite(.rulesRegistered)
|
||||
struct FunctionParameterCountRuleTests {
|
||||
@Test
|
||||
func functionParameterCount() {
|
||||
let baseDescription = FunctionParameterCountRule.description
|
||||
let nonTriggeringExamples = [
|
||||
funcWithParameters(repeatElement("x: Int, ", count: 3).joined() + "x: Int")
|
||||
@@ -27,7 +31,8 @@ final class FunctionParameterCountRuleTests: SwiftLintTestCase {
|
||||
verifyRule(description)
|
||||
}
|
||||
|
||||
func testDefaultFunctionParameterCount() {
|
||||
@Test
|
||||
func defaultFunctionParameterCount() {
|
||||
let baseDescription = FunctionParameterCountRule.description
|
||||
let nonTriggeringExamples = [
|
||||
funcWithParameters(repeatElement("x: Int, ", count: 3).joined() + "x: Int")
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
@testable import SwiftLintBuiltInRules
|
||||
import TestHelpers
|
||||
import Testing
|
||||
|
||||
final class GenericTypeNameRuleTests: SwiftLintTestCase {
|
||||
func testGenericTypeNameWithExcluded() {
|
||||
@testable import SwiftLintBuiltInRules
|
||||
|
||||
@Suite(.rulesRegistered)
|
||||
struct GenericTypeNameRuleTests {
|
||||
@Test
|
||||
func genericTypeNameWithExcluded() {
|
||||
let baseDescription = GenericTypeNameRule.description
|
||||
let nonTriggeringExamples = baseDescription.nonTriggeringExamples + [
|
||||
Example("func foo<apple> {}"),
|
||||
@@ -18,7 +22,8 @@ final class GenericTypeNameRuleTests: SwiftLintTestCase {
|
||||
verifyRule(description, ruleConfiguration: ["excluded": ["apple", "some.*", ".*st\\d+.*"]])
|
||||
}
|
||||
|
||||
func testGenericTypeNameWithAllowedSymbols() {
|
||||
@Test
|
||||
func genericTypeNameWithAllowedSymbols() {
|
||||
let baseDescription = GenericTypeNameRule.description
|
||||
let nonTriggeringExamples = baseDescription.nonTriggeringExamples + [
|
||||
Example("func foo<T$>() {}"),
|
||||
@@ -33,7 +38,8 @@ final class GenericTypeNameRuleTests: SwiftLintTestCase {
|
||||
verifyRule(description, ruleConfiguration: ["allowed_symbols": ["$", "%"]])
|
||||
}
|
||||
|
||||
func testGenericTypeNameWithAllowedSymbolsAndViolation() {
|
||||
@Test
|
||||
func genericTypeNameWithAllowedSymbolsAndViolation() {
|
||||
let baseDescription = GenericTypeNameRule.description
|
||||
let triggeringExamples = [
|
||||
Example("func foo<↓T_$>() {}")
|
||||
@@ -43,7 +49,8 @@ final class GenericTypeNameRuleTests: SwiftLintTestCase {
|
||||
verifyRule(description, ruleConfiguration: ["allowed_symbols": ["$", "%"]])
|
||||
}
|
||||
|
||||
func testGenericTypeNameWithIgnoreStartWithLowercase() {
|
||||
@Test
|
||||
func genericTypeNameWithIgnoreStartWithLowercase() {
|
||||
let baseDescription = GenericTypeNameRule.description
|
||||
let triggeringExamplesToRemove = [
|
||||
Example("func foo<↓type>() {}"),
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
@testable import SwiftLintBuiltInRules
|
||||
import TestHelpers
|
||||
import XCTest
|
||||
import Testing
|
||||
|
||||
final class IdentifierNameRuleTests: SwiftLintTestCase {
|
||||
func testIdentifierNameWithExcluded() {
|
||||
@testable import SwiftLintBuiltInRules
|
||||
|
||||
@Suite(.rulesRegistered)
|
||||
struct IdentifierNameRuleTests {
|
||||
@Test
|
||||
func identifierNameWithExcluded() {
|
||||
let baseDescription = IdentifierNameRule.description
|
||||
let nonTriggeringExamples = baseDescription.nonTriggeringExamples + [
|
||||
Example("let Apple = 0"),
|
||||
@@ -19,7 +22,8 @@ final class IdentifierNameRuleTests: SwiftLintTestCase {
|
||||
verifyRule(description, ruleConfiguration: ["excluded": ["Apple", "some.*", ".*\\d+.*"]])
|
||||
}
|
||||
|
||||
func testIdentifierNameWithAllowedSymbols() {
|
||||
@Test
|
||||
func identifierNameWithAllowedSymbols() {
|
||||
let baseDescription = IdentifierNameRule.description
|
||||
let nonTriggeringExamples = baseDescription.nonTriggeringExamples + [
|
||||
Example("let myLet$ = 0"),
|
||||
@@ -33,7 +37,8 @@ final class IdentifierNameRuleTests: SwiftLintTestCase {
|
||||
verifyRule(description, ruleConfiguration: ["allowed_symbols": ["$", "%", "_"]])
|
||||
}
|
||||
|
||||
func testIdentifierNameWithAllowedSymbolsAndViolation() {
|
||||
@Test
|
||||
func identifierNameWithAllowedSymbolsAndViolation() {
|
||||
let baseDescription = IdentifierNameRule.description
|
||||
let triggeringExamples = [
|
||||
Example("let ↓my_Let$ = 0")
|
||||
@@ -43,7 +48,8 @@ final class IdentifierNameRuleTests: SwiftLintTestCase {
|
||||
verifyRule(description, ruleConfiguration: ["allowed_symbols": ["$", "%"]])
|
||||
}
|
||||
|
||||
func testIdentifierNameWithIgnoreStartWithLowercase() {
|
||||
@Test
|
||||
func identifierNameWithIgnoreStartWithLowercase() {
|
||||
let baseDescription = IdentifierNameRule.description
|
||||
let triggeringExamplesToRemove = [
|
||||
Example("let ↓MyLet = 0"),
|
||||
@@ -65,7 +71,8 @@ final class IdentifierNameRuleTests: SwiftLintTestCase {
|
||||
verifyRule(description, ruleConfiguration: ["validates_start_with_lowercase": "off"])
|
||||
}
|
||||
|
||||
func testStartsWithLowercaseCheck() {
|
||||
@Test
|
||||
func startsWithLowercaseCheck() {
|
||||
let triggeringExamples = [
|
||||
Example("let ↓MyLet = 0"),
|
||||
Example("enum Foo { case ↓MyCase }"),
|
||||
@@ -92,7 +99,8 @@ final class IdentifierNameRuleTests: SwiftLintTestCase {
|
||||
)
|
||||
}
|
||||
|
||||
func testStartsWithLowercaseCheckInCombinationWithAllowedSymbols() {
|
||||
@Test
|
||||
func startsWithLowercaseCheckInCombinationWithAllowedSymbols() {
|
||||
verifyRule(
|
||||
IdentifierNameRule.description
|
||||
.with(triggeringExamples: [
|
||||
@@ -109,7 +117,8 @@ final class IdentifierNameRuleTests: SwiftLintTestCase {
|
||||
)
|
||||
}
|
||||
|
||||
func testLinuxCrashOnEmojiNames() {
|
||||
@Test
|
||||
func linuxCrashOnEmojiNames() {
|
||||
let baseDescription = IdentifierNameRule.description
|
||||
let triggeringExamples = [
|
||||
Example("let 👦🏼 = \"👦🏼\"")
|
||||
@@ -119,12 +128,13 @@ final class IdentifierNameRuleTests: SwiftLintTestCase {
|
||||
verifyRule(description, ruleConfiguration: ["allowed_symbols": ["$", "%"]])
|
||||
}
|
||||
|
||||
func testFunctionNameInViolationMessage() {
|
||||
@Test
|
||||
func functionNameInViolationMessage() {
|
||||
let example = SwiftLintFile(contents: "func _abc(arg: String) {}")
|
||||
let violations = IdentifierNameRule().validate(file: example)
|
||||
XCTAssertEqual(
|
||||
violations.map(\.reason),
|
||||
["Function name \'_abc(arg:)\' should start with a lowercase character"]
|
||||
#expect(
|
||||
violations.map(\.reason)
|
||||
== ["Function name \'_abc(arg:)\' should start with a lowercase character"]
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,39 +1,43 @@
|
||||
@testable import SwiftLintBuiltInRules
|
||||
import TestHelpers
|
||||
import XCTest
|
||||
import Testing
|
||||
|
||||
final class ImplicitGetterRuleTests: SwiftLintTestCase {
|
||||
func testPropertyReason() throws {
|
||||
let config = try XCTUnwrap(makeConfig(nil, ImplicitGetterRule.identifier))
|
||||
@testable import SwiftLintBuiltInRules
|
||||
|
||||
@Suite(.rulesRegistered)
|
||||
struct ImplicitGetterRuleTests {
|
||||
@Test
|
||||
func propertyReason() throws {
|
||||
let config = try #require(makeConfig(nil, ImplicitGetterRule.identifier))
|
||||
let example = Example("""
|
||||
class Foo {
|
||||
var foo: Int {
|
||||
↓get {
|
||||
return 20
|
||||
class Foo {
|
||||
var foo: Int {
|
||||
↓get {
|
||||
return 20
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
""")
|
||||
""")
|
||||
|
||||
let violations = violations(example, config: config)
|
||||
XCTAssertEqual(violations.count, 1)
|
||||
XCTAssertEqual(violations.first?.reason, "Computed read-only properties should avoid using the get keyword")
|
||||
#expect(violations.count == 1)
|
||||
#expect(violations.first?.reason == "Computed read-only properties should avoid using the get keyword")
|
||||
}
|
||||
|
||||
func testSubscriptReason() throws {
|
||||
let config = try XCTUnwrap(makeConfig(nil, ImplicitGetterRule.identifier))
|
||||
@Test
|
||||
func subscriptReason() throws {
|
||||
let config = try #require(makeConfig(nil, ImplicitGetterRule.identifier))
|
||||
let example = Example("""
|
||||
class Foo {
|
||||
subscript(i: Int) -> Int {
|
||||
↓get {
|
||||
return 20
|
||||
class Foo {
|
||||
subscript(i: Int) -> Int {
|
||||
↓get {
|
||||
return 20
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
""")
|
||||
""")
|
||||
|
||||
let violations = violations(example, config: config)
|
||||
XCTAssertEqual(violations.count, 1)
|
||||
XCTAssertEqual(violations.first?.reason, "Computed read-only subscripts should avoid using the get keyword")
|
||||
#expect(violations.count == 1)
|
||||
#expect(violations.first?.reason == "Computed read-only subscripts should avoid using the get keyword")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
@testable import SwiftLintBuiltInRules
|
||||
import TestHelpers
|
||||
import XCTest
|
||||
import Testing
|
||||
|
||||
final class ImplicitReturnConfigurationTests: SwiftLintTestCase {
|
||||
func testImplicitReturnConfigurationFromDictionary() throws {
|
||||
@Suite(.rulesRegistered)
|
||||
struct ImplicitReturnConfigurationTests {
|
||||
@Test
|
||||
func implicitReturnConfigurationFromDictionary() throws {
|
||||
var configuration = ImplicitReturnConfiguration(includedKinds: Set<ImplicitReturnConfiguration.ReturnKind>())
|
||||
let config: [String: Any] = [
|
||||
"severity": "error",
|
||||
@@ -24,11 +26,12 @@ final class ImplicitReturnConfigurationTests: SwiftLintTestCase {
|
||||
.initializer,
|
||||
.subscript,
|
||||
])
|
||||
XCTAssertEqual(configuration.severityConfiguration.severity, .error)
|
||||
XCTAssertEqual(configuration.includedKinds, expectedKinds)
|
||||
#expect(configuration.severityConfiguration.severity == .error)
|
||||
#expect(configuration.includedKinds == expectedKinds)
|
||||
}
|
||||
|
||||
func testImplicitReturnConfigurationThrowsOnUnrecognizedModifierGroup() {
|
||||
@Test
|
||||
func implicitReturnConfigurationThrowsOnUnrecognizedModifierGroup() {
|
||||
var configuration = ImplicitReturnConfiguration()
|
||||
let config = ["included": ["foreach"]] as [String: any Sendable]
|
||||
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
@testable import SwiftLintBuiltInRules
|
||||
import TestHelpers
|
||||
import Testing
|
||||
|
||||
final class ImplicitReturnRuleTests: SwiftLintTestCase {
|
||||
func testOnlyClosureKindIncluded() {
|
||||
@testable import SwiftLintBuiltInRules
|
||||
|
||||
@Suite(.rulesRegistered)
|
||||
struct ImplicitReturnRuleTests {
|
||||
@Test
|
||||
func onlyClosureKindIncluded() {
|
||||
var nonTriggeringExamples = ImplicitReturnRuleExamples.nonTriggeringExamples +
|
||||
ImplicitReturnRuleExamples.triggeringExamples
|
||||
nonTriggeringExamples.removeAll(
|
||||
@@ -17,7 +21,8 @@ final class ImplicitReturnRuleTests: SwiftLintTestCase {
|
||||
)
|
||||
}
|
||||
|
||||
func testOnlyFunctionKindIncluded() {
|
||||
@Test
|
||||
func onlyFunctionKindIncluded() {
|
||||
var nonTriggeringExamples = ImplicitReturnRuleExamples.nonTriggeringExamples +
|
||||
ImplicitReturnRuleExamples.triggeringExamples
|
||||
nonTriggeringExamples.removeAll(
|
||||
@@ -32,7 +37,8 @@ final class ImplicitReturnRuleTests: SwiftLintTestCase {
|
||||
)
|
||||
}
|
||||
|
||||
func testOnlyGetterKindIncluded() {
|
||||
@Test
|
||||
func onlyGetterKindIncluded() {
|
||||
var nonTriggeringExamples = ImplicitReturnRuleExamples.nonTriggeringExamples +
|
||||
ImplicitReturnRuleExamples.triggeringExamples
|
||||
nonTriggeringExamples.removeAll(
|
||||
@@ -47,7 +53,8 @@ final class ImplicitReturnRuleTests: SwiftLintTestCase {
|
||||
)
|
||||
}
|
||||
|
||||
func testOnlyInitializerKindIncluded() {
|
||||
@Test
|
||||
func onlyInitializerKindIncluded() {
|
||||
var nonTriggeringExamples = ImplicitReturnRuleExamples.nonTriggeringExamples +
|
||||
ImplicitReturnRuleExamples.triggeringExamples
|
||||
nonTriggeringExamples.removeAll(
|
||||
@@ -62,7 +69,8 @@ final class ImplicitReturnRuleTests: SwiftLintTestCase {
|
||||
)
|
||||
}
|
||||
|
||||
func testOnlySubscriptKindIncluded() {
|
||||
@Test
|
||||
func onlySubscriptKindIncluded() {
|
||||
var nonTriggeringExamples = ImplicitReturnRuleExamples.nonTriggeringExamples +
|
||||
ImplicitReturnRuleExamples.triggeringExamples
|
||||
nonTriggeringExamples.removeAll(
|
||||
@@ -88,6 +96,6 @@ final class ImplicitReturnRuleTests: SwiftLintTestCase {
|
||||
.with(triggeringExamples: triggeringExamples)
|
||||
.with(corrections: corrections)
|
||||
|
||||
self.verifyRule(description, ruleConfiguration: ["included": [kind.rawValue]])
|
||||
verifyRule(description, ruleConfiguration: ["included": [kind.rawValue]])
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,33 +1,37 @@
|
||||
@testable import SwiftLintBuiltInRules
|
||||
import TestHelpers
|
||||
import XCTest
|
||||
import Testing
|
||||
|
||||
// swiftlint:disable:next type_name
|
||||
final class ImplicitlyUnwrappedOptionalConfigurationTests: SwiftLintTestCase {
|
||||
func testImplicitlyUnwrappedOptionalConfigurationProperlyAppliesConfigurationFromDictionary() throws {
|
||||
@testable import SwiftLintBuiltInRules
|
||||
|
||||
@Suite(.rulesRegistered)
|
||||
struct ImplicitlyUnwrappedOptionalConfigurationTests { // swiftlint:disable:this type_name
|
||||
|
||||
@Test
|
||||
func implicitlyUnwrappedOptionalConfigurationProperlyAppliesConfigurationFromDictionary() throws {
|
||||
var configuration = ImplicitlyUnwrappedOptionalConfiguration(
|
||||
severityConfiguration: SeverityConfiguration(.warning),
|
||||
mode: .allExceptIBOutlets
|
||||
)
|
||||
|
||||
try configuration.apply(configuration: ["mode": "all", "severity": "error"])
|
||||
XCTAssertEqual(configuration.mode, .all)
|
||||
XCTAssertEqual(configuration.severity, .error)
|
||||
#expect(configuration.mode == .all)
|
||||
#expect(configuration.severity == .error)
|
||||
|
||||
try configuration.apply(configuration: ["mode": "all_except_iboutlets"])
|
||||
XCTAssertEqual(configuration.mode, .allExceptIBOutlets)
|
||||
XCTAssertEqual(configuration.severity, .error)
|
||||
#expect(configuration.mode == .allExceptIBOutlets)
|
||||
#expect(configuration.severity == .error)
|
||||
|
||||
try configuration.apply(configuration: ["severity": "warning"])
|
||||
XCTAssertEqual(configuration.mode, .allExceptIBOutlets)
|
||||
XCTAssertEqual(configuration.severity, .warning)
|
||||
#expect(configuration.mode == .allExceptIBOutlets)
|
||||
#expect(configuration.severity == .warning)
|
||||
|
||||
try configuration.apply(configuration: ["mode": "all", "severity": "warning"])
|
||||
XCTAssertEqual(configuration.mode, .all)
|
||||
XCTAssertEqual(configuration.severity, .warning)
|
||||
#expect(configuration.mode == .all)
|
||||
#expect(configuration.severity == .warning)
|
||||
}
|
||||
|
||||
func testImplicitlyUnwrappedOptionalConfigurationThrowsOnBadConfig() {
|
||||
@Test
|
||||
func implicitlyUnwrappedOptionalConfigurationThrowsOnBadConfig() {
|
||||
let badConfigs: [[String: Any]] = [
|
||||
["mode": "everything"],
|
||||
["mode": false],
|
||||
@@ -40,7 +44,7 @@ final class ImplicitlyUnwrappedOptionalConfigurationTests: SwiftLintTestCase {
|
||||
mode: .allExceptIBOutlets
|
||||
)
|
||||
|
||||
checkError(Issue.invalidConfiguration(ruleID: ImplicitlyUnwrappedOptionalRule.identifier)) {
|
||||
#expect(throws: Issue.invalidConfiguration(ruleID: ImplicitlyUnwrappedOptionalRule.identifier)) {
|
||||
try configuration.apply(configuration: badConfig)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,15 +1,19 @@
|
||||
@testable import SwiftLintBuiltInRules
|
||||
import TestHelpers
|
||||
import XCTest
|
||||
import Testing
|
||||
|
||||
final class ImplicitlyUnwrappedOptionalRuleTests: SwiftLintTestCase {
|
||||
func testImplicitlyUnwrappedOptionalRuleDefaultConfiguration() {
|
||||
@testable import SwiftLintBuiltInRules
|
||||
|
||||
@Suite(.rulesRegistered)
|
||||
struct ImplicitlyUnwrappedOptionalRuleTests {
|
||||
@Test
|
||||
func implicitlyUnwrappedOptionalRuleDefaultConfiguration() {
|
||||
let rule = ImplicitlyUnwrappedOptionalRule()
|
||||
XCTAssertEqual(rule.configuration.mode, .allExceptIBOutlets)
|
||||
XCTAssertEqual(rule.configuration.severity, .warning)
|
||||
#expect(rule.configuration.mode == .allExceptIBOutlets)
|
||||
#expect(rule.configuration.severity == .warning)
|
||||
}
|
||||
|
||||
func testImplicitlyUnwrappedOptionalRuleWarnsOnOutletsInAllMode() {
|
||||
@Test
|
||||
func implicitlyUnwrappedOptionalRuleWarnsOnOutletsInAllMode() {
|
||||
let baseDescription = ImplicitlyUnwrappedOptionalRule.description
|
||||
let triggeringExamples = [
|
||||
Example("@IBOutlet private var label: UILabel!"),
|
||||
@@ -25,7 +29,8 @@ final class ImplicitlyUnwrappedOptionalRuleTests: SwiftLintTestCase {
|
||||
commentDoesntViolate: true, stringDoesntViolate: true)
|
||||
}
|
||||
|
||||
func testImplicitlyUnwrappedOptionalRuleWarnsOnOutletsInWeakMode() {
|
||||
@Test
|
||||
func implicitlyUnwrappedOptionalRuleWarnsOnOutletsInWeakMode() {
|
||||
let baseDescription = ImplicitlyUnwrappedOptionalRule.description
|
||||
let triggeringExamples = [
|
||||
Example("private weak var label: ↓UILabel!"),
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
@testable import SwiftLintBuiltInRules
|
||||
import TestHelpers
|
||||
import Testing
|
||||
|
||||
final class InclusiveLanguageRuleTests: SwiftLintTestCase {
|
||||
func testNonTriggeringExamplesWithNonDefaultConfig() {
|
||||
@testable import SwiftLintBuiltInRules
|
||||
|
||||
@Suite(.rulesRegistered)
|
||||
struct InclusiveLanguageRuleTests {
|
||||
@Test
|
||||
func nonTriggeringExamplesWithNonDefaultConfig() {
|
||||
InclusiveLanguageRuleExamples.nonTriggeringExamplesWithConfig.forEach { example in
|
||||
let description = InclusiveLanguageRule.description
|
||||
.with(nonTriggeringExamples: [example])
|
||||
@@ -11,7 +15,8 @@ final class InclusiveLanguageRuleTests: SwiftLintTestCase {
|
||||
}
|
||||
}
|
||||
|
||||
func testTriggeringExamplesWithNonDefaultConfig() {
|
||||
@Test
|
||||
func triggeringExamplesWithNonDefaultConfig() {
|
||||
InclusiveLanguageRuleExamples.triggeringExamplesWithConfig.forEach { example in
|
||||
let description = InclusiveLanguageRule.description
|
||||
.with(nonTriggeringExamples: [])
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
import TestHelpers
|
||||
import Testing
|
||||
|
||||
@testable import SwiftLintBuiltInRules
|
||||
@testable import SwiftLintCore
|
||||
import TestHelpers
|
||||
import XCTest
|
||||
|
||||
final class IndentationWidthRuleTests: SwiftLintTestCase {
|
||||
func testInvalidIndentation() async throws {
|
||||
@Suite(.rulesRegistered)
|
||||
struct IndentationWidthRuleTests {
|
||||
@Test
|
||||
func invalidIndentation() async throws {
|
||||
let defaultValue = IndentationWidthConfiguration().indentationWidth
|
||||
|
||||
for indentation in [0, -1, -5] {
|
||||
@@ -13,17 +16,17 @@ final class IndentationWidthRuleTests: SwiftLintTestCase {
|
||||
try testee.apply(configuration: ["indentation_width": indentation])
|
||||
|
||||
// Value remains the default.
|
||||
XCTAssertEqual(testee.indentationWidth, defaultValue)
|
||||
#expect(testee.indentationWidth == defaultValue)
|
||||
}
|
||||
XCTAssertEqual(
|
||||
console,
|
||||
"warning: Invalid configuration for 'indentation_width' rule. Falling back to default."
|
||||
#expect(
|
||||
console == "warning: Invalid configuration for 'indentation_width' rule. Falling back to default."
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/// It's not okay to have the first line indented.
|
||||
func testFirstLineIndentation() {
|
||||
@Test
|
||||
func firstLineIndentation() {
|
||||
assert1Violation(in: " firstLine")
|
||||
assert1Violation(in: " firstLine")
|
||||
assert1Violation(in: " firstLine")
|
||||
@@ -33,28 +36,32 @@ final class IndentationWidthRuleTests: SwiftLintTestCase {
|
||||
}
|
||||
|
||||
/// It's not okay to indent using both tabs and spaces in one line.
|
||||
func testMixedTabSpaceIndentation() {
|
||||
@Test
|
||||
func mixedTabSpaceIndentation() {
|
||||
// Expect 2 violations as secondLine is also indented by 8 spaces (which isn't valid)
|
||||
assertViolations(in: "firstLine\n\t secondLine", equals: 2)
|
||||
assertViolations(in: "firstLine\n \tsecondLine", equals: 2)
|
||||
}
|
||||
|
||||
/// It's okay to indent using either tabs or spaces in different lines.
|
||||
func testMixedTabsAndSpacesIndentation() {
|
||||
@Test
|
||||
func mixedTabsAndSpacesIndentation() {
|
||||
assertNoViolation(in: "firstLine\n\tsecondLine\n thirdLine")
|
||||
assertNoViolation(in: "firstLine\n secondLine\n\t\tthirdLine")
|
||||
assertNoViolation(in: "firstLine\n\tsecondLine\n thirdLine\n\t\t\tfourthLine")
|
||||
}
|
||||
|
||||
/// It's okay to keep the same indentation.
|
||||
func testKeepingIndentation() {
|
||||
@Test
|
||||
func keepingIndentation() {
|
||||
assertNoViolation(in: "firstLine\nsecondLine")
|
||||
assertNoViolation(in: "firstLine \nsecondLine\n thirdLine")
|
||||
assertNoViolation(in: "firstLine\t\nsecondLine\n\tthirdLine")
|
||||
}
|
||||
|
||||
/// It's only okay to indent using one tab or indentationWidth spaces.
|
||||
func testIndentationLength() {
|
||||
@Test
|
||||
func indentationLength() {
|
||||
assert1Violation(in: "firstLine\n secondLine", indentationWidth: 1)
|
||||
assert1Violation(in: "firstLine\n secondLine", indentationWidth: 2)
|
||||
assert1Violation(in: "firstLine\n secondLine", indentationWidth: 3)
|
||||
@@ -78,7 +85,8 @@ final class IndentationWidthRuleTests: SwiftLintTestCase {
|
||||
}
|
||||
|
||||
/// It's okay to unindent indentationWidth * (1, 2, 3, ...) - x iff x == 0.
|
||||
func testUnindentation() {
|
||||
@Test
|
||||
func unindentation() {
|
||||
assert1Violation(in: "firstLine\n secondLine\n thirdLine\n fourthLine")
|
||||
assert1Violation(in: "firstLine\n secondLine\n thirdLine\n fourthLine")
|
||||
assert1Violation(in: "firstLine\n secondLine\n thirdLine\n fourthLine")
|
||||
@@ -90,7 +98,8 @@ final class IndentationWidthRuleTests: SwiftLintTestCase {
|
||||
}
|
||||
|
||||
/// It's okay to have empty lines between iff the following indentations obey the rules.
|
||||
func testEmptyLinesBetween() {
|
||||
@Test
|
||||
func emptyLinesBetween() {
|
||||
assertNoViolation(in: "firstLine\n\tsecondLine\n\n\tfourthLine")
|
||||
assertNoViolation(in: "firstLine\n\tsecondLine\n \n\tfourthLine")
|
||||
assertNoViolation(in: "firstLine\n\tsecondLine\n \n\tfourthLine")
|
||||
@@ -106,7 +115,8 @@ final class IndentationWidthRuleTests: SwiftLintTestCase {
|
||||
assert1Violation(in: "firstLine\n\tsecondLine\n \n fourthLine")
|
||||
}
|
||||
|
||||
func testsBrackets() {
|
||||
@Test
|
||||
func sBrackets() {
|
||||
assertNoViolation(
|
||||
in: "firstLine\n [\n .thirdLine\n ]\nfifthLine",
|
||||
includeComments: true
|
||||
@@ -129,7 +139,8 @@ final class IndentationWidthRuleTests: SwiftLintTestCase {
|
||||
}
|
||||
|
||||
/// It's okay to have comments not following the indentation pattern iff the configuration allows this.
|
||||
func testCommentLines() {
|
||||
@Test
|
||||
func commentLines() {
|
||||
assert1Violation(
|
||||
in: "firstLine\n\tsecondLine\n\t\tthirdLine\n//test\n\t\tfourthLine",
|
||||
includeComments: true
|
||||
@@ -160,7 +171,8 @@ final class IndentationWidthRuleTests: SwiftLintTestCase {
|
||||
}
|
||||
|
||||
/// Duplicate warnings for one actual indentation issue should be avoided.
|
||||
func testDuplicateWarningAvoidanceMechanism() {
|
||||
@Test
|
||||
func duplicateWarningAvoidanceMechanism() {
|
||||
// thirdLine is indented correctly, yet not in-line with the badly indented secondLine. This should be allowed.
|
||||
assert1Violation(in: "firstLine\n secondLine\nthirdLine")
|
||||
|
||||
@@ -181,7 +193,8 @@ final class IndentationWidthRuleTests: SwiftLintTestCase {
|
||||
assertViolations(in: "firstLine\n secondLine\n thirdLine\n fourthLine\n fifthLine", equals: 2)
|
||||
}
|
||||
|
||||
func testIgnoredCompilerDirectives() {
|
||||
@Test
|
||||
func ignoredCompilerDirectives() {
|
||||
assertNoViolation(in: """
|
||||
struct S {
|
||||
#if os(iOS)
|
||||
@@ -215,7 +228,8 @@ final class IndentationWidthRuleTests: SwiftLintTestCase {
|
||||
""", includeCompilerDirectives: true)
|
||||
}
|
||||
|
||||
func testIncludeMultilineStrings() {
|
||||
@Test
|
||||
func includeMultilineStrings() {
|
||||
let example0 = #"""
|
||||
let x = """
|
||||
string1
|
||||
@@ -274,9 +288,7 @@ final class IndentationWidthRuleTests: SwiftLintTestCase {
|
||||
indentationWidth: Int? = nil,
|
||||
includeComments: Bool = true,
|
||||
includeCompilerDirectives: Bool = true,
|
||||
includeMultilineStrings: Bool = true,
|
||||
file: StaticString = #filePath,
|
||||
line: UInt = #line
|
||||
includeMultilineStrings: Bool = true
|
||||
) -> Int {
|
||||
var configDict: [String: Any] = [:]
|
||||
if let indentationWidth {
|
||||
@@ -287,7 +299,7 @@ final class IndentationWidthRuleTests: SwiftLintTestCase {
|
||||
configDict["include_multiline_strings"] = includeMultilineStrings
|
||||
|
||||
guard let config = makeConfig(configDict, IndentationWidthRule.identifier) else {
|
||||
XCTFail("Unable to create rule configuration.", file: (file), line: line)
|
||||
Testing.Issue.record("Unable to create rule configuration.")
|
||||
return 0
|
||||
}
|
||||
|
||||
@@ -304,19 +316,20 @@ final class IndentationWidthRuleTests: SwiftLintTestCase {
|
||||
file: StaticString = #filePath,
|
||||
line: UInt = #line
|
||||
) {
|
||||
XCTAssertEqual(
|
||||
#expect(
|
||||
countViolations(
|
||||
in: Example(string, file: (file), line: line),
|
||||
indentationWidth: indentationWidth,
|
||||
includeComments: includeComments,
|
||||
includeCompilerDirectives: includeCompilerDirectives,
|
||||
includeMultilineStrings: includeMultilineStrings,
|
||||
file: file,
|
||||
line: line
|
||||
),
|
||||
expectedCount,
|
||||
file: (file),
|
||||
line: line
|
||||
includeMultilineStrings: includeMultilineStrings
|
||||
) == expectedCount,
|
||||
sourceLocation: SourceLocation(
|
||||
fileID: #fileID,
|
||||
filePath: String(describing: file),
|
||||
line: Int(line),
|
||||
column: 1
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,83 +1,95 @@
|
||||
@testable import SwiftLintBuiltInRules
|
||||
import TestHelpers
|
||||
import XCTest
|
||||
import Testing
|
||||
|
||||
final class LineLengthConfigurationTests: SwiftLintTestCase {
|
||||
@testable import SwiftLintBuiltInRules
|
||||
|
||||
@Suite(.rulesRegistered)
|
||||
struct LineLengthConfigurationTests {
|
||||
private let severityLevels = SeverityLevelsConfiguration<LineLengthRule>(warning: 100, error: 150)
|
||||
|
||||
func testLineLengthConfigurationInitializerSetsLength() {
|
||||
@Test
|
||||
func lineLengthConfigurationInitializerSetsLength() {
|
||||
let configuration1 = LineLengthConfiguration(length: severityLevels)
|
||||
XCTAssertEqual(configuration1.length, severityLevels)
|
||||
#expect(configuration1.length == severityLevels)
|
||||
|
||||
let length2 = SeverityLevelsConfiguration<LineLengthRule>(warning: 100, error: nil)
|
||||
let configuration2 = LineLengthConfiguration(length: length2)
|
||||
XCTAssertEqual(configuration2.length, length2)
|
||||
#expect(configuration2.length == length2)
|
||||
}
|
||||
|
||||
func testLineLengthConfigurationInitialiserSetsIgnoresURLs() {
|
||||
@Test
|
||||
func lineLengthConfigurationInitialiserSetsIgnoresURLs() {
|
||||
let configuration1 = LineLengthConfiguration(length: severityLevels, ignoresURLs: true)
|
||||
|
||||
XCTAssertTrue(configuration1.ignoresURLs)
|
||||
#expect(configuration1.ignoresURLs)
|
||||
|
||||
let configuration2 = LineLengthConfiguration(length: severityLevels)
|
||||
XCTAssertFalse(configuration2.ignoresURLs)
|
||||
#expect(!configuration2.ignoresURLs)
|
||||
}
|
||||
|
||||
func testLineLengthConfigurationInitialiserSetsIgnoresFunctionDeclarations() {
|
||||
@Test
|
||||
func lineLengthConfigurationInitialiserSetsIgnoresFunctionDeclarations() {
|
||||
let configuration1 = LineLengthConfiguration(length: severityLevels, ignoresFunctionDeclarations: true)
|
||||
XCTAssertTrue(configuration1.ignoresFunctionDeclarations)
|
||||
#expect(configuration1.ignoresFunctionDeclarations)
|
||||
|
||||
let configuration2 = LineLengthConfiguration(length: severityLevels)
|
||||
XCTAssertFalse(configuration2.ignoresFunctionDeclarations)
|
||||
#expect(!configuration2.ignoresFunctionDeclarations)
|
||||
}
|
||||
|
||||
func testLineLengthConfigurationInitialiserSetsIgnoresComments() {
|
||||
@Test
|
||||
func lineLengthConfigurationInitialiserSetsIgnoresComments() {
|
||||
let configuration1 = LineLengthConfiguration(length: severityLevels, ignoresComments: true)
|
||||
XCTAssertTrue(configuration1.ignoresComments)
|
||||
#expect(configuration1.ignoresComments)
|
||||
|
||||
let configuration2 = LineLengthConfiguration(length: severityLevels)
|
||||
XCTAssertFalse(configuration2.ignoresComments)
|
||||
#expect(!configuration2.ignoresComments)
|
||||
}
|
||||
|
||||
func testLineLengthConfigurationInitialiserSetsIgnoresInterpolatedStrings() {
|
||||
@Test
|
||||
func lineLengthConfigurationInitialiserSetsIgnoresInterpolatedStrings() {
|
||||
let configuration1 = LineLengthConfiguration(length: severityLevels, ignoresInterpolatedStrings: true)
|
||||
XCTAssertTrue(configuration1.ignoresInterpolatedStrings)
|
||||
#expect(configuration1.ignoresInterpolatedStrings)
|
||||
|
||||
let configuration2 = LineLengthConfiguration(length: severityLevels)
|
||||
XCTAssertFalse(configuration2.ignoresInterpolatedStrings)
|
||||
#expect(!configuration2.ignoresInterpolatedStrings)
|
||||
}
|
||||
|
||||
func testLineLengthConfigurationInitialiserSetsIgnoresMultilineStrings() {
|
||||
@Test
|
||||
func lineLengthConfigurationInitialiserSetsIgnoresMultilineStrings() {
|
||||
let configuration1 = LineLengthConfiguration(length: severityLevels, ignoresMultilineStrings: true)
|
||||
XCTAssertTrue(configuration1.ignoresMultilineStrings)
|
||||
#expect(configuration1.ignoresMultilineStrings)
|
||||
|
||||
let configuration2 = LineLengthConfiguration(length: severityLevels)
|
||||
XCTAssertFalse(configuration2.ignoresMultilineStrings)
|
||||
#expect(!configuration2.ignoresMultilineStrings)
|
||||
}
|
||||
|
||||
func testLineLengthConfigurationInitialiserSetsExcludedLinesPatterns() {
|
||||
@Test
|
||||
func lineLengthConfigurationInitialiserSetsExcludedLinesPatterns() {
|
||||
let patterns: Set = ["foo", "bar"]
|
||||
let configuration1 = LineLengthConfiguration(length: severityLevels, excludedLinesPatterns: patterns)
|
||||
XCTAssertEqual(configuration1.excludedLinesPatterns, patterns)
|
||||
#expect(configuration1.excludedLinesPatterns == patterns)
|
||||
|
||||
let configuration2 = LineLengthConfiguration(length: severityLevels)
|
||||
XCTAssertTrue(configuration2.excludedLinesPatterns.isEmpty)
|
||||
#expect(configuration2.excludedLinesPatterns.isEmpty)
|
||||
}
|
||||
|
||||
func testLineLengthConfigurationParams() {
|
||||
@Test
|
||||
func lineLengthConfigurationParams() {
|
||||
let warning = 13
|
||||
let error = 10
|
||||
let configuration = LineLengthConfiguration(length: SeverityLevelsConfiguration(warning: warning, error: error))
|
||||
let params = [RuleParameter(severity: .error, value: error), RuleParameter(severity: .warning, value: warning)]
|
||||
XCTAssertEqual(configuration.params, params)
|
||||
#expect(configuration.params == params)
|
||||
}
|
||||
|
||||
func testLineLengthConfigurationPartialParams() {
|
||||
@Test
|
||||
func lineLengthConfigurationPartialParams() {
|
||||
let configuration = LineLengthConfiguration(length: SeverityLevelsConfiguration(warning: 13))
|
||||
XCTAssertEqual(configuration.params, [RuleParameter(severity: .warning, value: 13)])
|
||||
#expect(configuration.params == [RuleParameter(severity: .warning, value: 13)])
|
||||
}
|
||||
|
||||
func testLineLengthConfigurationThrowsOnBadConfig() {
|
||||
@Test
|
||||
func lineLengthConfigurationThrowsOnBadConfig() {
|
||||
let config = ["warning": "unknown"]
|
||||
var configuration = LineLengthConfiguration(length: severityLevels)
|
||||
checkError(Issue.invalidConfiguration(ruleID: LineLengthRule.identifier)) {
|
||||
@@ -85,7 +97,8 @@ final class LineLengthConfigurationTests: SwiftLintTestCase {
|
||||
}
|
||||
}
|
||||
|
||||
func testLineLengthConfigurationThrowsOnBadConfigValues() {
|
||||
@Test
|
||||
func lineLengthConfigurationThrowsOnBadConfigValues() {
|
||||
let badConfigs: [[String: Any]] = [
|
||||
["warning": true],
|
||||
["ignores_function_declarations": 300],
|
||||
@@ -99,7 +112,8 @@ final class LineLengthConfigurationTests: SwiftLintTestCase {
|
||||
}
|
||||
}
|
||||
|
||||
func testLineLengthConfigurationApplyConfigurationWithArray() throws {
|
||||
@Test
|
||||
func lineLengthConfigurationApplyConfigurationWithArray() throws {
|
||||
var configuration = LineLengthConfiguration(length: SeverityLevelsConfiguration(warning: 0, error: 0))
|
||||
|
||||
let warning1 = 100
|
||||
@@ -112,13 +126,14 @@ final class LineLengthConfigurationTests: SwiftLintTestCase {
|
||||
let config2 = [warning2]
|
||||
|
||||
try configuration.apply(configuration: config1)
|
||||
XCTAssertEqual(configuration.length, length1)
|
||||
#expect(configuration.length == length1)
|
||||
|
||||
try configuration.apply(configuration: config2)
|
||||
XCTAssertEqual(configuration.length, length2)
|
||||
#expect(configuration.length == length2)
|
||||
}
|
||||
|
||||
func testLineLengthConfigurationApplyConfigurationWithDictionary() throws {
|
||||
@Test
|
||||
func lineLengthConfigurationApplyConfigurationWithDictionary() throws {
|
||||
var configuration = LineLengthConfiguration(length: SeverityLevelsConfiguration(warning: 0, error: 0))
|
||||
|
||||
let warning1 = 100
|
||||
@@ -144,47 +159,48 @@ final class LineLengthConfigurationTests: SwiftLintTestCase {
|
||||
]
|
||||
|
||||
try configuration.apply(configuration: config1)
|
||||
XCTAssertEqual(configuration.length, length1)
|
||||
XCTAssertTrue(configuration.ignoresURLs)
|
||||
XCTAssertTrue(configuration.ignoresFunctionDeclarations)
|
||||
XCTAssertTrue(configuration.ignoresComments)
|
||||
#expect(configuration.length == length1)
|
||||
#expect(configuration.ignoresURLs)
|
||||
#expect(configuration.ignoresFunctionDeclarations)
|
||||
#expect(configuration.ignoresComments)
|
||||
|
||||
try configuration.apply(configuration: config2)
|
||||
XCTAssertEqual(configuration.length, length2)
|
||||
XCTAssertTrue(configuration.ignoresURLs)
|
||||
XCTAssertTrue(configuration.ignoresFunctionDeclarations)
|
||||
XCTAssertTrue(configuration.ignoresComments)
|
||||
#expect(configuration.length == length2)
|
||||
#expect(configuration.ignoresURLs)
|
||||
#expect(configuration.ignoresFunctionDeclarations)
|
||||
#expect(configuration.ignoresComments)
|
||||
|
||||
try configuration.apply(configuration: config3)
|
||||
XCTAssertEqual(configuration.length, length2)
|
||||
XCTAssertFalse(configuration.ignoresURLs)
|
||||
XCTAssertFalse(configuration.ignoresFunctionDeclarations)
|
||||
XCTAssertFalse(configuration.ignoresComments)
|
||||
#expect(configuration.length == length2)
|
||||
#expect(!configuration.ignoresURLs)
|
||||
#expect(!configuration.ignoresFunctionDeclarations)
|
||||
#expect(!configuration.ignoresComments)
|
||||
}
|
||||
|
||||
func testLineLengthConfigurationCompares() {
|
||||
@Test
|
||||
func lineLengthConfigurationCompares() {
|
||||
let configuration1 = LineLengthConfiguration(length: SeverityLevelsConfiguration(warning: 100, error: 100))
|
||||
let configuration2 = LineLengthConfiguration(
|
||||
length: SeverityLevelsConfiguration(warning: 100, error: 100),
|
||||
ignoresFunctionDeclarations: true,
|
||||
ignoresComments: true
|
||||
)
|
||||
XCTAssertNotEqual(configuration1, configuration2)
|
||||
#expect(configuration1 != configuration2)
|
||||
|
||||
let configuration3 = LineLengthConfiguration(length: SeverityLevelsConfiguration(warning: 100, error: 200))
|
||||
XCTAssertNotEqual(configuration1, configuration3)
|
||||
#expect(configuration1 != configuration3)
|
||||
|
||||
let configuration4 = LineLengthConfiguration(length: SeverityLevelsConfiguration(warning: 200, error: 200))
|
||||
XCTAssertNotEqual(configuration1, configuration4)
|
||||
#expect(configuration1 != configuration4)
|
||||
|
||||
let configuration5 = LineLengthConfiguration(length: SeverityLevelsConfiguration(warning: 100, error: 100))
|
||||
XCTAssertEqual(configuration1, configuration5)
|
||||
#expect(configuration1 == configuration5)
|
||||
|
||||
let configuration6 = LineLengthConfiguration(
|
||||
length: SeverityLevelsConfiguration(warning: 100, error: 100),
|
||||
ignoresFunctionDeclarations: true,
|
||||
ignoresComments: true
|
||||
)
|
||||
XCTAssertEqual(configuration2, configuration6)
|
||||
#expect(configuration2 == configuration6)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
@testable import SwiftLintBuiltInRules
|
||||
import TestHelpers
|
||||
import Testing
|
||||
|
||||
final class LineLengthRuleTests: SwiftLintTestCase {
|
||||
@testable import SwiftLintBuiltInRules
|
||||
|
||||
@Suite(.rulesRegistered)
|
||||
struct LineLengthRuleTests {
|
||||
private static let longString = String(repeating: "a", count: 121)
|
||||
|
||||
private let longFunctionDeclarations = [
|
||||
@@ -50,53 +53,55 @@ final class LineLengthRuleTests: SwiftLintTestCase {
|
||||
private let longBlockComment = Example("/*" + String(repeating: " ", count: 121) + "*/\n")
|
||||
private let longRealBlockComment = Example("""
|
||||
/*
|
||||
\(LineLengthRuleTests.longString)
|
||||
\(Self.longString)
|
||||
*/
|
||||
|
||||
""")
|
||||
private let declarationWithTrailingLongComment = Example("let foo = 1 " + String(repeating: "/", count: 121) + "\n")
|
||||
private let interpolatedString = Example("print(\"\\(value)" + String(repeating: "A", count: 113) + "\" )\n")
|
||||
private let plainString = Example("print(\"" + LineLengthRuleTests.longString + ")\"\n")
|
||||
private let plainString = Example("print(\"" + Self.longString + ")\"\n")
|
||||
|
||||
private let multilineString = Example("""
|
||||
let multilineString = \"\"\"
|
||||
\(LineLengthRuleTests.longString)
|
||||
\(Self.longString)
|
||||
\"\"\"
|
||||
|
||||
""")
|
||||
private let tripleStringSingleLine = Example(
|
||||
"let tripleString = \"\"\"\(LineLengthRuleTests.longString)\"\"\"\n"
|
||||
"let tripleString = \"\"\"\(Self.longString)\"\"\"\n"
|
||||
)
|
||||
private let poundStringSingleLine = Example("let poundString = #\"\(LineLengthRuleTests.longString)\"#\n")
|
||||
private let poundStringSingleLine = Example("let poundString = #\"\(Self.longString)\"#\n")
|
||||
private let multilineStringWithExpression = Example("""
|
||||
let multilineString = \"\"\"
|
||||
\(LineLengthRuleTests.longString)
|
||||
\(Self.longString)
|
||||
|
||||
\"\"\"; let a = 1
|
||||
""")
|
||||
private let multilineStringWithNewlineExpression = Example("""
|
||||
let multilineString = \"\"\"
|
||||
\(LineLengthRuleTests.longString)
|
||||
\(Self.longString)
|
||||
|
||||
\"\"\"
|
||||
; let a = 1
|
||||
""")
|
||||
private let multilineStringFail = Example("""
|
||||
let multilineString = "A" +
|
||||
"\(LineLengthRuleTests.longString)"
|
||||
"\(Self.longString)"
|
||||
|
||||
""")
|
||||
private let multilineStringWithFunction = Example("""
|
||||
let multilineString = \"\"\"
|
||||
\(LineLengthRuleTests.longString)
|
||||
\(Self.longString)
|
||||
\"\"\".functionCall()
|
||||
""")
|
||||
|
||||
func testLineLength() {
|
||||
@Test
|
||||
func lineLength() {
|
||||
verifyRule(LineLengthRule.description, commentDoesntViolate: false, stringDoesntViolate: false)
|
||||
}
|
||||
|
||||
func testLineLengthWithIgnoreFunctionDeclarationsEnabled() {
|
||||
@Test
|
||||
func lineLengthWithIgnoreFunctionDeclarationsEnabled() {
|
||||
let baseDescription = LineLengthRule.description
|
||||
let nonTriggeringExamples = baseDescription.nonTriggeringExamples + longFunctionDeclarations
|
||||
let description = baseDescription.with(nonTriggeringExamples: nonTriggeringExamples)
|
||||
@@ -109,7 +114,8 @@ final class LineLengthRuleTests: SwiftLintTestCase {
|
||||
)
|
||||
}
|
||||
|
||||
func testLineLengthWithIgnoreCommentsEnabled() {
|
||||
@Test
|
||||
func lineLengthWithIgnoreCommentsEnabled() {
|
||||
let baseDescription = LineLengthRule.description
|
||||
let triggeringExamples = longFunctionDeclarations + [declarationWithTrailingLongComment]
|
||||
let nonTriggeringExamples = [longComment, longBlockComment, longRealBlockComment]
|
||||
@@ -121,7 +127,8 @@ final class LineLengthRuleTests: SwiftLintTestCase {
|
||||
commentDoesntViolate: false, stringDoesntViolate: false, skipCommentTests: true)
|
||||
}
|
||||
|
||||
func testLineLengthWithIgnoreURLsEnabled() {
|
||||
@Test
|
||||
func lineLengthWithIgnoreURLsEnabled() {
|
||||
let url = "https://github.com/realm/SwiftLint"
|
||||
let triggeringLines = [Example(String(repeating: "/", count: 121) + "\(url)\n")]
|
||||
let nonTriggeringLines = [
|
||||
@@ -140,7 +147,8 @@ final class LineLengthRuleTests: SwiftLintTestCase {
|
||||
commentDoesntViolate: false, stringDoesntViolate: false)
|
||||
}
|
||||
|
||||
func testLineLengthWithIgnoreInterpolatedStringsTrue() {
|
||||
@Test
|
||||
func lineLengthWithIgnoreInterpolatedStringsTrue() {
|
||||
let triggeringLines = [plainString]
|
||||
let nonTriggeringLines = [interpolatedString]
|
||||
|
||||
@@ -155,7 +163,8 @@ final class LineLengthRuleTests: SwiftLintTestCase {
|
||||
commentDoesntViolate: false, stringDoesntViolate: false)
|
||||
}
|
||||
|
||||
func testLineLengthWithIgnoreMultilineStringsTrue() {
|
||||
@Test
|
||||
func lineLengthWithIgnoreMultilineStringsTrue() {
|
||||
let triggeringLines = [
|
||||
multilineStringFail,
|
||||
tripleStringSingleLine,
|
||||
@@ -179,7 +188,8 @@ final class LineLengthRuleTests: SwiftLintTestCase {
|
||||
commentDoesntViolate: false, stringDoesntViolate: false)
|
||||
}
|
||||
|
||||
func testLineLengthWithIgnoreInterpolatedStringsFalse() {
|
||||
@Test
|
||||
func lineLengthWithIgnoreInterpolatedStringsFalse() {
|
||||
let triggeringLines = [plainString, interpolatedString]
|
||||
|
||||
let baseDescription = LineLengthRule.description
|
||||
@@ -193,7 +203,8 @@ final class LineLengthRuleTests: SwiftLintTestCase {
|
||||
commentDoesntViolate: false, stringDoesntViolate: false)
|
||||
}
|
||||
|
||||
func testLineLengthWithExcludedLinesPatterns() {
|
||||
@Test
|
||||
func lineLengthWithExcludedLinesPatterns() {
|
||||
let nonTriggeringLines = [plainString, interpolatedString]
|
||||
|
||||
let baseDescription = LineLengthRule.description
|
||||
@@ -212,7 +223,8 @@ final class LineLengthRuleTests: SwiftLintTestCase {
|
||||
)
|
||||
}
|
||||
|
||||
func testLineLengthWithEmptyExcludedLinesPatterns() {
|
||||
@Test
|
||||
func lineLengthWithEmptyExcludedLinesPatterns() {
|
||||
let triggeringLines = [plainString, interpolatedString]
|
||||
|
||||
let baseDescription = LineLengthRule.description
|
||||
|
||||
@@ -1,207 +1,230 @@
|
||||
@testable import SwiftLintBuiltInRules
|
||||
import TestHelpers
|
||||
import XCTest
|
||||
import Testing
|
||||
|
||||
final class MissingDocsRuleTests: SwiftLintTestCase {
|
||||
func testDescriptionEmpty() {
|
||||
@testable import SwiftLintBuiltInRules
|
||||
|
||||
@Suite(.rulesRegistered)
|
||||
struct MissingDocsRuleTests {
|
||||
@Test
|
||||
func descriptionEmpty() {
|
||||
let configuration = MissingDocsConfiguration()
|
||||
XCTAssertEqual(
|
||||
configuration.parameterDescription?.oneLiner(),
|
||||
"warning: [open, public]; excludes_extensions: true; " +
|
||||
"excludes_inherited_types: true; excludes_trivial_init: false; " +
|
||||
"evaluate_effective_access_control_level: false"
|
||||
#expect(
|
||||
configuration.parameterDescription?.oneLiner() == """
|
||||
warning: [open, public]; excludes_extensions: true; \
|
||||
excludes_inherited_types: true; excludes_trivial_init: false; \
|
||||
evaluate_effective_access_control_level: false
|
||||
"""
|
||||
)
|
||||
}
|
||||
|
||||
func testDescriptionExcludesFalse() {
|
||||
@Test
|
||||
func descriptionExcludesFalse() {
|
||||
let configuration = MissingDocsConfiguration(excludesExtensions: false, excludesInheritedTypes: false)
|
||||
XCTAssertEqual(
|
||||
configuration.parameterDescription?.oneLiner(),
|
||||
"warning: [open, public]; excludes_extensions: false; " +
|
||||
"excludes_inherited_types: false; excludes_trivial_init: false; " +
|
||||
"evaluate_effective_access_control_level: false"
|
||||
#expect(
|
||||
configuration.parameterDescription?.oneLiner() == """
|
||||
warning: [open, public]; excludes_extensions: false; \
|
||||
excludes_inherited_types: false; excludes_trivial_init: false; \
|
||||
evaluate_effective_access_control_level: false
|
||||
"""
|
||||
)
|
||||
}
|
||||
|
||||
func testDescriptionExcludesExtensionsFalseExcludesInheritedTypesTrue() {
|
||||
@Test
|
||||
func descriptionExcludesExtensionsFalseExcludesInheritedTypesTrue() {
|
||||
let configuration = MissingDocsConfiguration(excludesExtensions: false, excludesInheritedTypes: true)
|
||||
XCTAssertEqual(
|
||||
configuration.parameterDescription?.oneLiner(),
|
||||
"warning: [open, public]; excludes_extensions: false; " +
|
||||
"excludes_inherited_types: true; excludes_trivial_init: false; " +
|
||||
"evaluate_effective_access_control_level: false"
|
||||
#expect(
|
||||
configuration.parameterDescription?.oneLiner() == """
|
||||
warning: [open, public]; excludes_extensions: false; \
|
||||
excludes_inherited_types: true; excludes_trivial_init: false; \
|
||||
evaluate_effective_access_control_level: false
|
||||
"""
|
||||
)
|
||||
}
|
||||
|
||||
func testDescriptionExcludesExtensionsTrueExcludesInheritedTypesFalse() {
|
||||
@Test
|
||||
func descriptionExcludesExtensionsTrueExcludesInheritedTypesFalse() {
|
||||
let configuration = MissingDocsConfiguration(
|
||||
excludesExtensions: true,
|
||||
excludesInheritedTypes: false,
|
||||
evaluateEffectiveAccessControlLevel: true
|
||||
)
|
||||
XCTAssertEqual(
|
||||
configuration.parameterDescription?.oneLiner(),
|
||||
"warning: [open, public]; excludes_extensions: true; " +
|
||||
"excludes_inherited_types: false; excludes_trivial_init: false; " +
|
||||
"evaluate_effective_access_control_level: true"
|
||||
#expect(
|
||||
configuration.parameterDescription?.oneLiner() == """
|
||||
warning: [open, public]; excludes_extensions: true; \
|
||||
excludes_inherited_types: false; excludes_trivial_init: false; \
|
||||
evaluate_effective_access_control_level: true
|
||||
"""
|
||||
)
|
||||
}
|
||||
|
||||
func testDescriptionSingleServety() {
|
||||
@Test
|
||||
func descriptionSingleServety() {
|
||||
let configuration = MissingDocsConfiguration(
|
||||
parameters: [RuleParameter<AccessControlLevel>(severity: .error, value: .open)])
|
||||
XCTAssertEqual(
|
||||
configuration.parameterDescription?.oneLiner(),
|
||||
"error: [open]; excludes_extensions: true; " +
|
||||
"excludes_inherited_types: true; excludes_trivial_init: false; " +
|
||||
"evaluate_effective_access_control_level: false"
|
||||
#expect(
|
||||
configuration.parameterDescription?.oneLiner() == """
|
||||
error: [open]; excludes_extensions: true; \
|
||||
excludes_inherited_types: true; excludes_trivial_init: false; \
|
||||
evaluate_effective_access_control_level: false
|
||||
"""
|
||||
)
|
||||
}
|
||||
|
||||
func testDescriptionMultipleSeverities() {
|
||||
@Test
|
||||
func descriptionMultipleSeverities() {
|
||||
let configuration = MissingDocsConfiguration(
|
||||
parameters: [
|
||||
RuleParameter<AccessControlLevel>(severity: .error, value: .open),
|
||||
RuleParameter<AccessControlLevel>(severity: .warning, value: .public),
|
||||
]
|
||||
)
|
||||
XCTAssertEqual(
|
||||
configuration.parameterDescription?.oneLiner(),
|
||||
"error: [open]; warning: [public]; excludes_extensions: true; " +
|
||||
"excludes_inherited_types: true; excludes_trivial_init: false; " +
|
||||
"evaluate_effective_access_control_level: false"
|
||||
#expect(
|
||||
configuration.parameterDescription?.oneLiner() == """
|
||||
error: [open]; warning: [public]; excludes_extensions: true; \
|
||||
excludes_inherited_types: true; excludes_trivial_init: false; \
|
||||
evaluate_effective_access_control_level: false
|
||||
"""
|
||||
)
|
||||
}
|
||||
|
||||
func testDescriptionMultipleAcls() {
|
||||
@Test
|
||||
func descriptionMultipleAcls() {
|
||||
let configuration = MissingDocsConfiguration(
|
||||
parameters: [
|
||||
RuleParameter<AccessControlLevel>(severity: .warning, value: .open),
|
||||
RuleParameter<AccessControlLevel>(severity: .warning, value: .public),
|
||||
]
|
||||
)
|
||||
XCTAssertEqual(
|
||||
configuration.parameterDescription?.oneLiner(),
|
||||
"warning: [open, public]; excludes_extensions: true; " +
|
||||
"excludes_inherited_types: true; excludes_trivial_init: false; " +
|
||||
"evaluate_effective_access_control_level: false"
|
||||
#expect(
|
||||
configuration.parameterDescription?.oneLiner() == """
|
||||
warning: [open, public]; excludes_extensions: true; \
|
||||
excludes_inherited_types: true; excludes_trivial_init: false; \
|
||||
evaluate_effective_access_control_level: false
|
||||
"""
|
||||
)
|
||||
}
|
||||
|
||||
func testDescriptionExcludesTrivialInitTrue() {
|
||||
@Test
|
||||
func descriptionExcludesTrivialInitTrue() {
|
||||
let configuration = MissingDocsConfiguration(excludesTrivialInit: true)
|
||||
XCTAssertEqual(
|
||||
configuration.parameterDescription?.oneLiner(),
|
||||
"warning: [open, public]; excludes_extensions: true; " +
|
||||
"excludes_inherited_types: true; excludes_trivial_init: true; " +
|
||||
"evaluate_effective_access_control_level: false"
|
||||
#expect(
|
||||
configuration.parameterDescription?.oneLiner() == """
|
||||
warning: [open, public]; excludes_extensions: true; \
|
||||
excludes_inherited_types: true; excludes_trivial_init: true; \
|
||||
evaluate_effective_access_control_level: false
|
||||
"""
|
||||
)
|
||||
}
|
||||
|
||||
func testParsingSingleServety() {
|
||||
@Test
|
||||
func parsingSingleServety() {
|
||||
var configuration = MissingDocsConfiguration()
|
||||
try? configuration.apply(configuration: ["warning": "open"])
|
||||
XCTAssertEqual(
|
||||
configuration.parameters,
|
||||
[RuleParameter<AccessControlLevel>(severity: .warning, value: .open)]
|
||||
#expect(
|
||||
configuration.parameters == [RuleParameter<AccessControlLevel>(severity: .warning, value: .open)]
|
||||
)
|
||||
}
|
||||
|
||||
func testParsingMultipleSeverities() {
|
||||
@Test
|
||||
func parsingMultipleSeverities() {
|
||||
var configuration = MissingDocsConfiguration()
|
||||
try? configuration.apply(configuration: ["warning": "public", "error": "open"])
|
||||
XCTAssertEqual(
|
||||
configuration.parameters.sorted { $0.value.rawValue > $1.value.rawValue },
|
||||
[
|
||||
#expect(
|
||||
configuration.parameters.sorted { $0.value.rawValue > $1.value.rawValue } == [
|
||||
RuleParameter<AccessControlLevel>(severity: .warning, value: .public),
|
||||
RuleParameter<AccessControlLevel>(severity: .error, value: .open),
|
||||
]
|
||||
)
|
||||
}
|
||||
|
||||
func testParsingMultipleAcls() {
|
||||
@Test
|
||||
func parsingMultipleAcls() {
|
||||
var configuration = MissingDocsConfiguration()
|
||||
try? configuration.apply(configuration: ["warning": ["public", "open"]])
|
||||
XCTAssertEqual(
|
||||
configuration.parameters.sorted { $0.value.rawValue > $1.value.rawValue },
|
||||
[
|
||||
#expect(
|
||||
configuration.parameters.sorted { $0.value.rawValue > $1.value.rawValue } == [
|
||||
RuleParameter<AccessControlLevel>(severity: .warning, value: .public),
|
||||
RuleParameter<AccessControlLevel>(severity: .warning, value: .open),
|
||||
]
|
||||
)
|
||||
XCTAssertTrue(configuration.excludesExtensions)
|
||||
XCTAssertTrue(configuration.excludesInheritedTypes)
|
||||
#expect(configuration.excludesExtensions)
|
||||
#expect(configuration.excludesInheritedTypes)
|
||||
}
|
||||
|
||||
func testInvalidServety() {
|
||||
@Test
|
||||
func invalidServety() {
|
||||
var configuration = MissingDocsConfiguration()
|
||||
XCTAssertThrowsError(try configuration.apply(configuration: ["warning": ["public", "closed"]]))
|
||||
#expect(throws: (any Error).self) {
|
||||
try configuration.apply(configuration: ["warning": ["public", "closed"]])
|
||||
}
|
||||
}
|
||||
|
||||
func testInvalidAcl() {
|
||||
@Test
|
||||
func invalidAcl() {
|
||||
var configuration = MissingDocsConfiguration()
|
||||
try? configuration.apply(configuration: ["debug": ["public", "open"]])
|
||||
XCTAssertTrue(configuration.excludesExtensions)
|
||||
XCTAssertTrue(configuration.excludesInheritedTypes)
|
||||
XCTAssertEqual(
|
||||
configuration.parameters.sorted { $0.value.rawValue > $1.value.rawValue },
|
||||
[
|
||||
#expect(configuration.excludesExtensions)
|
||||
#expect(configuration.excludesInheritedTypes)
|
||||
#expect(
|
||||
configuration.parameters.sorted { $0.value.rawValue > $1.value.rawValue } == [
|
||||
RuleParameter<AccessControlLevel>(severity: .warning, value: .public),
|
||||
RuleParameter<AccessControlLevel>(severity: .warning, value: .open),
|
||||
]
|
||||
)
|
||||
}
|
||||
|
||||
func testInvalidDuplicateAcl() {
|
||||
@Test
|
||||
func invalidDuplicateAcl() {
|
||||
var configuration = MissingDocsConfiguration()
|
||||
XCTAssertThrowsError(
|
||||
#expect(throws: (any Error).self) {
|
||||
try configuration.apply(configuration: ["warning": ["public", "open"] as Any, "error": "public"])
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
func testExcludesFalse() {
|
||||
@Test
|
||||
func excludesFalse() {
|
||||
var configuration = MissingDocsConfiguration()
|
||||
try? configuration.apply(configuration: ["excludes_extensions": false, "excludes_inherited_types": false])
|
||||
XCTAssertFalse(configuration.excludesExtensions)
|
||||
XCTAssertFalse(configuration.excludesInheritedTypes)
|
||||
XCTAssertEqual(
|
||||
configuration.parameters.sorted { $0.value.rawValue > $1.value.rawValue },
|
||||
[
|
||||
#expect(!configuration.excludesExtensions)
|
||||
#expect(!configuration.excludesInheritedTypes)
|
||||
#expect(
|
||||
configuration.parameters.sorted { $0.value.rawValue > $1.value.rawValue } == [
|
||||
RuleParameter<AccessControlLevel>(severity: .warning, value: .public),
|
||||
RuleParameter<AccessControlLevel>(severity: .warning, value: .open),
|
||||
]
|
||||
)
|
||||
}
|
||||
|
||||
func testExcludesExtensionsFalseExcludesInheritedTypesTrue() {
|
||||
@Test
|
||||
func excludesExtensionsFalseExcludesInheritedTypesTrue() {
|
||||
var configuration = MissingDocsConfiguration()
|
||||
try? configuration.apply(configuration: ["excludes_extensions": false, "excludes_inherited_types": true])
|
||||
XCTAssertFalse(configuration.excludesExtensions)
|
||||
XCTAssertTrue(configuration.excludesInheritedTypes)
|
||||
XCTAssertEqual(
|
||||
configuration.parameters.sorted { $0.value.rawValue > $1.value.rawValue },
|
||||
[
|
||||
#expect(!configuration.excludesExtensions)
|
||||
#expect(configuration.excludesInheritedTypes)
|
||||
#expect(
|
||||
configuration.parameters.sorted { $0.value.rawValue > $1.value.rawValue } == [
|
||||
RuleParameter<AccessControlLevel>(severity: .warning, value: .public),
|
||||
RuleParameter<AccessControlLevel>(severity: .warning, value: .open),
|
||||
]
|
||||
)
|
||||
}
|
||||
|
||||
func testExcludesExtensionsTrueExcludesInheritedTypesFalse() {
|
||||
@Test
|
||||
func excludesExtensionsTrueExcludesInheritedTypesFalse() {
|
||||
var configuration = MissingDocsConfiguration()
|
||||
try? configuration.apply(configuration: ["excludes_extensions": true, "excludes_inherited_types": false])
|
||||
XCTAssertTrue(configuration.excludesExtensions)
|
||||
XCTAssertFalse(configuration.excludesInheritedTypes)
|
||||
XCTAssertEqual(
|
||||
configuration.parameters.sorted { $0.value.rawValue > $1.value.rawValue },
|
||||
[
|
||||
#expect(configuration.excludesExtensions)
|
||||
#expect(!configuration.excludesInheritedTypes)
|
||||
#expect(
|
||||
configuration.parameters.sorted { $0.value.rawValue > $1.value.rawValue } == [
|
||||
RuleParameter<AccessControlLevel>(severity: .warning, value: .public),
|
||||
RuleParameter<AccessControlLevel>(severity: .warning, value: .open),
|
||||
]
|
||||
)
|
||||
}
|
||||
|
||||
func testExcludesExtensionsTrueExcludesInheritedTypesFalseWithParameters() {
|
||||
@Test
|
||||
func excludesExtensionsTrueExcludesInheritedTypesFalseWithParameters() {
|
||||
var configuration = MissingDocsConfiguration()
|
||||
try? configuration.apply(
|
||||
configuration: [
|
||||
@@ -211,11 +234,11 @@ final class MissingDocsRuleTests: SwiftLintTestCase {
|
||||
] as [String: any Sendable]
|
||||
)
|
||||
|
||||
XCTAssertTrue(configuration.excludesExtensions)
|
||||
XCTAssertFalse(configuration.excludesInheritedTypes)
|
||||
XCTAssertEqual(
|
||||
configuration.parameters.sorted { $0.value.rawValue > $1.value.rawValue },
|
||||
[RuleParameter<AccessControlLevel>(severity: .error, value: .public)]
|
||||
#expect(configuration.excludesExtensions)
|
||||
#expect(!configuration.excludesInheritedTypes)
|
||||
#expect(
|
||||
configuration.parameters.sorted { $0.value.rawValue > $1.value.rawValue }
|
||||
== [RuleParameter<AccessControlLevel>(severity: .error, value: .public)]
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
+26
-17
@@ -1,9 +1,14 @@
|
||||
@testable import SwiftLintBuiltInRules
|
||||
import TestHelpers
|
||||
import XCTest
|
||||
import Testing
|
||||
|
||||
final class ModifierOrderTests: SwiftLintTestCase {
|
||||
func testAttributeTypeMethod() {
|
||||
@testable import SwiftLintBuiltInRules
|
||||
|
||||
// swiftlint:disable file_length
|
||||
|
||||
@Suite(.rulesRegistered)
|
||||
struct ModifierOrderTests {
|
||||
@Test
|
||||
func attributeTypeMethod() {
|
||||
let descriptionOverride = ModifierOrderRule.description
|
||||
.with(nonTriggeringExamples: [
|
||||
Example("""
|
||||
@@ -35,7 +40,8 @@ final class ModifierOrderTests: SwiftLintTestCase {
|
||||
ruleConfiguration: ["preferred_modifier_order": ["typeMethods", "acl"]])
|
||||
}
|
||||
|
||||
func testRightOrderedModifierGroups() {
|
||||
@Test
|
||||
func rightOrderedModifierGroups() {
|
||||
let descriptionOverride = ModifierOrderRule.description
|
||||
.with(nonTriggeringExamples: [
|
||||
Example("public protocol Foo: class {}\n" +
|
||||
@@ -73,8 +79,8 @@ final class ModifierOrderTests: SwiftLintTestCase {
|
||||
)
|
||||
}
|
||||
|
||||
// swiftlint:disable:next function_body_length
|
||||
func testAtPrefixedGroup() {
|
||||
@Test
|
||||
func atPrefixedGroup() { // swiftlint:disable:this function_body_length
|
||||
let descriptionOverride = ModifierOrderRule.description
|
||||
.with(nonTriggeringExamples: [
|
||||
Example(#"""
|
||||
@@ -171,7 +177,8 @@ final class ModifierOrderTests: SwiftLintTestCase {
|
||||
ruleConfiguration: ["preferred_modifier_order": ["override", "acl", "owned", "final"]])
|
||||
}
|
||||
|
||||
func testNonSpecifiedModifiersDontInterfere() {
|
||||
@Test
|
||||
func nonSpecifiedModifiersDontInterfere() {
|
||||
let descriptionOverride = ModifierOrderRule.description
|
||||
.with(nonTriggeringExamples: [
|
||||
Example("""
|
||||
@@ -223,8 +230,8 @@ final class ModifierOrderTests: SwiftLintTestCase {
|
||||
ruleConfiguration: ["preferred_modifier_order": ["final", "override", "acl"]])
|
||||
}
|
||||
|
||||
// swiftlint:disable:next function_body_length
|
||||
func testCorrectionsAreAppliedCorrectly() {
|
||||
@Test
|
||||
func correctionsAreAppliedCorrectly() { // swiftlint:disable:this function_body_length
|
||||
let descriptionOverride = ModifierOrderRule.description
|
||||
.with(nonTriggeringExamples: [], triggeringExamples: [])
|
||||
.with(corrections: [
|
||||
@@ -290,8 +297,8 @@ final class ModifierOrderTests: SwiftLintTestCase {
|
||||
ruleConfiguration: ["preferred_modifier_order": ["final", "override", "acl", "typeMethods"]])
|
||||
}
|
||||
|
||||
// swiftlint:disable:next function_body_length
|
||||
func testCorrectionsAreNotAppliedToIrrelevantModifier() {
|
||||
@Test
|
||||
func correctionsAreNotAppliedToIrrelevantModifier() { // swiftlint:disable:this function_body_length
|
||||
let descriptionOverride = ModifierOrderRule.description
|
||||
.with(nonTriggeringExamples: [], triggeringExamples: [])
|
||||
.with(corrections: [
|
||||
@@ -361,7 +368,8 @@ final class ModifierOrderTests: SwiftLintTestCase {
|
||||
ruleConfiguration: ["preferred_modifier_order": ["final", "override", "acl", "typeMethods"]])
|
||||
}
|
||||
|
||||
func testTypeMethodClassCorrection() {
|
||||
@Test
|
||||
func typeMethodClassCorrection() {
|
||||
let descriptionOverride = ModifierOrderRule.description
|
||||
.with(nonTriggeringExamples: [], triggeringExamples: [])
|
||||
.with(corrections: [
|
||||
@@ -383,18 +391,19 @@ final class ModifierOrderTests: SwiftLintTestCase {
|
||||
ruleConfiguration: ["preferred_modifier_order": ["final", "typeMethods", "acl"]])
|
||||
}
|
||||
|
||||
func testViolationMessage() {
|
||||
@Test
|
||||
func violationMessage() {
|
||||
let ruleID = ModifierOrderRule.identifier
|
||||
guard let config = makeConfig(["preferred_modifier_order": ["acl", "final"]], ruleID) else {
|
||||
XCTFail("Failed to create configuration")
|
||||
Testing.Issue.record("Failed to create configuration")
|
||||
return
|
||||
}
|
||||
let allViolations = violations(Example("final public var foo: String"), config: config)
|
||||
let modifierOrderRuleViolation = allViolations.first { $0.ruleIdentifier == ruleID }
|
||||
if let violation = modifierOrderRuleViolation {
|
||||
XCTAssertEqual(violation.reason, "public modifier should come before final")
|
||||
#expect(violation.reason == "public modifier should come before final")
|
||||
} else {
|
||||
XCTFail("A modifier order violation should have been triggered!")
|
||||
Testing.Issue.record("A modifier order violation should have been triggered!")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,12 @@
|
||||
@testable import SwiftLintBuiltInRules
|
||||
import TestHelpers
|
||||
import Testing
|
||||
|
||||
final class MultilineArgumentsRuleTests: SwiftLintTestCase {
|
||||
func testMultilineArgumentsWithWithNextLine() {
|
||||
@testable import SwiftLintBuiltInRules
|
||||
|
||||
@Suite(.rulesRegistered)
|
||||
struct MultilineArgumentsRuleTests {
|
||||
@Test
|
||||
func multilineArgumentsWithWithNextLine() {
|
||||
let nonTriggeringExamples = [
|
||||
Example("foo()"),
|
||||
Example("foo(0)"),
|
||||
@@ -27,7 +31,8 @@ final class MultilineArgumentsRuleTests: SwiftLintTestCase {
|
||||
verifyRule(description, ruleConfiguration: ["first_argument_location": "next_line"])
|
||||
}
|
||||
|
||||
func testMultilineArgumentsWithWithSameLine() {
|
||||
@Test
|
||||
func multilineArgumentsWithWithSameLine() {
|
||||
let nonTriggeringExamples = [
|
||||
Example("foo()"),
|
||||
Example("foo(0)"),
|
||||
@@ -54,7 +59,8 @@ final class MultilineArgumentsRuleTests: SwiftLintTestCase {
|
||||
verifyRule(description, ruleConfiguration: ["first_argument_location": "same_line"])
|
||||
}
|
||||
|
||||
func testMultilineArgumentsWithOnlyEnforceAfterFirstClosureOnFirstLine() {
|
||||
@Test
|
||||
func multilineArgumentsWithOnlyEnforceAfterFirstClosureOnFirstLine() {
|
||||
let nonTriggeringExamples: [Example] = [
|
||||
Example("foo()"),
|
||||
Example("foo(0)"),
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
import TestHelpers
|
||||
import Testing
|
||||
|
||||
@testable import SwiftLintBuiltInRules
|
||||
@testable import SwiftLintCore
|
||||
import TestHelpers
|
||||
import XCTest
|
||||
|
||||
final class MultilineParametersConfigurationTests: SwiftLintTestCase {
|
||||
func testInvalidMaxNumberOfSingleLineParameters() async throws {
|
||||
@Suite(.rulesRegistered)
|
||||
struct MultilineParametersConfigurationTests {
|
||||
@Test
|
||||
func invalidMaxNumberOfSingleLineParameters() async throws {
|
||||
for maxNumberOfSingleLineParameters in [0, -1] {
|
||||
let console = try await Issue.captureConsole {
|
||||
var config = MultilineParametersConfiguration()
|
||||
@@ -12,29 +15,28 @@ final class MultilineParametersConfigurationTests: SwiftLintTestCase {
|
||||
configuration: ["max_number_of_single_line_parameters": maxNumberOfSingleLineParameters]
|
||||
)
|
||||
}
|
||||
XCTAssertEqual(
|
||||
console,
|
||||
"""
|
||||
warning: Inconsistent configuration for 'multiline_parameters' rule: Option \
|
||||
'max_number_of_single_line_parameters' should be >= 1.
|
||||
"""
|
||||
#expect(
|
||||
console == """
|
||||
warning: Inconsistent configuration for 'multiline_parameters' rule: Option \
|
||||
'max_number_of_single_line_parameters' should be >= 1.
|
||||
"""
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
func testInvalidMaxNumberOfSingleLineParametersWithSingleLineEnabled() async throws {
|
||||
@Test
|
||||
func invalidMaxNumberOfSingleLineParametersWithSingleLineEnabled() async throws {
|
||||
let console = try await Issue.captureConsole {
|
||||
var config = MultilineParametersConfiguration()
|
||||
try config.apply(
|
||||
configuration: ["max_number_of_single_line_parameters": 2, "allows_single_line": false]
|
||||
)
|
||||
}
|
||||
XCTAssertEqual(
|
||||
console,
|
||||
"""
|
||||
warning: Inconsistent configuration for 'multiline_parameters' rule: Option \
|
||||
'max_number_of_single_line_parameters' has no effect when 'allows_single_line' is false.
|
||||
"""
|
||||
#expect(
|
||||
console == """
|
||||
warning: Inconsistent configuration for 'multiline_parameters' rule: Option \
|
||||
'max_number_of_single_line_parameters' has no effect when 'allows_single_line' is false.
|
||||
"""
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
@testable import SwiftLintBuiltInRules
|
||||
import TestHelpers
|
||||
import XCTest
|
||||
import Testing
|
||||
|
||||
final class NameConfigurationTests: SwiftLintTestCase {
|
||||
@testable import SwiftLintBuiltInRules
|
||||
|
||||
@Suite(.rulesRegistered)
|
||||
struct NameConfigurationTests {
|
||||
typealias TesteeType = NameConfiguration<RuleMock>
|
||||
|
||||
func testNameConfigurationSetsCorrectly() {
|
||||
@Test
|
||||
func nameConfigurationSetsCorrectly() {
|
||||
let config: [String: any Sendable] = [
|
||||
"min_length": ["warning": 17, "error": 7],
|
||||
"max_length": ["warning": 170, "error": 700],
|
||||
@@ -26,66 +29,80 @@ final class NameConfigurationTests: SwiftLintTestCase {
|
||||
validatesStartWithLowercase: .warning)
|
||||
do {
|
||||
try nameConfig.apply(configuration: config)
|
||||
XCTAssertEqual(nameConfig, comp)
|
||||
#expect(nameConfig == comp)
|
||||
} catch {
|
||||
XCTFail("Did not configure correctly")
|
||||
Testing.Issue.record("Did not configure correctly")
|
||||
}
|
||||
}
|
||||
|
||||
func testCaseCheck() throws {
|
||||
var nameConfig = TesteeType(minLengthWarning: 0,
|
||||
minLengthError: 0,
|
||||
maxLengthWarning: 0,
|
||||
maxLengthError: 0)
|
||||
@Test
|
||||
func caseCheck() throws {
|
||||
var nameConfig = TesteeType(
|
||||
minLengthWarning: 0,
|
||||
minLengthError: 0,
|
||||
maxLengthWarning: 0,
|
||||
maxLengthError: 0
|
||||
)
|
||||
|
||||
XCTAssertEqual(nameConfig.validatesStartWithLowercase, .error)
|
||||
#expect(nameConfig.validatesStartWithLowercase == .error)
|
||||
|
||||
try nameConfig.apply(configuration: ["validates_start_with_lowercase": "off"])
|
||||
XCTAssertEqual(nameConfig.validatesStartWithLowercase, .off)
|
||||
#expect(nameConfig.validatesStartWithLowercase == .off)
|
||||
|
||||
try nameConfig.apply(configuration: ["validates_start_with_lowercase": "warning"])
|
||||
XCTAssertEqual(nameConfig.validatesStartWithLowercase, .warning)
|
||||
#expect(nameConfig.validatesStartWithLowercase == .warning)
|
||||
}
|
||||
|
||||
func testNameConfigurationThrowsOnBadConfig() {
|
||||
@Test
|
||||
func nameConfigurationThrowsOnBadConfig() {
|
||||
let config = 17
|
||||
var nameConfig = TesteeType(minLengthWarning: 0,
|
||||
minLengthError: 0,
|
||||
maxLengthWarning: 0,
|
||||
maxLengthError: 0)
|
||||
checkError(Issue.invalidConfiguration(ruleID: RuleMock.identifier)) {
|
||||
var nameConfig = TesteeType(
|
||||
minLengthWarning: 0,
|
||||
minLengthError: 0,
|
||||
maxLengthWarning: 0,
|
||||
maxLengthError: 0
|
||||
)
|
||||
#expect(throws: Issue.invalidConfiguration(ruleID: RuleMock.identifier)) {
|
||||
try nameConfig.apply(configuration: config)
|
||||
}
|
||||
}
|
||||
|
||||
func testNameConfigurationMinLengthThreshold() {
|
||||
let nameConfig = TesteeType(minLengthWarning: 7,
|
||||
minLengthError: 17,
|
||||
maxLengthWarning: 0,
|
||||
maxLengthError: 0,
|
||||
excluded: [])
|
||||
XCTAssertEqual(nameConfig.minLengthThreshold, 17)
|
||||
@Test
|
||||
func nameConfigurationMinLengthThreshold() {
|
||||
let nameConfig = TesteeType(
|
||||
minLengthWarning: 7,
|
||||
minLengthError: 17,
|
||||
maxLengthWarning: 0,
|
||||
maxLengthError: 0,
|
||||
excluded: []
|
||||
)
|
||||
#expect(nameConfig.minLengthThreshold == 17)
|
||||
}
|
||||
|
||||
func testNameConfigurationMaxLengthThreshold() {
|
||||
let nameConfig = TesteeType(minLengthWarning: 0,
|
||||
minLengthError: 0,
|
||||
maxLengthWarning: 17,
|
||||
maxLengthError: 7,
|
||||
excluded: [])
|
||||
XCTAssertEqual(nameConfig.maxLengthThreshold, 7)
|
||||
@Test
|
||||
func nameConfigurationMaxLengthThreshold() {
|
||||
let nameConfig = TesteeType(
|
||||
minLengthWarning: 0,
|
||||
minLengthError: 0,
|
||||
maxLengthWarning: 17,
|
||||
maxLengthError: 7,
|
||||
excluded: []
|
||||
)
|
||||
#expect(nameConfig.maxLengthThreshold == 7)
|
||||
}
|
||||
|
||||
func testUnallowedSymbolsSeverity() throws {
|
||||
var nameConfig = TesteeType(minLengthWarning: 3,
|
||||
minLengthError: 1,
|
||||
maxLengthWarning: 17,
|
||||
maxLengthError: 22,
|
||||
unallowedSymbolsSeverity: .warning)
|
||||
XCTAssertEqual(nameConfig.unallowedSymbolsSeverity, .warning)
|
||||
@Test
|
||||
func unallowedSymbolsSeverity() throws {
|
||||
var nameConfig = TesteeType(
|
||||
minLengthWarning: 3,
|
||||
minLengthError: 1,
|
||||
maxLengthWarning: 17,
|
||||
maxLengthError: 22,
|
||||
unallowedSymbolsSeverity: .warning
|
||||
)
|
||||
|
||||
#expect(nameConfig.unallowedSymbolsSeverity == .warning)
|
||||
try nameConfig.apply(configuration: ["unallowed_symbols_severity": "error"])
|
||||
|
||||
XCTAssertEqual(nameConfig.unallowedSymbolsSeverity, .error)
|
||||
#expect(nameConfig.unallowedSymbolsSeverity == .error)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +1,16 @@
|
||||
@testable import SwiftLintBuiltInRules
|
||||
import TestHelpers
|
||||
import Testing
|
||||
|
||||
@testable import SwiftLintBuiltInRules
|
||||
|
||||
// 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() {
|
||||
@Suite(.rulesRegistered)
|
||||
struct NestingRuleTests { // swiftlint:disable:this type_body_length
|
||||
@Test
|
||||
func nestingWithAlwaysAllowOneTypeInFunctions() { // swiftlint:disable:this function_body_length
|
||||
var nonTriggeringExamples = NestingRule.description.nonTriggeringExamples
|
||||
nonTriggeringExamples.append(contentsOf: detectingTypes.flatMap { type -> [Example] in
|
||||
[
|
||||
@@ -212,8 +214,8 @@ final class NestingRuleTests: SwiftLintTestCase {
|
||||
verifyRule(description, ruleConfiguration: ["always_allow_one_type_in_functions": true])
|
||||
}
|
||||
|
||||
// swiftlint:disable:next function_body_length
|
||||
func testNestingWithoutCheckNestingInClosuresAndStatements() {
|
||||
@Test
|
||||
func nestingWithoutCheckNestingInClosuresAndStatements() { // swiftlint:disable:this function_body_length
|
||||
var nonTriggeringExamples = NestingRule.description.nonTriggeringExamples
|
||||
// swiftlint:disable:next closure_body_length
|
||||
nonTriggeringExamples.append(contentsOf: detectingTypes.flatMap { type -> [Example] in
|
||||
@@ -511,7 +513,8 @@ final class NestingRuleTests: SwiftLintTestCase {
|
||||
verifyRule(description, ruleConfiguration: ["check_nesting_in_closures_and_statements": false])
|
||||
}
|
||||
|
||||
func testNestingWithoutTypealiasAndAssociatedtype() {
|
||||
@Test
|
||||
func nestingWithoutTypealiasAndAssociatedtype() {
|
||||
var nonTriggeringExamples = NestingRule.description.nonTriggeringExamples
|
||||
nonTriggeringExamples.append(contentsOf: detectingTypes.flatMap { type -> [Example] in
|
||||
[
|
||||
|
||||
@@ -1,16 +1,20 @@
|
||||
import TestHelpers
|
||||
import Testing
|
||||
|
||||
@testable import SwiftLintBuiltInRules
|
||||
@testable import SwiftLintCore
|
||||
import TestHelpers
|
||||
import XCTest
|
||||
|
||||
final class NoEmptyBlockConfigurationTests: SwiftLintTestCase {
|
||||
func testDefaultConfiguration() {
|
||||
@Suite(.rulesRegistered)
|
||||
struct NoEmptyBlockConfigurationTests {
|
||||
@Test
|
||||
func defaultConfiguration() {
|
||||
let config = NoEmptyBlockConfiguration()
|
||||
XCTAssertEqual(config.severityConfiguration.severity, .warning)
|
||||
XCTAssertEqual(config.enabledBlockTypes, NoEmptyBlockConfiguration.CodeBlockType.all)
|
||||
#expect(config.severityConfiguration.severity == .warning)
|
||||
#expect(config.enabledBlockTypes == NoEmptyBlockConfiguration.CodeBlockType.all)
|
||||
}
|
||||
|
||||
func testApplyingCustomConfiguration() throws {
|
||||
@Test
|
||||
func applyingCustomConfiguration() throws {
|
||||
var config = NoEmptyBlockConfiguration()
|
||||
try config.apply(
|
||||
configuration: [
|
||||
@@ -18,41 +22,44 @@ final class NoEmptyBlockConfigurationTests: SwiftLintTestCase {
|
||||
"disabled_block_types": ["function_bodies"],
|
||||
] as [String: any Sendable]
|
||||
)
|
||||
XCTAssertEqual(config.severityConfiguration.severity, .error)
|
||||
XCTAssertEqual(config.enabledBlockTypes, Set([.initializerBodies, .statementBlocks, .closureBlocks]))
|
||||
#expect(config.severityConfiguration.severity == .error)
|
||||
#expect(config.enabledBlockTypes == Set([.initializerBodies, .statementBlocks, .closureBlocks]))
|
||||
}
|
||||
|
||||
func testInvalidKeyInCustomConfiguration() async throws {
|
||||
@Test
|
||||
func invalidKeyInCustomConfiguration() async throws {
|
||||
let console = try await Issue.captureConsole {
|
||||
var config = NoEmptyBlockConfiguration()
|
||||
try config.apply(configuration: ["invalidKey": "error"])
|
||||
}
|
||||
XCTAssertEqual(
|
||||
console,
|
||||
"warning: Configuration for 'no_empty_block' rule contains the invalid key(s) 'invalidKey'."
|
||||
#expect(
|
||||
console == "warning: Configuration for 'no_empty_block' rule contains the invalid key(s) 'invalidKey'."
|
||||
)
|
||||
}
|
||||
|
||||
func testInvalidTypeOfCustomConfiguration() {
|
||||
@Test
|
||||
func invalidTypeOfCustomConfiguration() {
|
||||
var config = NoEmptyBlockConfiguration()
|
||||
checkError(Issue.invalidConfiguration(ruleID: NoEmptyBlockRule.identifier)) {
|
||||
#expect(throws: Issue.invalidConfiguration(ruleID: NoEmptyBlockRule.identifier)) {
|
||||
try config.apply(configuration: "invalidKey")
|
||||
}
|
||||
}
|
||||
|
||||
func testInvalidTypeOfValueInCustomConfiguration() {
|
||||
@Test
|
||||
func invalidTypeOfValueInCustomConfiguration() {
|
||||
var config = NoEmptyBlockConfiguration()
|
||||
checkError(Issue.invalidConfiguration(ruleID: NoEmptyBlockRule.identifier)) {
|
||||
#expect(throws: Issue.invalidConfiguration(ruleID: NoEmptyBlockRule.identifier)) {
|
||||
try config.apply(configuration: ["severity": "foo"])
|
||||
}
|
||||
}
|
||||
|
||||
func testConsoleDescription() throws {
|
||||
@Test
|
||||
func consoleDescription() throws {
|
||||
var config = NoEmptyBlockConfiguration()
|
||||
try config.apply(configuration: ["disabled_block_types": ["initializer_bodies", "statement_blocks"]])
|
||||
XCTAssertEqual(
|
||||
RuleConfigurationDescription.from(configuration: config).oneLiner(),
|
||||
"severity: warning; disabled_block_types: [initializer_bodies, statement_blocks]"
|
||||
#expect(
|
||||
RuleConfigurationDescription.from(configuration: config).oneLiner()
|
||||
== "severity: warning; disabled_block_types: [initializer_bodies, statement_blocks]"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
@testable import SwiftLintBuiltInRules
|
||||
import SwiftParser
|
||||
import TestHelpers
|
||||
import XCTest
|
||||
import Testing
|
||||
|
||||
final class NumberSeparatorRuleTests: SwiftLintTestCase {
|
||||
func testNumberSeparatorWithMinimumLength() {
|
||||
@testable import SwiftLintBuiltInRules
|
||||
|
||||
@Suite(.rulesRegistered)
|
||||
struct NumberSeparatorRuleTests {
|
||||
@Test
|
||||
func numberSeparatorWithMinimumLength() {
|
||||
let nonTriggeringExamples = [
|
||||
Example("let foo = 10_000"),
|
||||
Example("let foo = 1000"),
|
||||
@@ -31,7 +34,8 @@ final class NumberSeparatorRuleTests: SwiftLintTestCase {
|
||||
verifyRule(description, ruleConfiguration: ["minimum_length": 5])
|
||||
}
|
||||
|
||||
func testNumberSeparatorWithMinimumFractionLength() {
|
||||
@Test
|
||||
func numberSeparatorWithMinimumFractionLength() {
|
||||
let nonTriggeringExamples = [
|
||||
Example("let foo = 1_000.000_000_1"),
|
||||
Example("let foo = 1.000_001"),
|
||||
@@ -57,7 +61,8 @@ final class NumberSeparatorRuleTests: SwiftLintTestCase {
|
||||
verifyRule(description, ruleConfiguration: ["minimum_fraction_length": 5])
|
||||
}
|
||||
|
||||
func testNumberSeparatorWithExcludeRanges() {
|
||||
@Test
|
||||
func numberSeparatorWithExcludeRanges() {
|
||||
let nonTriggeringExamples = [
|
||||
Example("let foo = 1950"),
|
||||
Example("let foo = 1_950"),
|
||||
@@ -100,38 +105,24 @@ final class NumberSeparatorRuleTests: SwiftLintTestCase {
|
||||
)
|
||||
}
|
||||
|
||||
func testSpecificViolationReasons() {
|
||||
XCTAssertEqual(
|
||||
violations(in: "1_000"),
|
||||
[]
|
||||
@Test
|
||||
func specificViolationReasons() {
|
||||
#expect(violations(in: "1_000").isEmpty)
|
||||
#expect(violations(in: "1000") == [NumberSeparatorRule.missingSeparatorsReason])
|
||||
#expect(
|
||||
violations(in: "1.000000", config: ["minimum_fraction_length": 5])
|
||||
== [NumberSeparatorRule.missingSeparatorsReason]
|
||||
)
|
||||
XCTAssertEqual(
|
||||
violations(in: "1000"),
|
||||
[NumberSeparatorRule.missingSeparatorsReason]
|
||||
#expect(violations(in: "10_00") == [NumberSeparatorRule.misplacedSeparatorsReason])
|
||||
#expect(violations(in: "1_000_0") == [NumberSeparatorRule.misplacedSeparatorsReason])
|
||||
#expect(violations(in: "1000.0_00") == [NumberSeparatorRule.misplacedSeparatorsReason])
|
||||
#expect(
|
||||
violations(in: "10_00", config: ["minimum_length": 5])
|
||||
== [NumberSeparatorRule.misplacedSeparatorsReason]
|
||||
)
|
||||
XCTAssertEqual(
|
||||
violations(in: "1.000000", config: ["minimum_fraction_length": 5]),
|
||||
[NumberSeparatorRule.missingSeparatorsReason]
|
||||
)
|
||||
XCTAssertEqual(
|
||||
violations(in: "10_00"),
|
||||
[NumberSeparatorRule.misplacedSeparatorsReason]
|
||||
)
|
||||
XCTAssertEqual(
|
||||
violations(in: "1_000_0"),
|
||||
[NumberSeparatorRule.misplacedSeparatorsReason]
|
||||
)
|
||||
XCTAssertEqual(
|
||||
violations(in: "1000.0_00"),
|
||||
[NumberSeparatorRule.misplacedSeparatorsReason]
|
||||
)
|
||||
XCTAssertEqual(
|
||||
violations(in: "10_00", config: ["minimum_length": 5]),
|
||||
[NumberSeparatorRule.misplacedSeparatorsReason]
|
||||
)
|
||||
XCTAssertEqual(
|
||||
violations(in: "1000.0_00", config: ["minimum_fraction_length": 5]),
|
||||
[NumberSeparatorRule.misplacedSeparatorsReason]
|
||||
#expect(
|
||||
violations(in: "1000.0_00", config: ["minimum_fraction_length": 5])
|
||||
== [NumberSeparatorRule.misplacedSeparatorsReason]
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
@testable import SwiftLintBuiltInRules
|
||||
import TestHelpers
|
||||
import Testing
|
||||
|
||||
final class ObjectLiteralRuleTests: SwiftLintTestCase {
|
||||
@testable import SwiftLintBuiltInRules
|
||||
|
||||
@Suite(.rulesRegistered)
|
||||
struct ObjectLiteralRuleTests {
|
||||
// MARK: - Instance Properties
|
||||
private let imageLiteralTriggeringExamples = ["", ".init"].flatMap { (method: String) -> [Example] in
|
||||
["UI", "NS"].flatMap { (prefix: String) -> [Example] in
|
||||
@@ -26,7 +29,8 @@ final class ObjectLiteralRuleTests: SwiftLintTestCase {
|
||||
}
|
||||
|
||||
// MARK: - Test Methods
|
||||
func testObjectLiteralWithImageLiteral() {
|
||||
@Test
|
||||
func objectLiteralWithImageLiteral() {
|
||||
// Verify ObjectLiteral rule for when image_literal is true.
|
||||
let baseDescription = ObjectLiteralRule.description
|
||||
let nonTriggeringColorLiteralExamples = colorLiteralTriggeringExamples.removingViolationMarkers()
|
||||
@@ -38,7 +42,8 @@ final class ObjectLiteralRuleTests: SwiftLintTestCase {
|
||||
verifyRule(description, ruleConfiguration: ["image_literal": true, "color_literal": false])
|
||||
}
|
||||
|
||||
func testObjectLiteralWithColorLiteral() {
|
||||
@Test
|
||||
func objectLiteralWithColorLiteral() {
|
||||
// Verify ObjectLiteral rule for when color_literal is true.
|
||||
let baseDescription = ObjectLiteralRule.description
|
||||
let nonTriggeringImageLiteralExamples = imageLiteralTriggeringExamples.removingViolationMarkers()
|
||||
@@ -50,7 +55,8 @@ final class ObjectLiteralRuleTests: SwiftLintTestCase {
|
||||
verifyRule(description, ruleConfiguration: ["image_literal": false, "color_literal": true])
|
||||
}
|
||||
|
||||
func testObjectLiteralWithImageAndColorLiteral() {
|
||||
@Test
|
||||
func objectLiteralWithImageAndColorLiteral() {
|
||||
// Verify ObjectLiteral rule for when image_literal & color_literal are true.
|
||||
let description = ObjectLiteralRule.description.with(triggeringExamples: allTriggeringExamples)
|
||||
verifyRule(description, ruleConfiguration: ["image_literal": true, "color_literal": true])
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
@testable import SwiftLintBuiltInRules
|
||||
import TestHelpers
|
||||
import Testing
|
||||
|
||||
final class OpeningBraceRuleTests: SwiftLintTestCase {
|
||||
func testDefaultNonTriggeringExamplesWithMultilineOptionsTrue() {
|
||||
@testable import SwiftLintBuiltInRules
|
||||
|
||||
@Suite(.rulesRegistered)
|
||||
struct OpeningBraceRuleTests {
|
||||
@Test
|
||||
func defaultNonTriggeringExamplesWithMultilineOptionsTrue() {
|
||||
let description = OpeningBraceRule.description
|
||||
.with(triggeringExamples: [])
|
||||
.with(corrections: [:])
|
||||
@@ -14,7 +18,8 @@ final class OpeningBraceRuleTests: SwiftLintTestCase {
|
||||
])
|
||||
}
|
||||
|
||||
func testWithIgnoreMultilineTypeHeadersTrue() {
|
||||
@Test
|
||||
func withIgnoreMultilineTypeHeadersTrue() {
|
||||
let nonTriggeringExamples = [
|
||||
Example("""
|
||||
extension A
|
||||
@@ -56,7 +61,8 @@ final class OpeningBraceRuleTests: SwiftLintTestCase {
|
||||
verifyRule(description, ruleConfiguration: ["ignore_multiline_type_headers": true])
|
||||
}
|
||||
|
||||
func testWithIgnoreMultilineStatementConditionsTrue() {
|
||||
@Test
|
||||
func withIgnoreMultilineStatementConditionsTrue() {
|
||||
let nonTriggeringExamples = [
|
||||
Example("""
|
||||
while
|
||||
@@ -114,8 +120,8 @@ final class OpeningBraceRuleTests: SwiftLintTestCase {
|
||||
verifyRule(description, ruleConfiguration: ["ignore_multiline_statement_conditions": true])
|
||||
}
|
||||
|
||||
// swiftlint:disable:next function_body_length
|
||||
func testWithIgnoreMultilineFunctionSignaturesTrue() {
|
||||
@Test
|
||||
func withIgnoreMultilineFunctionSignaturesTrue() { // swiftlint:disable:this function_body_length
|
||||
let nonTriggeringExamples = [
|
||||
Example("""
|
||||
func abc(
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
@testable import SwiftLintBuiltInRules
|
||||
import TestHelpers
|
||||
import XCTest
|
||||
import Testing
|
||||
|
||||
final class PreferKeyPathRuleTests: SwiftLintTestCase {
|
||||
@testable import SwiftLintBuiltInRules
|
||||
|
||||
@Suite(.rulesRegistered)
|
||||
struct PreferKeyPathRuleTests {
|
||||
private static let extendedMode = ["restrict_to_standard_functions": false]
|
||||
private static let ignoreIdentity = ["ignore_identity_closures": true]
|
||||
private static let extendedModeAndIgnoreIdentity = [
|
||||
@@ -10,9 +12,8 @@ final class PreferKeyPathRuleTests: SwiftLintTestCase {
|
||||
"ignore_identity_closures": true,
|
||||
]
|
||||
|
||||
func testIdentityExpressionInSwift6() throws {
|
||||
try XCTSkipIf(SwiftVersion.current < .six)
|
||||
|
||||
@Test(.disabled(if: SwiftVersion.current < .six))
|
||||
func identityExpressionInSwift6() throws {
|
||||
let description = PreferKeyPathRule.description
|
||||
.with(nonTriggeringExamples: [
|
||||
Example("f.filter { a in b }"),
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
@testable import SwiftLintBuiltInRules
|
||||
import TestHelpers
|
||||
import Testing
|
||||
|
||||
final class PrefixedTopLevelConstantRuleTests: SwiftLintTestCase {
|
||||
func testPrivateOnly() {
|
||||
@testable import SwiftLintBuiltInRules
|
||||
|
||||
@Suite(.rulesRegistered)
|
||||
struct PrefixedTopLevelConstantRuleTests {
|
||||
@Test
|
||||
func privateOnly() {
|
||||
let triggeringExamples = [
|
||||
Example("private let ↓Foo = 20.0"),
|
||||
Example("fileprivate let ↓foo = 20.0"),
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
@testable import SwiftLintBuiltInRules
|
||||
import TestHelpers
|
||||
import Testing
|
||||
|
||||
final class PrivateOverFilePrivateRuleTests: SwiftLintTestCase {
|
||||
func testPrivateOverFilePrivateValidatingExtensions() {
|
||||
@testable import SwiftLintBuiltInRules
|
||||
|
||||
@Suite(.rulesRegistered)
|
||||
struct PrivateOverFilePrivateRuleTests {
|
||||
@Test
|
||||
func privateOverFilePrivateValidatingExtensions() {
|
||||
let baseDescription = PrivateOverFilePrivateRule.description
|
||||
let triggeringExamples = baseDescription.triggeringExamples + [
|
||||
Example("↓fileprivate extension String {}"),
|
||||
@@ -20,7 +24,8 @@ final class PrivateOverFilePrivateRuleTests: SwiftLintTestCase {
|
||||
verifyRule(description, ruleConfiguration: ["validate_extensions": true])
|
||||
}
|
||||
|
||||
func testPrivateOverFilePrivateNotValidatingExtensions() {
|
||||
@Test
|
||||
func privateOverFilePrivateNotValidatingExtensions() {
|
||||
let baseDescription = PrivateOverFilePrivateRule.description
|
||||
let nonTriggeringExamples = baseDescription.nonTriggeringExamples + [
|
||||
Example("fileprivate extension String {}")
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
@testable import SwiftLintBuiltInRules
|
||||
import TestHelpers
|
||||
import XCTest
|
||||
import Testing
|
||||
|
||||
final class RequiredEnumCaseConfigurationTests: SwiftLintTestCase {
|
||||
@testable import SwiftLintBuiltInRules
|
||||
|
||||
@Suite(.rulesRegistered)
|
||||
final class RequiredEnumCaseConfigurationTests {
|
||||
private typealias RuleConfiguration = RequiredEnumCaseConfiguration
|
||||
private typealias RequiredCase = RuleConfiguration.RequiredCase
|
||||
|
||||
@@ -20,56 +22,64 @@ final class RequiredEnumCaseConfigurationTests: SwiftLintTestCase {
|
||||
return config
|
||||
}()
|
||||
|
||||
func testRequiredCaseHashValue() {
|
||||
@Test
|
||||
func requiredCaseHashValue() {
|
||||
let requiredCase = RequiredCase(name: "success")
|
||||
XCTAssertEqual(requiredCase.hashValue, RequiredCase(name: "success").hashValue)
|
||||
#expect(requiredCase.hashValue == RequiredCase(name: "success").hashValue)
|
||||
}
|
||||
|
||||
func testRequiredCaseEquatableReturnsTrue() {
|
||||
@Test
|
||||
func requiredCaseEquatableReturnsTrue() {
|
||||
let lhs = RequiredCase(name: "success")
|
||||
let rhs = RequiredCase(name: "success")
|
||||
XCTAssertEqual(lhs, rhs)
|
||||
#expect(lhs == rhs)
|
||||
}
|
||||
|
||||
func testRequiredCaseEquatableReturnsFalseBecauseOfDifferentName() {
|
||||
@Test
|
||||
func requiredCaseEquatableReturnsFalseBecauseOfDifferentName() {
|
||||
let lhs = RequiredCase(name: "success")
|
||||
let rhs = RequiredCase(name: "error")
|
||||
XCTAssertNotEqual(lhs, rhs)
|
||||
#expect(lhs != rhs)
|
||||
}
|
||||
|
||||
func testConsoleDescriptionReturnsAllConfiguredProtocols() {
|
||||
@Test
|
||||
func consoleDescriptionReturnsAllConfiguredProtocols() {
|
||||
let expected = "NetworkResults: error: warning; RequiredProtocol: error: warning, success: warning"
|
||||
XCTAssertEqual(config.parameterDescription?.oneLiner(), expected)
|
||||
#expect(config.parameterDescription?.oneLiner() == expected)
|
||||
}
|
||||
|
||||
func testConsoleDescriptionReturnsNoConfiguredProtocols() {
|
||||
@Test
|
||||
func consoleDescriptionReturnsNoConfiguredProtocols() {
|
||||
let expected = "{Protocol Name}: {Case Name 1}: {warning|error}, {Case Name 2}: {warning|error}"
|
||||
|
||||
config.protocols.removeAll()
|
||||
XCTAssertEqual(config.parameterDescription?.oneLiner(), expected)
|
||||
#expect(config.parameterDescription?.oneLiner() == expected)
|
||||
}
|
||||
|
||||
private func validateRulesExistForProtocol1() {
|
||||
XCTAssertTrue(self.config.protocols[Self.protocol1]?.contains(Self.rule1) ?? false)
|
||||
XCTAssertTrue(self.config.protocols[Self.protocol1]?.contains(Self.rule2) ?? false)
|
||||
#expect(self.config.protocols[Self.protocol1]?.contains(Self.rule1) ?? false)
|
||||
#expect(self.config.protocols[Self.protocol1]?.contains(Self.rule2) ?? false)
|
||||
}
|
||||
|
||||
func testRegisterProtocolCasesRegistersCasesWithSpecifiedSeverity() {
|
||||
@Test
|
||||
func registerProtocolCasesRegistersCasesWithSpecifiedSeverity() {
|
||||
config.register(protocol: Self.protocol3, cases: ["success": "error", "error": "warning"])
|
||||
validateRulesExistForProtocol3()
|
||||
}
|
||||
|
||||
private func validateRulesExistForProtocol3() {
|
||||
XCTAssertTrue(self.config.protocols[Self.protocol3]?.contains(Self.rule3) ?? false)
|
||||
XCTAssertTrue(self.config.protocols[Self.protocol3]?.contains(Self.rule2) ?? false)
|
||||
#expect(self.config.protocols[Self.protocol3]?.contains(Self.rule3) ?? false)
|
||||
#expect(self.config.protocols[Self.protocol3]?.contains(Self.rule2) ?? false)
|
||||
}
|
||||
|
||||
func testRegisterProtocols() {
|
||||
@Test
|
||||
func registerProtocols() {
|
||||
config.register(protocols: [Self.protocol1: ["success": "warning", "error": "warning"]])
|
||||
validateRulesExistForProtocol1()
|
||||
}
|
||||
|
||||
func testApplyThrowsErrorBecausePassedConfigurationCantBeCast() {
|
||||
@Test
|
||||
func applyThrowsErrorBecausePassedConfigurationCantBeCast() {
|
||||
var errorThrown = false
|
||||
|
||||
do {
|
||||
@@ -78,41 +88,45 @@ final class RequiredEnumCaseConfigurationTests: SwiftLintTestCase {
|
||||
errorThrown = true
|
||||
}
|
||||
|
||||
XCTAssertTrue(errorThrown)
|
||||
#expect(errorThrown)
|
||||
}
|
||||
|
||||
func testApplyRegistersProtocols() {
|
||||
@Test
|
||||
func applyRegistersProtocols() {
|
||||
try? config.apply(configuration: [Self.protocol1: ["success": "warning", "error": "warning"]])
|
||||
validateRulesExistForProtocol1()
|
||||
}
|
||||
|
||||
func testEqualsReturnsTrue() {
|
||||
@Test
|
||||
func equalsReturnsTrue() {
|
||||
var lhs = RuleConfiguration()
|
||||
try? lhs.apply(configuration: [Self.protocol1: ["success", "error"]])
|
||||
|
||||
var rhs = RuleConfiguration()
|
||||
try? rhs.apply(configuration: [Self.protocol1: ["success", "error"]])
|
||||
|
||||
XCTAssertEqual(lhs, rhs)
|
||||
#expect(lhs == rhs)
|
||||
}
|
||||
|
||||
func testEqualsReturnsFalseBecauseProtocolsArentEqual() {
|
||||
@Test
|
||||
func equalsReturnsFalseBecauseProtocolsArentEqual() {
|
||||
var lhs = RuleConfiguration()
|
||||
try? lhs.apply(configuration: [Self.protocol1: ["success": "error"]])
|
||||
|
||||
var rhs = RuleConfiguration()
|
||||
try? rhs.apply(configuration: [Self.protocol2: ["success": "error", "error": "warning"]])
|
||||
|
||||
XCTAssertNotEqual(lhs, rhs)
|
||||
#expect(lhs != rhs)
|
||||
}
|
||||
|
||||
func testEqualsReturnsFalseBecauseSeverityIsntEqual() {
|
||||
@Test
|
||||
func equalsReturnsFalseBecauseSeverityIsntEqual() {
|
||||
var lhs = RuleConfiguration()
|
||||
try? lhs.apply(configuration: [Self.protocol1: ["success": "error", "error": "error"]])
|
||||
|
||||
var rhs = RuleConfiguration()
|
||||
try? rhs.apply(configuration: [Self.protocol1: ["success": "warning", "error": "error"]])
|
||||
|
||||
XCTAssertNotEqual(lhs, rhs)
|
||||
#expect(lhs != rhs)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
@testable import SwiftLintBuiltInRules
|
||||
import TestHelpers
|
||||
import Testing
|
||||
|
||||
final class StatementPositionRuleTests: SwiftLintTestCase {
|
||||
func testStatementPositionUncuddled() {
|
||||
@testable import SwiftLintBuiltInRules
|
||||
|
||||
@Suite(.rulesRegistered)
|
||||
struct StatementPositionRuleTests {
|
||||
@Test
|
||||
func statementPositionUncuddled() {
|
||||
let configuration = ["statement_mode": "uncuddled_else"]
|
||||
verifyRule(StatementPositionRule.uncuddledDescription, ruleConfiguration: configuration)
|
||||
}
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
@testable import SwiftLintBuiltInRules
|
||||
import TestHelpers
|
||||
import Testing
|
||||
|
||||
final class SwitchCaseAlignmentRuleTests: SwiftLintTestCase {
|
||||
func testSwitchCaseAlignmentWithoutIndentedCases() {
|
||||
@testable import SwiftLintBuiltInRules
|
||||
|
||||
@Suite(.rulesRegistered)
|
||||
struct SwitchCaseAlignmentRuleTests {
|
||||
@Test
|
||||
func switchCaseAlignmentWithoutIndentedCases() {
|
||||
let baseDescription = SwitchCaseAlignmentRule.description
|
||||
let examples = SwitchCaseAlignmentRule.Examples(indentedCases: false)
|
||||
|
||||
@@ -12,7 +16,8 @@ final class SwitchCaseAlignmentRuleTests: SwiftLintTestCase {
|
||||
verifyRule(description)
|
||||
}
|
||||
|
||||
func testSwitchCaseAlignmentWithIndentedCases() {
|
||||
@Test
|
||||
func switchCaseAlignmentWithIndentedCases() {
|
||||
let baseDescription = SwitchCaseAlignmentRule.description
|
||||
let examples = SwitchCaseAlignmentRule.Examples(indentedCases: true)
|
||||
|
||||
|
||||
@@ -1,44 +1,51 @@
|
||||
@testable import SwiftLintBuiltInRules
|
||||
import TestHelpers
|
||||
import XCTest
|
||||
import Testing
|
||||
|
||||
final class TodoRuleTests: SwiftLintTestCase {
|
||||
func testTodo() {
|
||||
@testable import SwiftLintBuiltInRules
|
||||
|
||||
@Suite(.rulesRegistered)
|
||||
struct TodoRuleTests {
|
||||
@Test
|
||||
func todo() {
|
||||
verifyRule(TodoRule.description, commentDoesntViolate: false)
|
||||
}
|
||||
|
||||
func testTodoMessage() {
|
||||
@Test
|
||||
func todoMessage() {
|
||||
let example = Example("fatalError() // TODO: Implement")
|
||||
let violations = self.violations(example)
|
||||
XCTAssertEqual(violations.count, 1)
|
||||
XCTAssertEqual(violations.first!.reason, "TODOs should be resolved (Implement)")
|
||||
#expect(violations.count == 1)
|
||||
#expect(violations.first?.reason == "TODOs should be resolved (Implement)")
|
||||
}
|
||||
|
||||
func testFixMeMessage() {
|
||||
@Test
|
||||
func fixMeMessage() {
|
||||
let example = Example("fatalError() // FIXME: Implement")
|
||||
let violations = self.violations(example)
|
||||
XCTAssertEqual(violations.count, 1)
|
||||
XCTAssertEqual(violations.first!.reason, "FIXMEs should be resolved (Implement)")
|
||||
#expect(violations.count == 1)
|
||||
#expect(violations.first?.reason == "FIXMEs should be resolved (Implement)")
|
||||
}
|
||||
|
||||
func testOnlyFixMe() {
|
||||
@Test
|
||||
func onlyFixMe() {
|
||||
let example = Example("""
|
||||
fatalError() // TODO: Implement todo
|
||||
fatalError() // FIXME: Implement fixme
|
||||
""")
|
||||
""")
|
||||
let violations = self.violations(example, config: ["only": ["FIXME"]])
|
||||
XCTAssertEqual(violations.count, 1)
|
||||
XCTAssertEqual(violations.first!.reason, "FIXMEs should be resolved (Implement fixme)")
|
||||
#expect(violations.count == 1)
|
||||
#expect(violations.first?.reason == "FIXMEs should be resolved (Implement fixme)")
|
||||
}
|
||||
|
||||
func testOnlyTodo() {
|
||||
@Test
|
||||
func onlyTodo() {
|
||||
let example = Example("""
|
||||
fatalError() // TODO: Implement todo
|
||||
fatalError() // FIXME: Implement fixme
|
||||
""")
|
||||
""")
|
||||
let violations = self.violations(example, config: ["only": ["TODO"]])
|
||||
XCTAssertEqual(violations.count, 1)
|
||||
XCTAssertEqual(violations.first!.reason, "TODOs should be resolved (Implement todo)")
|
||||
#expect(violations.count == 1)
|
||||
#expect(violations.first?.reason == "TODOs should be resolved (Implement todo)")
|
||||
}
|
||||
|
||||
private func violations(_ example: Example, config: Any? = nil) -> [StyleViolation] {
|
||||
|
||||
@@ -1,15 +1,19 @@
|
||||
@testable import SwiftLintBuiltInRules
|
||||
import TestHelpers
|
||||
import XCTest
|
||||
import Testing
|
||||
|
||||
final class TrailingClosureConfigurationTests: SwiftLintTestCase {
|
||||
func testDefaultConfiguration() {
|
||||
@testable import SwiftLintBuiltInRules
|
||||
|
||||
@Suite(.rulesRegistered)
|
||||
struct TrailingClosureConfigurationTests {
|
||||
@Test
|
||||
func defaultConfiguration() {
|
||||
let config = TrailingClosureConfiguration()
|
||||
XCTAssertEqual(config.severityConfiguration.severity, .warning)
|
||||
XCTAssertFalse(config.onlySingleMutedParameter)
|
||||
#expect(config.severityConfiguration.severity == .warning)
|
||||
#expect(!config.onlySingleMutedParameter)
|
||||
}
|
||||
|
||||
func testApplyingCustomConfiguration() throws {
|
||||
@Test
|
||||
func applyingCustomConfiguration() throws {
|
||||
var config = TrailingClosureConfiguration()
|
||||
try config.apply(
|
||||
configuration: [
|
||||
@@ -17,7 +21,7 @@ final class TrailingClosureConfigurationTests: SwiftLintTestCase {
|
||||
"only_single_muted_parameter": true,
|
||||
] as [String: any Sendable]
|
||||
)
|
||||
XCTAssertEqual(config.severityConfiguration.severity, .error)
|
||||
XCTAssertTrue(config.onlySingleMutedParameter)
|
||||
#expect(config.severityConfiguration.severity == .error)
|
||||
#expect(config.onlySingleMutedParameter)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
@testable import SwiftLintBuiltInRules
|
||||
import TestHelpers
|
||||
import Testing
|
||||
|
||||
final class TrailingClosureRuleTests: SwiftLintTestCase {
|
||||
func testWithOnlySingleMutedParameterEnabled() {
|
||||
@testable import SwiftLintBuiltInRules
|
||||
|
||||
@Suite(.rulesRegistered)
|
||||
struct TrailingClosureRuleTests {
|
||||
@Test
|
||||
func withOnlySingleMutedParameterEnabled() {
|
||||
let originalDescription = TrailingClosureRule.description
|
||||
let description = originalDescription
|
||||
.with(nonTriggeringExamples: originalDescription.nonTriggeringExamples + [
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
@testable import SwiftLintBuiltInRules
|
||||
import TestHelpers
|
||||
import XCTest
|
||||
import Testing
|
||||
|
||||
final class TrailingCommaRuleTests: SwiftLintTestCase {
|
||||
func testTrailingCommaRuleWithDefaultConfiguration() {
|
||||
@testable import SwiftLintBuiltInRules
|
||||
|
||||
@Suite(.rulesRegistered)
|
||||
struct TrailingCommaRuleTests {
|
||||
@Test
|
||||
func trailingCommaRuleWithDefaultConfiguration() {
|
||||
// Verify TrailingCommaRule with test values for when mandatory_comma is false (default).
|
||||
let triggeringExamples = TrailingCommaRule.description.triggeringExamples +
|
||||
[Example("class C {\n #if true\n func f() {\n let foo = [1, 2, 3↓,]\n }\n #endif\n}")]
|
||||
@@ -11,8 +14,8 @@ final class TrailingCommaRuleTests: SwiftLintTestCase {
|
||||
|
||||
// Ensure the rule produces the correct reason string.
|
||||
let failingCase = Example("let array = [\n\t1,\n\t2,\n]\n")
|
||||
XCTAssertEqual(trailingCommaViolations(failingCase).first?.reason,
|
||||
"Collection literals should not have trailing commas")
|
||||
#expect(
|
||||
trailingCommaViolations(failingCase).first?.reason == "Collection literals should not have trailing commas")
|
||||
}
|
||||
|
||||
private static let triggeringExamples = [
|
||||
@@ -52,11 +55,12 @@ final class TrailingCommaRuleTests: SwiftLintTestCase {
|
||||
}()
|
||||
|
||||
private let mandatoryCommaRuleDescription = TrailingCommaRule.description
|
||||
.with(nonTriggeringExamples: TrailingCommaRuleTests.nonTriggeringExamples)
|
||||
.with(triggeringExamples: TrailingCommaRuleTests.triggeringExamples)
|
||||
.with(corrections: TrailingCommaRuleTests.corrections)
|
||||
.with(nonTriggeringExamples: Self.nonTriggeringExamples)
|
||||
.with(triggeringExamples: Self.triggeringExamples)
|
||||
.with(corrections: Self.corrections)
|
||||
|
||||
func testTrailingCommaRuleWithMandatoryComma() {
|
||||
@Test
|
||||
func trailingCommaRuleWithMandatoryComma() {
|
||||
// Verify TrailingCommaRule with test values for when mandatory_comma is true.
|
||||
let ruleDescription = mandatoryCommaRuleDescription
|
||||
let ruleConfiguration = ["mandatory_comma": true]
|
||||
@@ -65,8 +69,9 @@ final class TrailingCommaRuleTests: SwiftLintTestCase {
|
||||
|
||||
// Ensure the rule produces the correct reason string.
|
||||
let failingCase = Example("let array = [\n\t1,\n\t2\n]\n")
|
||||
XCTAssertEqual(trailingCommaViolations(failingCase, ruleConfiguration: ruleConfiguration).first?.reason,
|
||||
"Multi-line collection literals should have trailing commas")
|
||||
#expect(
|
||||
trailingCommaViolations(failingCase, ruleConfiguration: ruleConfiguration).first?.reason
|
||||
== "Multi-line collection literals should have trailing commas")
|
||||
}
|
||||
|
||||
private func trailingCommaViolations(_ example: Example, ruleConfiguration: Any? = nil) -> [StyleViolation] {
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
@testable import SwiftLintBuiltInRules
|
||||
import TestHelpers
|
||||
import Testing
|
||||
|
||||
final class TrailingWhitespaceRuleTests: SwiftLintTestCase {
|
||||
func testWithIgnoresEmptyLinesEnabled() {
|
||||
@testable import SwiftLintBuiltInRules
|
||||
|
||||
@Suite(.rulesRegistered)
|
||||
struct TrailingWhitespaceRuleTests {
|
||||
@Test
|
||||
func withIgnoresEmptyLinesEnabled() {
|
||||
// Perform additional tests with the ignores_empty_lines setting enabled.
|
||||
// The set of non-triggering examples is extended by a whitespace-indented empty line
|
||||
let baseDescription = TrailingWhitespaceRule.description
|
||||
@@ -13,7 +17,8 @@ final class TrailingWhitespaceRuleTests: SwiftLintTestCase {
|
||||
ruleConfiguration: ["ignores_empty_lines": true, "ignores_comments": true])
|
||||
}
|
||||
|
||||
func testWithIgnoresCommentsDisabled() {
|
||||
@Test
|
||||
func withIgnoresCommentsDisabled() {
|
||||
// Perform additional tests with the ignores_comments settings disabled.
|
||||
let baseDescription = TrailingWhitespaceRule.description
|
||||
let triggeringComments = [
|
||||
|
||||
@@ -1,16 +1,20 @@
|
||||
@testable import SwiftLintBuiltInRules
|
||||
import TestHelpers
|
||||
import XCTest
|
||||
import Testing
|
||||
|
||||
final class TypeBodyLengthConfigurationTests: SwiftLintTestCase {
|
||||
func testDefaultConfiguration() {
|
||||
@testable import SwiftLintBuiltInRules
|
||||
|
||||
@Suite(.rulesRegistered)
|
||||
struct TypeBodyLengthConfigurationTests {
|
||||
@Test
|
||||
func defaultConfiguration() {
|
||||
let config = TypeBodyLengthConfiguration()
|
||||
XCTAssertEqual(config.severityConfiguration.warning, 250)
|
||||
XCTAssertEqual(config.severityConfiguration.error, 350)
|
||||
XCTAssertEqual(config.excludedTypes, [.extension, .protocol])
|
||||
#expect(config.severityConfiguration.warning == 250)
|
||||
#expect(config.severityConfiguration.error == 350)
|
||||
#expect(config.excludedTypes == [.extension, .protocol])
|
||||
}
|
||||
|
||||
func testApplyingCustomConfiguration() throws {
|
||||
@Test
|
||||
func applyingCustomConfiguration() throws {
|
||||
var config = TypeBodyLengthConfiguration()
|
||||
try config.apply(
|
||||
configuration: [
|
||||
@@ -19,58 +23,63 @@ final class TypeBodyLengthConfigurationTests: SwiftLintTestCase {
|
||||
"excluded_types": ["struct", "class"],
|
||||
] as [String: any Sendable]
|
||||
)
|
||||
XCTAssertEqual(config.severityConfiguration.warning, 150)
|
||||
XCTAssertEqual(config.severityConfiguration.error, 200)
|
||||
XCTAssertEqual(config.excludedTypes, Set([.struct, .class]))
|
||||
#expect(config.severityConfiguration.warning == 150)
|
||||
#expect(config.severityConfiguration.error == 200)
|
||||
#expect(config.excludedTypes == Set([.struct, .class]))
|
||||
}
|
||||
|
||||
func testApplyingOnlyExcludedTypesConfiguration() throws {
|
||||
@Test
|
||||
func applyingOnlyExcludedTypesConfiguration() throws {
|
||||
var config = TypeBodyLengthConfiguration()
|
||||
try config.apply(
|
||||
configuration: [
|
||||
"excluded_types": ["actor", "enum"]
|
||||
] as [String: any Sendable]
|
||||
)
|
||||
configuration: [
|
||||
"excluded_types": ["actor", "enum"]
|
||||
] as [String: any Sendable]
|
||||
)
|
||||
|
||||
// Severity should remain default
|
||||
XCTAssertEqual(config.severityConfiguration.warning, 250)
|
||||
XCTAssertEqual(config.severityConfiguration.error, 350)
|
||||
#expect(config.severityConfiguration.warning == 250)
|
||||
#expect(config.severityConfiguration.error == 350)
|
||||
|
||||
// Excluded types should be updated
|
||||
XCTAssertEqual(config.excludedTypes, Set([.actor, .enum]))
|
||||
#expect(config.excludedTypes == Set([.actor, .enum]))
|
||||
}
|
||||
|
||||
func testApplyingAllTypesAsExcludedConfiguration() throws {
|
||||
@Test
|
||||
func applyingAllTypesAsExcludedConfiguration() throws {
|
||||
var config = TypeBodyLengthConfiguration()
|
||||
try config.apply(
|
||||
configuration: [
|
||||
"excluded_types": ["struct", "class", "actor", "enum", "extension", "protocol"]
|
||||
] as [String: any Sendable]
|
||||
)
|
||||
XCTAssertEqual(config.excludedTypes, Set(TypeBodyLengthCheckType.allCases))
|
||||
#expect(config.excludedTypes == Set(TypeBodyLengthCheckType.allCases))
|
||||
}
|
||||
|
||||
func testApplyingEmptyExcludedTypesConfiguration() throws {
|
||||
@Test
|
||||
func applyingEmptyExcludedTypesConfiguration() throws {
|
||||
var config = TypeBodyLengthConfiguration()
|
||||
try config.apply(
|
||||
configuration: [
|
||||
"excluded_types": [] as [String]
|
||||
] as [String: any Sendable]
|
||||
)
|
||||
XCTAssertTrue(config.excludedTypes.isEmpty)
|
||||
#expect(config.excludedTypes.isEmpty)
|
||||
}
|
||||
|
||||
func testApplyingSingleExcludedTypeConfiguration() throws {
|
||||
@Test
|
||||
func applyingSingleExcludedTypeConfiguration() throws {
|
||||
var config = TypeBodyLengthConfiguration()
|
||||
try config.apply(
|
||||
configuration: [
|
||||
"excluded_types": ["extension"]
|
||||
] as [String: any Sendable]
|
||||
)
|
||||
XCTAssertEqual(config.excludedTypes, Set([.extension]))
|
||||
#expect(config.excludedTypes == Set([.extension]))
|
||||
}
|
||||
|
||||
func testInvalidExcludedTypeConfiguration() throws {
|
||||
@Test
|
||||
func invalidExcludedTypeConfiguration() throws {
|
||||
var config = TypeBodyLengthConfiguration()
|
||||
checkError(Issue.invalidConfiguration(ruleID: TypeBodyLengthRule.identifier)) {
|
||||
try config.apply(
|
||||
@@ -79,13 +88,13 @@ final class TypeBodyLengthConfigurationTests: SwiftLintTestCase {
|
||||
] as [String: any Sendable]
|
||||
)
|
||||
}
|
||||
XCTAssertEqual(config.excludedTypes, Set([.extension, .protocol]))
|
||||
#expect(config.excludedTypes == Set([.extension, .protocol]))
|
||||
}
|
||||
|
||||
func testTypeEnumComparability() {
|
||||
XCTAssertEqual(
|
||||
TypeBodyLengthCheckType.allCases.sorted(),
|
||||
[.actor, .class, .enum, .extension, .protocol, .struct]
|
||||
@Test
|
||||
func typeEnumComparability() {
|
||||
#expect(
|
||||
TypeBodyLengthCheckType.allCases.sorted() == [.actor, .class, .enum, .extension, .protocol, .struct]
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
@testable import SwiftLintBuiltInRules
|
||||
import TestHelpers
|
||||
import XCTest
|
||||
import Testing
|
||||
|
||||
final class TypeBodyLengthRuleTests: SwiftLintTestCase {
|
||||
func testWarning() {
|
||||
@testable import SwiftLintBuiltInRules
|
||||
|
||||
@Suite(.rulesRegistered)
|
||||
struct TypeBodyLengthRuleTests {
|
||||
@Test
|
||||
func warning() {
|
||||
let example = Example("""
|
||||
actor A {
|
||||
let x = 0
|
||||
@@ -12,9 +15,8 @@ final class TypeBodyLengthRuleTests: SwiftLintTestCase {
|
||||
}
|
||||
""")
|
||||
|
||||
XCTAssertEqual(
|
||||
self.violations(example, configuration: ["warning": 2, "error": 4]),
|
||||
[
|
||||
#expect(
|
||||
self.violations(example, configuration: ["warning": 2, "error": 4]) == [
|
||||
StyleViolation(
|
||||
ruleDescription: TypeBodyLengthRule.description,
|
||||
severity: .warning,
|
||||
@@ -28,7 +30,8 @@ final class TypeBodyLengthRuleTests: SwiftLintTestCase {
|
||||
)
|
||||
}
|
||||
|
||||
func testError() {
|
||||
@Test
|
||||
func error() {
|
||||
let example = Example("""
|
||||
class C {
|
||||
let x = 0
|
||||
@@ -37,9 +40,8 @@ final class TypeBodyLengthRuleTests: SwiftLintTestCase {
|
||||
}
|
||||
""")
|
||||
|
||||
XCTAssertEqual(
|
||||
self.violations(example, configuration: ["warning": 1, "error": 2]),
|
||||
[
|
||||
#expect(
|
||||
self.violations(example, configuration: ["warning": 1, "error": 2]) == [
|
||||
StyleViolation(
|
||||
ruleDescription: TypeBodyLengthRule.description,
|
||||
severity: .error,
|
||||
@@ -53,16 +55,16 @@ final class TypeBodyLengthRuleTests: SwiftLintTestCase {
|
||||
)
|
||||
}
|
||||
|
||||
func testViolationMessages() {
|
||||
@Test
|
||||
func violationMessages() {
|
||||
let types = TypeBodyLengthRule.description.triggeringExamples.flatMap {
|
||||
self.violations($0, configuration: ["warning": 2])
|
||||
violations($0, configuration: ["warning": 2])
|
||||
}.compactMap {
|
||||
$0.reason.split(separator: " ", maxSplits: 1).first
|
||||
}
|
||||
|
||||
XCTAssertEqual(
|
||||
types,
|
||||
["Actor", "Class", "Enum", "Extension", "Protocol", "Struct"]
|
||||
#expect(
|
||||
types == ["Actor", "Class", "Enum", "Extension", "Protocol", "Struct"]
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
@testable import SwiftLintBuiltInRules
|
||||
import TestHelpers
|
||||
import Testing
|
||||
|
||||
final class TypeContentsOrderRuleTests: SwiftLintTestCase {
|
||||
// swiftlint:disable:next function_body_length
|
||||
func testTypeContentsOrderReversedOrder() {
|
||||
@testable import SwiftLintBuiltInRules
|
||||
|
||||
@Suite(.rulesRegistered)
|
||||
struct TypeContentsOrderRuleTests {
|
||||
@Test
|
||||
func typeContentsOrderReversedOrder() { // swiftlint:disable:this function_body_length
|
||||
// Test with reversed `order` entries
|
||||
let nonTriggeringExamples = [
|
||||
Example([
|
||||
@@ -164,8 +167,8 @@ final class TypeContentsOrderRuleTests: SwiftLintTestCase {
|
||||
)
|
||||
}
|
||||
|
||||
// swiftlint:disable:next function_body_length
|
||||
func testTypeContentsOrderGroupedOrder() {
|
||||
@Test
|
||||
func typeContentsOrderGroupedOrder() { // swiftlint:disable:this function_body_length
|
||||
// Test with grouped `order` entries
|
||||
let nonTriggeringExamples = [
|
||||
Example("""
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
@testable import SwiftLintBuiltInRules
|
||||
import TestHelpers
|
||||
import Testing
|
||||
|
||||
final class TypeNameRuleTests: SwiftLintTestCase {
|
||||
func testTypeNameWithExcluded() {
|
||||
@testable import SwiftLintBuiltInRules
|
||||
|
||||
@Suite(.rulesRegistered)
|
||||
struct TypeNameRuleTests {
|
||||
@Test
|
||||
func typeNameWithExcluded() {
|
||||
let baseDescription = TypeNameRule.description
|
||||
let nonTriggeringExamples = baseDescription.nonTriggeringExamples + [
|
||||
Example("class apple {}"),
|
||||
@@ -18,7 +22,8 @@ final class TypeNameRuleTests: SwiftLintTestCase {
|
||||
verifyRule(description, ruleConfiguration: ["excluded": ["apple", "some.*", ".*st\\d+.*"]])
|
||||
}
|
||||
|
||||
func testTypeNameWithAllowedSymbols() {
|
||||
@Test
|
||||
func typeNameWithAllowedSymbols() {
|
||||
let baseDescription = TypeNameRule.description
|
||||
let nonTriggeringExamples = baseDescription.nonTriggeringExamples + [
|
||||
Example("class MyType$ {}"),
|
||||
@@ -32,7 +37,8 @@ final class TypeNameRuleTests: SwiftLintTestCase {
|
||||
verifyRule(description, ruleConfiguration: ["allowed_symbols": ["$"]])
|
||||
}
|
||||
|
||||
func testTypeNameWithAllowedSymbolsAndViolation() {
|
||||
@Test
|
||||
func typeNameWithAllowedSymbolsAndViolation() {
|
||||
let baseDescription = TypeNameRule.description
|
||||
let triggeringExamples = [
|
||||
Example("class ↓My_Type$ {}")
|
||||
@@ -42,7 +48,8 @@ final class TypeNameRuleTests: SwiftLintTestCase {
|
||||
verifyRule(description, ruleConfiguration: ["allowed_symbols": ["$", "%"]])
|
||||
}
|
||||
|
||||
func testTypeNameWithIgnoreStartWithLowercase() {
|
||||
@Test
|
||||
func typeNameWithIgnoreStartWithLowercase() {
|
||||
let baseDescription = TypeNameRule.description
|
||||
let triggeringExamplesToRemove = [
|
||||
Example("private typealias ↓foo = Void"),
|
||||
|
||||
@@ -1,20 +1,16 @@
|
||||
@testable import SwiftLintBuiltInRules
|
||||
import TestHelpers
|
||||
import XCTest
|
||||
import Testing
|
||||
|
||||
final class TypesafeArrayInitRuleTests: SwiftLintTestCase {
|
||||
func testViolationRuleIdentifier() {
|
||||
@testable import SwiftLintBuiltInRules
|
||||
|
||||
@Suite(.rulesRegistered)
|
||||
struct TypesafeArrayInitRuleTests {
|
||||
@Test
|
||||
func violationRuleIdentifier() throws {
|
||||
let baseDescription = TypesafeArrayInitRule.description
|
||||
guard let triggeringExample = baseDescription.triggeringExamples.first else {
|
||||
XCTFail("No triggering examples found")
|
||||
return
|
||||
}
|
||||
guard let config = makeConfig(nil, baseDescription.identifier) else {
|
||||
XCTFail("Failed to create configuration")
|
||||
return
|
||||
}
|
||||
let triggeringExample = try #require(baseDescription.triggeringExamples.first)
|
||||
let config = try #require(makeConfig(nil, baseDescription.identifier))
|
||||
let violations = violations(triggeringExample, config: config, requiresFileOnDisk: true)
|
||||
XCTAssertGreaterThanOrEqual(violations.count, 1)
|
||||
XCTAssertEqual(violations.first?.ruleIdentifier, baseDescription.identifier)
|
||||
#expect(violations.first?.ruleIdentifier == baseDescription.identifier)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
@testable import SwiftLintBuiltInRules
|
||||
import TestHelpers
|
||||
import Testing
|
||||
|
||||
final class UnneededOverrideRuleTests: SwiftLintTestCase {
|
||||
func testIncludeAffectInits() {
|
||||
@testable import SwiftLintBuiltInRules
|
||||
|
||||
@Suite(.rulesRegistered)
|
||||
struct UnneededOverrideRuleTests {
|
||||
@Test
|
||||
func includeAffectInits() {
|
||||
let nonTriggeringExamples = [
|
||||
Example("""
|
||||
override init() {
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
@testable import SwiftLintBuiltInRules
|
||||
import XCTest
|
||||
import Testing
|
||||
|
||||
final class UnusedDeclarationConfigurationTests: XCTestCase {
|
||||
func testParseConfiguration() throws {
|
||||
@testable import SwiftLintBuiltInRules
|
||||
|
||||
@Suite(.rulesRegistered)
|
||||
struct UnusedDeclarationConfigurationTests {
|
||||
@Test
|
||||
func parseConfiguration() throws {
|
||||
var testee = UnusedDeclarationConfiguration()
|
||||
let config = [
|
||||
"severity": "warning",
|
||||
@@ -12,8 +15,8 @@ final class UnusedDeclarationConfigurationTests: XCTestCase {
|
||||
|
||||
try testee.apply(configuration: config)
|
||||
|
||||
XCTAssertEqual(testee.severityConfiguration.severity, .warning)
|
||||
XCTAssertTrue(testee.includePublicAndOpen)
|
||||
XCTAssertEqual(testee.relatedUSRsToSkip, ["a", "b", "s:7SwiftUI15PreviewProviderP"])
|
||||
#expect(testee.severityConfiguration.severity == .warning)
|
||||
#expect(testee.includePublicAndOpen)
|
||||
#expect(testee.relatedUSRsToSkip == ["a", "b", "s:7SwiftUI15PreviewProviderP"])
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
@testable import SwiftLintBuiltInRules
|
||||
import TestHelpers
|
||||
import Testing
|
||||
|
||||
final class UnusedOptionalBindingRuleTests: SwiftLintTestCase {
|
||||
func testDefaultConfiguration() {
|
||||
@testable import SwiftLintBuiltInRules
|
||||
|
||||
@Suite(.rulesRegistered)
|
||||
struct UnusedOptionalBindingRuleTests {
|
||||
@Test
|
||||
func defaultConfiguration() {
|
||||
let baseDescription = UnusedOptionalBindingRule.description
|
||||
let triggeringExamples = baseDescription.triggeringExamples + [
|
||||
Example("guard let _ = try? alwaysThrows() else { return }")
|
||||
@@ -12,7 +16,8 @@ final class UnusedOptionalBindingRuleTests: SwiftLintTestCase {
|
||||
verifyRule(description)
|
||||
}
|
||||
|
||||
func testIgnoreOptionalTryEnabled() {
|
||||
@Test
|
||||
func ignoreOptionalTryEnabled() {
|
||||
// Perform additional tests with the ignore_optional_try settings enabled.
|
||||
let baseDescription = UnusedOptionalBindingRule.description
|
||||
let nonTriggeringExamples = baseDescription.nonTriggeringExamples + [
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
@testable import SwiftLintBuiltInRules
|
||||
import TestHelpers
|
||||
import XCTest
|
||||
import Testing
|
||||
|
||||
final class VerticalWhitespaceRuleTests: SwiftLintTestCase {
|
||||
@testable import SwiftLintBuiltInRules
|
||||
|
||||
@Suite(.rulesRegistered)
|
||||
struct VerticalWhitespaceRuleTests {
|
||||
private let ruleID = VerticalWhitespaceRule.identifier
|
||||
|
||||
func testAttributesWithMaxEmptyLines() {
|
||||
@Test
|
||||
func attributesWithMaxEmptyLines() {
|
||||
// Test with custom `max_empty_lines`
|
||||
let maxEmptyLinesDescription = VerticalWhitespaceRule.description
|
||||
.with(nonTriggeringExamples: [Example("let aaaa = 0\n\n\n")])
|
||||
@@ -15,11 +18,11 @@ final class VerticalWhitespaceRuleTests: SwiftLintTestCase {
|
||||
])
|
||||
.with(corrections: [:])
|
||||
|
||||
verifyRule(maxEmptyLinesDescription,
|
||||
ruleConfiguration: ["max_empty_lines": 2])
|
||||
verifyRule(maxEmptyLinesDescription, ruleConfiguration: ["max_empty_lines": 2])
|
||||
}
|
||||
|
||||
func testAutoCorrectionWithMaxEmptyLines() {
|
||||
@Test
|
||||
func autoCorrectionWithMaxEmptyLines() {
|
||||
let maxEmptyLinesDescription = VerticalWhitespaceRule.description
|
||||
.with(nonTriggeringExamples: [])
|
||||
.with(triggeringExamples: [])
|
||||
@@ -29,32 +32,21 @@ final class VerticalWhitespaceRuleTests: SwiftLintTestCase {
|
||||
Example("class BB {\n \n \n↓ \n let b = 0\n}\n"): Example("class BB {\n \n \n let b = 0\n}\n"),
|
||||
])
|
||||
|
||||
verifyRule(maxEmptyLinesDescription,
|
||||
ruleConfiguration: ["max_empty_lines": 2])
|
||||
verifyRule(maxEmptyLinesDescription, ruleConfiguration: ["max_empty_lines": 2])
|
||||
}
|
||||
|
||||
func testViolationMessageWithMaxEmptyLines() {
|
||||
guard let config = makeConfig(["max_empty_lines": 2], ruleID) else {
|
||||
XCTFail("Failed to create configuration")
|
||||
return
|
||||
}
|
||||
@Test
|
||||
func violationMessageWithMaxEmptyLines() throws {
|
||||
let config = try #require(makeConfig(["max_empty_lines": 2], ruleID))
|
||||
let allViolations = violations(Example("let aaaa = 0\n\n\n\nlet bbb = 2\n"), config: config)
|
||||
|
||||
let verticalWhiteSpaceViolation = allViolations.first { $0.ruleIdentifier == ruleID }
|
||||
if let violation = verticalWhiteSpaceViolation {
|
||||
XCTAssertEqual(violation.reason, "Limit vertical whitespace to maximum 2 empty lines; currently 3")
|
||||
} else {
|
||||
XCTFail("A vertical whitespace violation should have been triggered!")
|
||||
}
|
||||
let violation = try #require(allViolations.first { $0.ruleIdentifier == ruleID })
|
||||
#expect(violation.reason == "Limit vertical whitespace to maximum 2 empty lines; currently 3")
|
||||
}
|
||||
|
||||
func testViolationMessageWithDefaultConfiguration() {
|
||||
@Test
|
||||
func violationMessageWithDefaultConfiguration() throws {
|
||||
let allViolations = violations(Example("let aaaa = 0\n\n\n\nlet bbb = 2\n"))
|
||||
let verticalWhiteSpaceViolation = allViolations.first(where: { $0.ruleIdentifier == ruleID })
|
||||
if let violation = verticalWhiteSpaceViolation {
|
||||
XCTAssertEqual(violation.reason, "Limit vertical whitespace to a single empty line; currently 3")
|
||||
} else {
|
||||
XCTFail("A vertical whitespace violation should have been triggered!")
|
||||
}
|
||||
let violation = try #require(allViolations.first { $0.ruleIdentifier == ruleID })
|
||||
#expect(violation.reason == "Limit vertical whitespace to a single empty line; currently 3")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,234 +1,265 @@
|
||||
@testable import SwiftLintBuiltInRules
|
||||
import TestHelpers
|
||||
import XCTest
|
||||
import Testing
|
||||
|
||||
final class XCTSpecificMatcherRuleTests: SwiftLintTestCase {
|
||||
func testEqualTrue() {
|
||||
@testable import SwiftLintBuiltInRules
|
||||
|
||||
@Suite(.rulesRegistered)
|
||||
struct XCTSpecificMatcherRuleTests {
|
||||
@Test
|
||||
func equalTrue() {
|
||||
let example = Example("XCTAssertEqual(a, true)")
|
||||
let violations = self.violations(example)
|
||||
|
||||
XCTAssertEqual(violations.count, 1)
|
||||
XCTAssertEqual(violations.first?.reason, "Prefer the specific matcher 'XCTAssertTrue' instead")
|
||||
#expect(violations.count == 1)
|
||||
#expect(violations.first?.reason == "Prefer the specific matcher 'XCTAssertTrue' instead")
|
||||
}
|
||||
|
||||
func testEqualFalse() {
|
||||
@Test
|
||||
func equalFalse() {
|
||||
let example = Example("XCTAssertEqual(a, false)")
|
||||
let violations = self.violations(example)
|
||||
|
||||
XCTAssertEqual(violations.count, 1)
|
||||
XCTAssertEqual(violations.first?.reason, "Prefer the specific matcher 'XCTAssertFalse' instead")
|
||||
#expect(violations.count == 1)
|
||||
#expect(violations.first?.reason == "Prefer the specific matcher 'XCTAssertFalse' instead")
|
||||
}
|
||||
|
||||
func testEqualNil() {
|
||||
@Test
|
||||
func equalNil() {
|
||||
let example = Example("XCTAssertEqual(a, nil)")
|
||||
let violations = self.violations(example)
|
||||
|
||||
XCTAssertEqual(violations.count, 1)
|
||||
XCTAssertEqual(violations.first?.reason, "Prefer the specific matcher 'XCTAssertNil' instead")
|
||||
#expect(violations.count == 1)
|
||||
#expect(violations.first?.reason == "Prefer the specific matcher 'XCTAssertNil' instead")
|
||||
}
|
||||
|
||||
func testNotEqualTrue() {
|
||||
@Test
|
||||
func notEqualTrue() {
|
||||
let example = Example("XCTAssertNotEqual(a, true)")
|
||||
let violations = self.violations(example)
|
||||
|
||||
XCTAssertEqual(violations.count, 1)
|
||||
XCTAssertEqual(violations.first?.reason, "Prefer the specific matcher 'XCTAssertFalse' instead")
|
||||
#expect(violations.count == 1)
|
||||
#expect(violations.first?.reason == "Prefer the specific matcher 'XCTAssertFalse' instead")
|
||||
}
|
||||
|
||||
func testNotEqualFalse() {
|
||||
@Test
|
||||
func notEqualFalse() {
|
||||
let example = Example("XCTAssertNotEqual(a, false)")
|
||||
let violations = self.violations(example)
|
||||
|
||||
XCTAssertEqual(violations.count, 1)
|
||||
XCTAssertEqual(violations.first?.reason, "Prefer the specific matcher 'XCTAssertTrue' instead")
|
||||
#expect(violations.count == 1)
|
||||
#expect(violations.first?.reason == "Prefer the specific matcher 'XCTAssertTrue' instead")
|
||||
}
|
||||
|
||||
func testNotEqualNil() {
|
||||
@Test
|
||||
func notEqualNil() {
|
||||
let example = Example("XCTAssertNotEqual(a, nil)")
|
||||
let violations = self.violations(example)
|
||||
|
||||
XCTAssertEqual(violations.count, 1)
|
||||
XCTAssertEqual(violations.first?.reason, "Prefer the specific matcher 'XCTAssertNotNil' instead")
|
||||
#expect(violations.count == 1)
|
||||
#expect(violations.first?.reason == "Prefer the specific matcher 'XCTAssertNotNil' instead")
|
||||
}
|
||||
|
||||
// MARK: - Additional Tests
|
||||
|
||||
func testEqualOptionalFalse() {
|
||||
@Test
|
||||
func equalOptionalFalse() {
|
||||
let example = Example("XCTAssertEqual(a?.b, false)")
|
||||
let violations = self.violations(example)
|
||||
|
||||
XCTAssertEqual(violations.count, 0)
|
||||
#expect(violations.isEmpty)
|
||||
}
|
||||
|
||||
func testEqualUnwrappedOptionalFalse() {
|
||||
@Test
|
||||
func equalUnwrappedOptionalFalse() {
|
||||
let example = Example("XCTAssertEqual(a!.b, false)")
|
||||
let violations = self.violations(example)
|
||||
|
||||
XCTAssertEqual(violations.count, 1)
|
||||
XCTAssertEqual(violations.first?.reason, "Prefer the specific matcher 'XCTAssertFalse' instead")
|
||||
#expect(violations.count == 1)
|
||||
#expect(violations.first?.reason == "Prefer the specific matcher 'XCTAssertFalse' instead")
|
||||
}
|
||||
|
||||
func testEqualNilNil() {
|
||||
@Test
|
||||
func equalNilNil() {
|
||||
let example = Example("XCTAssertEqual(nil, nil)")
|
||||
let violations = self.violations(example)
|
||||
|
||||
XCTAssertEqual(violations.count, 1)
|
||||
XCTAssertEqual(violations.first?.reason, "Prefer the specific matcher 'XCTAssertNil' instead")
|
||||
#expect(violations.count == 1)
|
||||
#expect(violations.first?.reason == "Prefer the specific matcher 'XCTAssertNil' instead")
|
||||
}
|
||||
|
||||
func testEqualTrueTrue() {
|
||||
@Test
|
||||
func equalTrueTrue() {
|
||||
let example = Example("XCTAssertEqual(true, true)")
|
||||
let violations = self.violations(example)
|
||||
|
||||
XCTAssertEqual(violations.count, 1)
|
||||
XCTAssertEqual(violations.first?.reason, "Prefer the specific matcher 'XCTAssertTrue' instead")
|
||||
#expect(violations.count == 1)
|
||||
#expect(violations.first?.reason == "Prefer the specific matcher 'XCTAssertTrue' instead")
|
||||
}
|
||||
|
||||
func testEqualFalseFalse() {
|
||||
@Test
|
||||
func equalFalseFalse() {
|
||||
let example = Example("XCTAssertEqual(false, false)")
|
||||
let violations = self.violations(example)
|
||||
|
||||
XCTAssertEqual(violations.count, 1)
|
||||
XCTAssertEqual(violations.first?.reason, "Prefer the specific matcher 'XCTAssertFalse' instead")
|
||||
#expect(violations.count == 1)
|
||||
#expect(violations.first?.reason == "Prefer the specific matcher 'XCTAssertFalse' instead")
|
||||
}
|
||||
|
||||
func testNotEqualNilNil() {
|
||||
@Test
|
||||
func notEqualNilNil() {
|
||||
let example = Example("XCTAssertNotEqual(nil, nil)")
|
||||
let violations = self.violations(example)
|
||||
|
||||
XCTAssertEqual(violations.count, 1)
|
||||
XCTAssertEqual(violations.first?.reason, "Prefer the specific matcher 'XCTAssertNotNil' instead")
|
||||
#expect(violations.count == 1)
|
||||
#expect(violations.first?.reason == "Prefer the specific matcher 'XCTAssertNotNil' instead")
|
||||
}
|
||||
|
||||
func testNotEqualTrueTrue() {
|
||||
@Test
|
||||
func notEqualTrueTrue() {
|
||||
let example = Example("XCTAssertNotEqual(true, true)")
|
||||
let violations = self.violations(example)
|
||||
|
||||
XCTAssertEqual(violations.count, 1)
|
||||
XCTAssertEqual(violations.first?.reason, "Prefer the specific matcher 'XCTAssertFalse' instead")
|
||||
#expect(violations.count == 1)
|
||||
#expect(violations.first?.reason == "Prefer the specific matcher 'XCTAssertFalse' instead")
|
||||
}
|
||||
|
||||
func testNotEqualFalseFalse() {
|
||||
@Test
|
||||
func notEqualFalseFalse() {
|
||||
let example = Example("XCTAssertNotEqual(false, false)")
|
||||
let violations = self.violations(example)
|
||||
|
||||
XCTAssertEqual(violations.count, 1)
|
||||
XCTAssertEqual(violations.first?.reason, "Prefer the specific matcher 'XCTAssertTrue' instead")
|
||||
#expect(violations.count == 1)
|
||||
#expect(violations.first?.reason == "Prefer the specific matcher 'XCTAssertTrue' instead")
|
||||
}
|
||||
|
||||
func testAssertEqual() {
|
||||
@Test
|
||||
func assertEqual() {
|
||||
let example = Example("XCTAssert(foo == bar)")
|
||||
let violations = self.violations(example)
|
||||
|
||||
XCTAssertEqual(violations.count, 1)
|
||||
XCTAssertEqual(violations.first?.reason, "Prefer the specific matcher 'XCTAssertEqual' instead")
|
||||
#expect(violations.count == 1)
|
||||
#expect(violations.first?.reason == "Prefer the specific matcher 'XCTAssertEqual' instead")
|
||||
}
|
||||
|
||||
func testAssertFalseNotEqual() {
|
||||
@Test
|
||||
func assertFalseNotEqual() {
|
||||
let example = Example("XCTAssertFalse(bar != foo)")
|
||||
let violations = self.violations(example)
|
||||
|
||||
XCTAssertEqual(violations.count, 1)
|
||||
XCTAssertEqual(violations.first?.reason, "Prefer the specific matcher 'XCTAssertEqual' instead")
|
||||
#expect(violations.count == 1)
|
||||
#expect(violations.first?.reason == "Prefer the specific matcher 'XCTAssertEqual' instead")
|
||||
}
|
||||
|
||||
func testAssertTrueEqual() {
|
||||
@Test
|
||||
func assertTrueEqual() {
|
||||
let example = Example("XCTAssertTrue(foo == 1)")
|
||||
let violations = self.violations(example)
|
||||
|
||||
XCTAssertEqual(violations.count, 1)
|
||||
XCTAssertEqual(violations.first?.reason, "Prefer the specific matcher 'XCTAssertEqual' instead")
|
||||
#expect(violations.count == 1)
|
||||
#expect(violations.first?.reason == "Prefer the specific matcher 'XCTAssertEqual' instead")
|
||||
}
|
||||
|
||||
func testAssertNotEqual() {
|
||||
@Test
|
||||
func assertNotEqual() {
|
||||
let example = Example("XCTAssert(foo != bar)")
|
||||
let violations = self.violations(example)
|
||||
|
||||
XCTAssertEqual(violations.count, 1)
|
||||
XCTAssertEqual(violations.first?.reason, "Prefer the specific matcher 'XCTAssertNotEqual' instead")
|
||||
#expect(violations.count == 1)
|
||||
#expect(violations.first?.reason == "Prefer the specific matcher 'XCTAssertNotEqual' instead")
|
||||
}
|
||||
|
||||
func testAssertFalseEqual() {
|
||||
@Test
|
||||
func assertFalseEqual() {
|
||||
let example = Example("XCTAssertFalse(bar == foo)")
|
||||
let violations = self.violations(example)
|
||||
|
||||
XCTAssertEqual(violations.count, 1)
|
||||
XCTAssertEqual(violations.first?.reason, "Prefer the specific matcher 'XCTAssertNotEqual' instead")
|
||||
#expect(violations.count == 1)
|
||||
#expect(violations.first?.reason == "Prefer the specific matcher 'XCTAssertNotEqual' instead")
|
||||
}
|
||||
|
||||
func testAssertTrueNotEqual() {
|
||||
@Test
|
||||
func assertTrueNotEqual() {
|
||||
let example = Example("XCTAssertTrue(foo != 1)")
|
||||
let violations = self.violations(example)
|
||||
|
||||
XCTAssertEqual(violations.count, 1)
|
||||
XCTAssertEqual(violations.first?.reason, "Prefer the specific matcher 'XCTAssertNotEqual' instead")
|
||||
#expect(violations.count == 1)
|
||||
#expect(violations.first?.reason == "Prefer the specific matcher 'XCTAssertNotEqual' instead")
|
||||
}
|
||||
|
||||
func testMultipleComparisons() {
|
||||
@Test
|
||||
func multipleComparisons() {
|
||||
let example = Example("XCTAssert(foo == (bar == baz))")
|
||||
let violations = self.violations(example)
|
||||
|
||||
XCTAssertEqual(violations.count, 1)
|
||||
XCTAssertEqual(violations.first?.reason, "Prefer the specific matcher 'XCTAssertEqual' instead")
|
||||
#expect(violations.count == 1)
|
||||
#expect(violations.first?.reason == "Prefer the specific matcher 'XCTAssertEqual' instead")
|
||||
}
|
||||
|
||||
func testEqualInCommentNotConsidered() {
|
||||
XCTAssert(noViolation(in: "XCTAssert(foo, \"a == b\")"))
|
||||
@Test
|
||||
func equalInCommentNotConsidered() {
|
||||
#expect(noViolation(in: "XCTAssert(foo, \"a == b\")"))
|
||||
}
|
||||
|
||||
func testEqualInFunctionCall() {
|
||||
XCTAssert(noViolation(in: "XCTAssert(foo(bar == baz))"))
|
||||
XCTAssert(noViolation(in: "XCTAssertTrue(foo(bar == baz), \"toto\")"))
|
||||
@Test
|
||||
func equalInFunctionCall() {
|
||||
#expect(noViolation(in: "XCTAssert(foo(bar == baz))"))
|
||||
#expect(noViolation(in: "XCTAssertTrue(foo(bar == baz), \"toto\")"))
|
||||
}
|
||||
|
||||
// MARK: - Identity Operator Tests
|
||||
|
||||
func testAssertIdentical() {
|
||||
@Test
|
||||
func assertIdentical() {
|
||||
let example = Example("XCTAssert(foo === bar)")
|
||||
let violations = self.violations(example)
|
||||
|
||||
XCTAssertEqual(violations.count, 1)
|
||||
XCTAssertEqual(violations.first?.reason, "Prefer the specific matcher 'XCTAssertIdentical' instead")
|
||||
#expect(violations.count == 1)
|
||||
#expect(violations.first?.reason == "Prefer the specific matcher 'XCTAssertIdentical' instead")
|
||||
}
|
||||
|
||||
func testAssertNotIdentical() {
|
||||
@Test
|
||||
func assertNotIdentical() {
|
||||
let example = Example("XCTAssert(foo !== bar)")
|
||||
let violations = self.violations(example)
|
||||
|
||||
XCTAssertEqual(violations.count, 1)
|
||||
XCTAssertEqual(violations.first?.reason, "Prefer the specific matcher 'XCTAssertNotIdentical' instead")
|
||||
#expect(violations.count == 1)
|
||||
#expect(violations.first?.reason == "Prefer the specific matcher 'XCTAssertNotIdentical' instead")
|
||||
}
|
||||
|
||||
func testAssertTrueIdentical() {
|
||||
@Test
|
||||
func assertTrueIdentical() {
|
||||
let example = Example("XCTAssertTrue(foo === bar)")
|
||||
let violations = self.violations(example)
|
||||
|
||||
XCTAssertEqual(violations.count, 1)
|
||||
XCTAssertEqual(violations.first?.reason, "Prefer the specific matcher 'XCTAssertIdentical' instead")
|
||||
#expect(violations.count == 1)
|
||||
#expect(violations.first?.reason == "Prefer the specific matcher 'XCTAssertIdentical' instead")
|
||||
}
|
||||
|
||||
func testAssertTrueNotIdentical() {
|
||||
@Test
|
||||
func assertTrueNotIdentical() {
|
||||
let example = Example("XCTAssertTrue(foo !== bar)")
|
||||
let violations = self.violations(example)
|
||||
|
||||
XCTAssertEqual(violations.count, 1)
|
||||
XCTAssertEqual(violations.first?.reason, "Prefer the specific matcher 'XCTAssertNotIdentical' instead")
|
||||
#expect(violations.count == 1)
|
||||
#expect(violations.first?.reason == "Prefer the specific matcher 'XCTAssertNotIdentical' instead")
|
||||
}
|
||||
|
||||
func testAssertFalseIdentical() {
|
||||
@Test
|
||||
func assertFalseIdentical() {
|
||||
let example = Example("XCTAssertFalse(foo === bar)")
|
||||
let violations = self.violations(example)
|
||||
|
||||
XCTAssertEqual(violations.count, 1)
|
||||
XCTAssertEqual(violations.first?.reason, "Prefer the specific matcher 'XCTAssertNotIdentical' instead")
|
||||
#expect(violations.count == 1)
|
||||
#expect(violations.first?.reason == "Prefer the specific matcher 'XCTAssertNotIdentical' instead")
|
||||
}
|
||||
|
||||
func testAssertFalseNotIdentical() {
|
||||
@Test
|
||||
func assertFalseNotIdentical() {
|
||||
let example = Example("XCTAssertFalse(foo !== bar)")
|
||||
let violations = self.violations(example)
|
||||
|
||||
XCTAssertEqual(violations.count, 1)
|
||||
XCTAssertEqual(violations.first?.reason, "Prefer the specific matcher 'XCTAssertIdentical' instead")
|
||||
#expect(violations.count == 1)
|
||||
#expect(violations.first?.reason == "Prefer the specific matcher 'XCTAssertIdentical' instead")
|
||||
}
|
||||
|
||||
private func violations(_ example: Example) -> [StyleViolation] {
|
||||
|
||||
@@ -1,22 +1,24 @@
|
||||
import SwiftLintCore
|
||||
import TestHelpers
|
||||
import XCTest
|
||||
import Testing
|
||||
|
||||
final class AccessControlLevelTests: SwiftLintTestCase {
|
||||
func testDescription() {
|
||||
XCTAssertEqual(AccessControlLevel.private.description, "private")
|
||||
XCTAssertEqual(AccessControlLevel.fileprivate.description, "fileprivate")
|
||||
XCTAssertEqual(AccessControlLevel.internal.description, "internal")
|
||||
XCTAssertEqual(AccessControlLevel.package.description, "package")
|
||||
XCTAssertEqual(AccessControlLevel.public.description, "public")
|
||||
XCTAssertEqual(AccessControlLevel.open.description, "open")
|
||||
@Suite
|
||||
struct AccessControlLevelTests {
|
||||
@Test
|
||||
func description() {
|
||||
#expect(AccessControlLevel.private.description == "private")
|
||||
#expect(AccessControlLevel.fileprivate.description == "fileprivate")
|
||||
#expect(AccessControlLevel.internal.description == "internal")
|
||||
#expect(AccessControlLevel.package.description == "package")
|
||||
#expect(AccessControlLevel.public.description == "public")
|
||||
#expect(AccessControlLevel.open.description == "open")
|
||||
}
|
||||
|
||||
func testPriority() {
|
||||
XCTAssertLessThan(AccessControlLevel.private, .fileprivate)
|
||||
XCTAssertLessThan(AccessControlLevel.fileprivate, .internal)
|
||||
XCTAssertLessThan(AccessControlLevel.internal, .package)
|
||||
XCTAssertLessThan(AccessControlLevel.package, .public)
|
||||
XCTAssertLessThan(AccessControlLevel.public, .open)
|
||||
@Test
|
||||
func priority() {
|
||||
#expect(AccessControlLevel.private < .fileprivate)
|
||||
#expect(AccessControlLevel.fileprivate < .internal)
|
||||
#expect(AccessControlLevel.internal < .package)
|
||||
#expect(AccessControlLevel.package < .public)
|
||||
#expect(AccessControlLevel.public < .open)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
import SwiftLintCore
|
||||
import SwiftParser
|
||||
import SwiftSyntax
|
||||
import XCTest
|
||||
import Testing
|
||||
|
||||
final class CodeIndentingRewriterTests: XCTestCase {
|
||||
func testIndentDefaultStyle() {
|
||||
@Suite
|
||||
struct CodeIndentingRewriterTests {
|
||||
@Test
|
||||
func indentDefaultStyle() {
|
||||
assertIndent(
|
||||
source: """
|
||||
if c {
|
||||
@@ -14,17 +16,18 @@ final class CodeIndentingRewriterTests: XCTestCase {
|
||||
}
|
||||
""",
|
||||
indentedSource: """
|
||||
if c {
|
||||
// comment
|
||||
return 1
|
||||
// another comment
|
||||
}
|
||||
""",
|
||||
if c {
|
||||
// comment
|
||||
return 1
|
||||
// another comment
|
||||
}
|
||||
""",
|
||||
style: .indentSpaces(4)
|
||||
)
|
||||
}
|
||||
|
||||
func testIndentThreeSpaces() {
|
||||
@Test
|
||||
func indentThreeSpaces() {
|
||||
assertIndent(
|
||||
source: """
|
||||
if c {
|
||||
@@ -34,17 +37,18 @@ final class CodeIndentingRewriterTests: XCTestCase {
|
||||
}
|
||||
""",
|
||||
indentedSource: """
|
||||
if c {
|
||||
// comment
|
||||
return 1
|
||||
// another comment
|
||||
}
|
||||
""",
|
||||
if c {
|
||||
// comment
|
||||
return 1
|
||||
// another comment
|
||||
}
|
||||
""",
|
||||
style: .indentSpaces(3)
|
||||
)
|
||||
}
|
||||
|
||||
func testIndentTabs() {
|
||||
@Test
|
||||
func indentTabs() {
|
||||
assertIndent(
|
||||
source: """
|
||||
if c {
|
||||
@@ -54,17 +58,18 @@ final class CodeIndentingRewriterTests: XCTestCase {
|
||||
}
|
||||
""",
|
||||
indentedSource: """
|
||||
\tif c {
|
||||
\t // comment
|
||||
\t return 1
|
||||
\t // another comment
|
||||
\t}
|
||||
""",
|
||||
\tif c {
|
||||
\t // comment
|
||||
\t return 1
|
||||
\t // another comment
|
||||
\t}
|
||||
""",
|
||||
style: .indentTabs(1)
|
||||
)
|
||||
}
|
||||
|
||||
func testIndentCodeBlock() {
|
||||
@Test
|
||||
func indentCodeBlock() {
|
||||
assertIndent(
|
||||
source: """
|
||||
// initial comment
|
||||
@@ -92,15 +97,16 @@ final class CodeIndentingRewriterTests: XCTestCase {
|
||||
)
|
||||
}
|
||||
|
||||
func testUnindentDefaultStyle() {
|
||||
@Test
|
||||
func unindentDefaultStyle() {
|
||||
assertIndent(
|
||||
source: """
|
||||
if c {
|
||||
// comment
|
||||
return 1
|
||||
// another comment
|
||||
}
|
||||
""",
|
||||
if c {
|
||||
// comment
|
||||
return 1
|
||||
// another comment
|
||||
}
|
||||
""",
|
||||
indentedSource: """
|
||||
if c {
|
||||
// comment
|
||||
@@ -112,15 +118,16 @@ final class CodeIndentingRewriterTests: XCTestCase {
|
||||
)
|
||||
}
|
||||
|
||||
func testUnindentTwoSpaces() {
|
||||
@Test
|
||||
func unindentTwoSpaces() {
|
||||
assertIndent(
|
||||
source: """
|
||||
if c {
|
||||
// comment
|
||||
return 1
|
||||
// another comment
|
||||
}
|
||||
""",
|
||||
if c {
|
||||
// comment
|
||||
return 1
|
||||
// another comment
|
||||
}
|
||||
""",
|
||||
indentedSource: """
|
||||
if c {
|
||||
// comment
|
||||
@@ -132,15 +139,16 @@ final class CodeIndentingRewriterTests: XCTestCase {
|
||||
)
|
||||
}
|
||||
|
||||
func testUnindentTabs() {
|
||||
@Test
|
||||
func unindentTabs() {
|
||||
assertIndent(
|
||||
source: """
|
||||
\tif c {
|
||||
\t\t // comment
|
||||
\t\treturn 1
|
||||
\t\t\t// another comment
|
||||
\t}
|
||||
""",
|
||||
\tif c {
|
||||
\t\t // comment
|
||||
\t\treturn 1
|
||||
\t\t\t// another comment
|
||||
\t}
|
||||
""",
|
||||
indentedSource: """
|
||||
if c {
|
||||
\t // comment
|
||||
@@ -154,6 +162,6 @@ final class CodeIndentingRewriterTests: XCTestCase {
|
||||
|
||||
private func assertIndent(source: String, indentedSource: String, style: CodeIndentingRewriter.IndentationStyle) {
|
||||
let rewritten = CodeIndentingRewriter(style: style).rewrite(Parser.parse(source: source))
|
||||
XCTAssertEqual(rewritten.description, indentedSource)
|
||||
#expect(rewritten.description == indentedSource)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,35 +1,41 @@
|
||||
@testable import SwiftLintCore
|
||||
import XCTest
|
||||
import SwiftLintCore
|
||||
import Testing
|
||||
|
||||
final class CommentLinesVisitorTests: XCTestCase {
|
||||
func testEmptyFile() {
|
||||
XCTAssertEqual(commentOnlyLines(in: ""), [])
|
||||
@Suite
|
||||
struct CommentLinesVisitorTests {
|
||||
@Test
|
||||
func emptyFile() {
|
||||
#expect(commentOnlyLines(in: "").isEmpty)
|
||||
}
|
||||
|
||||
func testSingleLineComment() {
|
||||
XCTAssertEqual(commentOnlyLines(in: "// This is a comment"), [1])
|
||||
@Test
|
||||
func singleLineComment() {
|
||||
#expect(commentOnlyLines(in: "// This is a comment") == [1])
|
||||
}
|
||||
|
||||
func testMultipleSingleLineComments() {
|
||||
@Test
|
||||
func multipleSingleLineComments() {
|
||||
let contents = """
|
||||
// First comment
|
||||
// Second comment
|
||||
// Third comment
|
||||
"""
|
||||
XCTAssertEqual(commentOnlyLines(in: contents), [1, 2, 3])
|
||||
#expect(commentOnlyLines(in: contents) == [1, 2, 3])
|
||||
}
|
||||
|
||||
func testBlockComment() {
|
||||
@Test
|
||||
func blockComment() {
|
||||
let contents = """
|
||||
/*
|
||||
* This is a block comment
|
||||
* spanning multiple lines
|
||||
*/
|
||||
"""
|
||||
XCTAssertEqual(commentOnlyLines(in: contents), [1, 2, 3, 4])
|
||||
#expect(commentOnlyLines(in: contents) == [1, 2, 3, 4])
|
||||
}
|
||||
|
||||
func testMixedCommentsAndCode() {
|
||||
@Test
|
||||
func mixedCommentsAndCode() {
|
||||
let contents = """
|
||||
// Comment at the top
|
||||
import Foundation
|
||||
@@ -41,29 +47,32 @@ final class CommentLinesVisitorTests: XCTestCase {
|
||||
}
|
||||
// Final comment
|
||||
"""
|
||||
XCTAssertEqual(commentOnlyLines(in: contents), [1, 4, 6, 9])
|
||||
#expect(commentOnlyLines(in: contents) == [1, 4, 6, 9])
|
||||
}
|
||||
|
||||
func testCommentsWithWhitespace() {
|
||||
@Test
|
||||
func commentsWithWhitespace() {
|
||||
let contents = """
|
||||
// Comment with leading spaces
|
||||
\t// Comment with leading tab
|
||||
\t // Comment with mixed whitespace
|
||||
"""
|
||||
XCTAssertEqual(commentOnlyLines(in: contents), [1, 2, 3])
|
||||
#expect(commentOnlyLines(in: contents) == [1, 2, 3])
|
||||
}
|
||||
|
||||
func testEmptyLinesIgnored() {
|
||||
@Test
|
||||
func emptyLinesIgnored() {
|
||||
let contents = """
|
||||
// First comment
|
||||
|
||||
|
||||
// Second comment after empty lines
|
||||
"""
|
||||
XCTAssertEqual(commentOnlyLines(in: contents), [1, 4])
|
||||
#expect(commentOnlyLines(in: contents) == [1, 4])
|
||||
}
|
||||
|
||||
func testDocumentationComments() {
|
||||
@Test
|
||||
func documentationComments() {
|
||||
let contents = """
|
||||
/// This is a documentation comment
|
||||
/// for a function
|
||||
@@ -72,26 +81,29 @@ final class CommentLinesVisitorTests: XCTestCase {
|
||||
*/
|
||||
func test() {}
|
||||
"""
|
||||
XCTAssertEqual(commentOnlyLines(in: contents), [1, 2, 3, 4, 5])
|
||||
#expect(commentOnlyLines(in: contents) == [1, 2, 3, 4, 5])
|
||||
}
|
||||
|
||||
func testInlineCommentsNotCounted() {
|
||||
@Test
|
||||
func inlineCommentsNotCounted() {
|
||||
let contents = """
|
||||
let x = 5 // This comment is on the same line as code
|
||||
print("test") /* inline block comment */
|
||||
"""
|
||||
XCTAssertEqual(commentOnlyLines(in: contents), [])
|
||||
#expect(commentOnlyLines(in: contents).isEmpty)
|
||||
}
|
||||
|
||||
func testCommentBlockStartedOnCodeLine() {
|
||||
@Test
|
||||
func commentBlockStartedOnCodeLine() {
|
||||
let contents = """
|
||||
print("test") /* block
|
||||
comment */
|
||||
"""
|
||||
XCTAssertEqual(commentOnlyLines(in: contents), [2])
|
||||
#expect(commentOnlyLines(in: contents) == [2])
|
||||
}
|
||||
|
||||
func testComplexExample() {
|
||||
@Test
|
||||
func complexExample() {
|
||||
let contents = """
|
||||
// Header comment
|
||||
/*
|
||||
@@ -118,10 +130,11 @@ final class CommentLinesVisitorTests: XCTestCase {
|
||||
// Trailing comment
|
||||
"""
|
||||
|
||||
XCTAssertEqual(commentOnlyLines(in: contents), [1, 2, 3, 4, 5, 9, 11, 14, 15, 16, 17, 19, 23])
|
||||
#expect(commentOnlyLines(in: contents) == [1, 2, 3, 4, 5, 9, 11, 14, 15, 16, 17, 19, 23])
|
||||
}
|
||||
|
||||
func testLineNumberAccuracy() {
|
||||
@Test
|
||||
func lineNumberAccuracy() {
|
||||
let contents = """
|
||||
let x = 1
|
||||
// Line 2 comment
|
||||
@@ -132,7 +145,7 @@ final class CommentLinesVisitorTests: XCTestCase {
|
||||
let z = 3 // Line 7 inline
|
||||
"""
|
||||
|
||||
XCTAssertEqual(commentOnlyLines(in: contents), [2, 4, 5, 6])
|
||||
#expect(commentOnlyLines(in: contents) == [2, 4, 5, 6])
|
||||
}
|
||||
|
||||
private func commentOnlyLines(in contents: String) -> [Int] {
|
||||
|
||||
@@ -1,86 +1,88 @@
|
||||
@testable import SwiftLintCore
|
||||
import XCTest
|
||||
import SwiftLintCore
|
||||
import Testing
|
||||
|
||||
final class ConditionallySourceKitFreeTests: XCTestCase {
|
||||
// Mock rule for testing ConditionallySourceKitFree protocol
|
||||
private struct MockConditionalRule: Rule, ConditionallySourceKitFree {
|
||||
static let description = RuleDescription(
|
||||
identifier: "mock_conditional",
|
||||
name: "Mock Conditional Rule",
|
||||
description: "A mock rule for testing ConditionallySourceKitFree",
|
||||
kind: .style
|
||||
)
|
||||
|
||||
var configuration = SeverityConfiguration<Self>(.warning)
|
||||
var isEffectivelySourceKitFree = true
|
||||
|
||||
func validate(file _: SwiftLintFile) -> [StyleViolation] {
|
||||
[]
|
||||
}
|
||||
}
|
||||
|
||||
private struct MockSourceKitFreeRule: Rule, SourceKitFreeRule {
|
||||
static let description = RuleDescription(
|
||||
identifier: "mock_sourcekit_free",
|
||||
name: "Mock SourceKit Free Rule",
|
||||
description: "A mock rule that is always SourceKit-free",
|
||||
kind: .style
|
||||
)
|
||||
|
||||
var configuration = SeverityConfiguration<Self>(.warning)
|
||||
|
||||
func validate(file _: SwiftLintFile) -> [StyleViolation] {
|
||||
[]
|
||||
}
|
||||
}
|
||||
|
||||
private struct MockRegularRule: Rule {
|
||||
static let description = RuleDescription(
|
||||
identifier: "mock_regular",
|
||||
name: "Mock Regular Rule",
|
||||
description: "A mock rule that requires SourceKit",
|
||||
kind: .style
|
||||
)
|
||||
|
||||
var configuration = SeverityConfiguration<Self>(.warning)
|
||||
|
||||
func validate(file _: SwiftLintFile) -> [StyleViolation] {
|
||||
[]
|
||||
}
|
||||
}
|
||||
|
||||
func testRequiresSourceKitForDifferentRuleTypes() {
|
||||
@Suite
|
||||
struct ConditionallySourceKitFreeTests {
|
||||
@Test
|
||||
func requiresSourceKitForDifferentRuleTypes() {
|
||||
// SourceKitFreeRule should not require SourceKit
|
||||
let sourceKitFreeRule = MockSourceKitFreeRule()
|
||||
XCTAssertFalse(sourceKitFreeRule.requiresSourceKit)
|
||||
#expect(!sourceKitFreeRule.requiresSourceKit)
|
||||
|
||||
// ConditionallySourceKitFree rule that is effectively SourceKit-free
|
||||
var conditionalRuleFree = MockConditionalRule()
|
||||
conditionalRuleFree.isEffectivelySourceKitFree = true
|
||||
XCTAssertFalse(conditionalRuleFree.requiresSourceKit)
|
||||
#expect(!conditionalRuleFree.requiresSourceKit)
|
||||
|
||||
// ConditionallySourceKitFree rule that requires SourceKit
|
||||
var conditionalRuleRequires = MockConditionalRule()
|
||||
conditionalRuleRequires.isEffectivelySourceKitFree = false
|
||||
XCTAssertTrue(conditionalRuleRequires.requiresSourceKit)
|
||||
#expect(conditionalRuleRequires.requiresSourceKit)
|
||||
|
||||
// Regular rule should require SourceKit
|
||||
let regularRule = MockRegularRule()
|
||||
XCTAssertTrue(regularRule.requiresSourceKit)
|
||||
#expect(regularRule.requiresSourceKit)
|
||||
}
|
||||
|
||||
func testTypeCheckingBehavior() {
|
||||
@Test
|
||||
func typeCheckingBehavior() {
|
||||
// Verify instance-level checks work correctly
|
||||
let sourceKitFreeRule: any Rule = MockSourceKitFreeRule()
|
||||
XCTAssertTrue(sourceKitFreeRule is any SourceKitFreeRule)
|
||||
XCTAssertFalse(sourceKitFreeRule is any ConditionallySourceKitFree)
|
||||
#expect(sourceKitFreeRule is any SourceKitFreeRule)
|
||||
#expect(!(sourceKitFreeRule is any ConditionallySourceKitFree))
|
||||
|
||||
let conditionalRule: any Rule = MockConditionalRule()
|
||||
XCTAssertFalse(conditionalRule is any SourceKitFreeRule)
|
||||
XCTAssertTrue(conditionalRule is any ConditionallySourceKitFree)
|
||||
#expect(!(conditionalRule is any SourceKitFreeRule))
|
||||
#expect(conditionalRule is any ConditionallySourceKitFree)
|
||||
|
||||
let regularRule: any Rule = MockRegularRule()
|
||||
XCTAssertFalse(regularRule is any SourceKitFreeRule)
|
||||
XCTAssertFalse(regularRule is any ConditionallySourceKitFree)
|
||||
#expect(!(regularRule is any SourceKitFreeRule))
|
||||
#expect(!(regularRule is any ConditionallySourceKitFree))
|
||||
}
|
||||
}
|
||||
|
||||
private struct MockConditionalRule: Rule, ConditionallySourceKitFree {
|
||||
static let description = RuleDescription(
|
||||
identifier: "mock_conditional",
|
||||
name: "Mock Conditional Rule",
|
||||
description: "A mock rule for testing ConditionallySourceKitFree",
|
||||
kind: .style
|
||||
)
|
||||
|
||||
var configuration = SeverityConfiguration<Self>(.warning)
|
||||
var isEffectivelySourceKitFree = true
|
||||
|
||||
func validate(file _: SwiftLintFile) -> [StyleViolation] {
|
||||
[]
|
||||
}
|
||||
}
|
||||
|
||||
private struct MockSourceKitFreeRule: Rule, SourceKitFreeRule {
|
||||
static let description = RuleDescription(
|
||||
identifier: "mock_sourcekit_free",
|
||||
name: "Mock SourceKit Free Rule",
|
||||
description: "A mock rule that is always SourceKit-free",
|
||||
kind: .style
|
||||
)
|
||||
|
||||
var configuration = SeverityConfiguration<Self>(.warning)
|
||||
|
||||
func validate(file _: SwiftLintFile) -> [StyleViolation] {
|
||||
[]
|
||||
}
|
||||
}
|
||||
|
||||
private struct MockRegularRule: Rule {
|
||||
static let description = RuleDescription(
|
||||
identifier: "mock_regular",
|
||||
name: "Mock Regular Rule",
|
||||
description: "A mock rule that requires SourceKit",
|
||||
kind: .style
|
||||
)
|
||||
|
||||
var configuration = SeverityConfiguration<Self>(.warning)
|
||||
|
||||
func validate(file _: SwiftLintFile) -> [StyleViolation] {
|
||||
[]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,162 +1,115 @@
|
||||
import SwiftLintCore
|
||||
import TestHelpers
|
||||
import XCTest
|
||||
import Testing
|
||||
|
||||
final class DisableAllTests: SwiftLintTestCase {
|
||||
@Suite(.rulesRegistered)
|
||||
struct DisableAllTests {
|
||||
/// Example violations. Could be replaced with other single violations.
|
||||
private let violatingPhrases = [
|
||||
Example("let r = 0"), // Violates identifier_name
|
||||
Example(#"let myString:String = """#), // Violates colon_whitespace
|
||||
Example("// TODO: Some todo"), // Violates todo
|
||||
private static let violatingPhrases = [
|
||||
Example("let r = 0"), // Violates identifier_name
|
||||
Example(#"let myString:String = """#), // Violates colon_whitespace
|
||||
Example("// TODO: Some todo"), // Violates todo
|
||||
]
|
||||
|
||||
// MARK: Violating Phrase
|
||||
/// Tests whether example violating phrases trigger when not applying disable rule
|
||||
func testViolatingPhrase() {
|
||||
for violatingPhrase in violatingPhrases {
|
||||
XCTAssertEqual(
|
||||
violations(violatingPhrase.with(code: violatingPhrase.code + "\n")).count,
|
||||
1,
|
||||
#function,
|
||||
file: violatingPhrase.file,
|
||||
line: violatingPhrase.line)
|
||||
}
|
||||
@Test(arguments: violatingPhrases)
|
||||
func violatingPhrase(_ violatingPhrase: Example) {
|
||||
#expect(violations(violatingPhrase.with(code: violatingPhrase.code + "\n")).count == 1)
|
||||
}
|
||||
|
||||
// MARK: Enable / Disable Base
|
||||
/// Tests whether swiftlint:disable all protects properly
|
||||
func testDisableAll() {
|
||||
for violatingPhrase in violatingPhrases {
|
||||
let code = "// swiftlint:disable all\n" + violatingPhrase.code + "\n// swiftlint:enable all\n"
|
||||
let protectedPhrase = violatingPhrase.with(code: code)
|
||||
XCTAssertEqual(
|
||||
violations(protectedPhrase).count,
|
||||
0,
|
||||
#function,
|
||||
file: violatingPhrase.file,
|
||||
line: violatingPhrase.line)
|
||||
}
|
||||
@Test(arguments: violatingPhrases)
|
||||
func disableAll(_ violatingPhrase: Example) {
|
||||
let code = "// swiftlint:disable all\n" + violatingPhrase.code + "\n// swiftlint:enable all\n"
|
||||
let protectedPhrase = violatingPhrase.with(code: code)
|
||||
#expect(violations(protectedPhrase).isEmpty)
|
||||
}
|
||||
|
||||
/// Tests whether swiftlint:enable all unprotects properly
|
||||
func testEnableAll() {
|
||||
for violatingPhrase in violatingPhrases {
|
||||
let unprotectedPhrase = violatingPhrase.with(code: """
|
||||
@Test(arguments: violatingPhrases)
|
||||
func enableAll(_ violatingPhrase: Example) {
|
||||
let unprotectedPhrase = violatingPhrase.with(
|
||||
code: """
|
||||
// swiftlint:disable all
|
||||
\(violatingPhrase.code)
|
||||
// swiftlint:enable all
|
||||
\(violatingPhrase.code)\n
|
||||
""")
|
||||
XCTAssertEqual(
|
||||
violations(unprotectedPhrase).count,
|
||||
1,
|
||||
#function,
|
||||
file: violatingPhrase.file,
|
||||
line: violatingPhrase.line)
|
||||
}
|
||||
#expect(violations(unprotectedPhrase).count == 1)
|
||||
}
|
||||
|
||||
// MARK: Enable / Disable Previous
|
||||
/// Tests whether swiftlint:disable:previous all protects properly
|
||||
func testDisableAllPrevious() {
|
||||
for violatingPhrase in violatingPhrases {
|
||||
let protectedPhrase = violatingPhrase
|
||||
.with(code: """
|
||||
@Test(arguments: violatingPhrases)
|
||||
func disableAllPrevious(_ violatingPhrase: Example) {
|
||||
let protectedPhrase =
|
||||
violatingPhrase
|
||||
.with(
|
||||
code: """
|
||||
\(violatingPhrase.code)
|
||||
// swiftlint:disable:previous all\n
|
||||
""")
|
||||
XCTAssertEqual(
|
||||
violations(protectedPhrase).count,
|
||||
0,
|
||||
#function,
|
||||
file: violatingPhrase.file,
|
||||
line: violatingPhrase.line)
|
||||
}
|
||||
#expect(violations(protectedPhrase).isEmpty)
|
||||
}
|
||||
|
||||
/// Tests whether swiftlint:enable:previous all unprotects properly
|
||||
func testEnableAllPrevious() {
|
||||
for violatingPhrase in violatingPhrases {
|
||||
let unprotectedPhrase = violatingPhrase.with(code: """
|
||||
@Test(arguments: violatingPhrases)
|
||||
func enableAllPrevious(_ violatingPhrase: Example) {
|
||||
let unprotectedPhrase = violatingPhrase.with(
|
||||
code: """
|
||||
// swiftlint:disable all
|
||||
\(violatingPhrase.code)
|
||||
\(violatingPhrase.code)
|
||||
// swiftlint:enable:previous all
|
||||
// swiftlint:enable all
|
||||
""")
|
||||
XCTAssertEqual(
|
||||
violations(unprotectedPhrase).count,
|
||||
1,
|
||||
#function,
|
||||
file: violatingPhrase.file,
|
||||
line: violatingPhrase.line)
|
||||
}
|
||||
#expect(violations(unprotectedPhrase).count == 1)
|
||||
}
|
||||
|
||||
// MARK: Enable / Disable Next
|
||||
/// Tests whether swiftlint:disable:next all protects properly
|
||||
func testDisableAllNext() {
|
||||
for violatingPhrase in violatingPhrases {
|
||||
let protectedPhrase = violatingPhrase.with(code: "// swiftlint:disable:next all\n" + violatingPhrase.code)
|
||||
XCTAssertEqual(
|
||||
violations(protectedPhrase).count,
|
||||
0,
|
||||
#function,
|
||||
file: violatingPhrase.file,
|
||||
line: violatingPhrase.line)
|
||||
}
|
||||
@Test(arguments: violatingPhrases)
|
||||
func disableAllNext(_ violatingPhrase: Example) {
|
||||
let protectedPhrase = violatingPhrase.with(code: "// swiftlint:disable:next all\n" + violatingPhrase.code)
|
||||
#expect(violations(protectedPhrase).isEmpty)
|
||||
}
|
||||
|
||||
/// Tests whether swiftlint:enable:next all unprotects properly
|
||||
func testEnableAllNext() {
|
||||
for violatingPhrase in violatingPhrases {
|
||||
let unprotectedPhrase = violatingPhrase.with(code: """
|
||||
@Test(arguments: violatingPhrases)
|
||||
func enableAllNext(_ violatingPhrase: Example) {
|
||||
let unprotectedPhrase = violatingPhrase.with(
|
||||
code: """
|
||||
// swiftlint:disable all
|
||||
\(violatingPhrase.code)
|
||||
// swiftlint:enable:next all
|
||||
\(violatingPhrase.code)
|
||||
// swiftlint:enable all
|
||||
""")
|
||||
XCTAssertEqual(
|
||||
violations(unprotectedPhrase).count,
|
||||
1,
|
||||
#function,
|
||||
file: violatingPhrase.file,
|
||||
line: violatingPhrase.line)
|
||||
}
|
||||
#expect(violations(unprotectedPhrase).count == 1)
|
||||
}
|
||||
|
||||
// MARK: Enable / Disable This
|
||||
/// Tests whether swiftlint:disable:this all protects properly
|
||||
func testDisableAllThis() {
|
||||
for violatingPhrase in violatingPhrases {
|
||||
let rawViolatingPhrase = violatingPhrase.code.replacingOccurrences(of: "\n", with: "")
|
||||
let protectedPhrase = violatingPhrase.with(code: rawViolatingPhrase + "// swiftlint:disable:this all\n")
|
||||
XCTAssertEqual(
|
||||
violations(protectedPhrase).count,
|
||||
0,
|
||||
#function,
|
||||
file: violatingPhrase.file,
|
||||
line: violatingPhrase.line)
|
||||
}
|
||||
@Test(arguments: violatingPhrases)
|
||||
func disableAllThis(_ violatingPhrase: Example) {
|
||||
let rawViolatingPhrase = violatingPhrase.code.replacingOccurrences(of: "\n", with: "")
|
||||
let protectedPhrase = violatingPhrase.with(code: rawViolatingPhrase + "// swiftlint:disable:this all\n")
|
||||
#expect(violations(protectedPhrase).isEmpty)
|
||||
}
|
||||
|
||||
/// Tests whether swiftlint:enable:next all unprotects properly
|
||||
func testEnableAllThis() {
|
||||
for violatingPhrase in violatingPhrases {
|
||||
let rawViolatingPhrase = violatingPhrase.code.replacingOccurrences(of: "\n", with: "")
|
||||
let unprotectedPhrase = violatingPhrase.with(code: """
|
||||
@Test(arguments: violatingPhrases)
|
||||
func enableAllThis(_ violatingPhrase: Example) {
|
||||
let rawViolatingPhrase = violatingPhrase.code.replacingOccurrences(of: "\n", with: "")
|
||||
let unprotectedPhrase = violatingPhrase.with(
|
||||
code: """
|
||||
// swiftlint:disable all
|
||||
\(violatingPhrase.code)
|
||||
\(rawViolatingPhrase)// swiftlint:enable:this all
|
||||
// swiftlint:enable all
|
||||
""")
|
||||
XCTAssertEqual(
|
||||
violations(unprotectedPhrase).count,
|
||||
1,
|
||||
#function,
|
||||
file: violatingPhrase.file,
|
||||
line: violatingPhrase.line)
|
||||
}
|
||||
#expect(violations(unprotectedPhrase).count == 1)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,62 +1,67 @@
|
||||
import SwiftLintCore
|
||||
import TestHelpers
|
||||
import XCTest
|
||||
import SwiftLintFramework
|
||||
import Testing
|
||||
|
||||
final class ExampleTests: SwiftLintTestCase {
|
||||
func testEquatableDoesNotLookAtFile() {
|
||||
@Suite
|
||||
struct ExampleTests {
|
||||
@Test
|
||||
func equatableDoesNotLookAtFile() {
|
||||
let first = Example("foo", file: "a", line: 1)
|
||||
let second = Example("foo", file: "b", line: 1)
|
||||
XCTAssertEqual(first, second)
|
||||
#expect(first == second)
|
||||
}
|
||||
|
||||
func testEquatableDoesNotLookAtLine() {
|
||||
@Test
|
||||
func equatableDoesNotLookAtLine() {
|
||||
let first = Example("foo", file: "a", line: 1)
|
||||
let second = Example("foo", file: "a", line: 2)
|
||||
XCTAssertEqual(first, second)
|
||||
#expect(first == second)
|
||||
}
|
||||
|
||||
func testEquatableLooksAtCode() {
|
||||
@Test
|
||||
func equatableLooksAtCode() {
|
||||
let first = Example("a", file: "a", line: 1)
|
||||
let second = Example("a", file: "x", line: 2)
|
||||
let third = Example("c", file: "y", line: 2)
|
||||
XCTAssertEqual(first, second)
|
||||
XCTAssertNotEqual(first, third)
|
||||
#expect(first == second)
|
||||
#expect(first != third)
|
||||
}
|
||||
|
||||
func testTestMultiByteOffsets() {
|
||||
XCTAssertTrue(Example("").testMultiByteOffsets)
|
||||
XCTAssertTrue(Example("", testMultiByteOffsets: true).testMultiByteOffsets)
|
||||
XCTAssertFalse(Example("", testMultiByteOffsets: false).testMultiByteOffsets)
|
||||
@Test
|
||||
func testMultiByteOffsets() {
|
||||
#expect(Example("").testMultiByteOffsets)
|
||||
#expect(Example("", testMultiByteOffsets: true).testMultiByteOffsets)
|
||||
#expect(!Example("", testMultiByteOffsets: false).testMultiByteOffsets)
|
||||
}
|
||||
|
||||
func testTestOnLinux() {
|
||||
XCTAssertTrue(Example("").testOnLinux)
|
||||
XCTAssertTrue(Example("", testOnLinux: true).testOnLinux)
|
||||
XCTAssertFalse(Example("", testOnLinux: false).testOnLinux)
|
||||
@Test
|
||||
func testOnLinux() {
|
||||
#expect(Example("").testOnLinux)
|
||||
#expect(Example("", testOnLinux: true).testOnLinux)
|
||||
#expect(!Example("", testOnLinux: false).testOnLinux)
|
||||
}
|
||||
|
||||
func testRemovingViolationMarkers() {
|
||||
@Test
|
||||
func removingViolationMarkers() {
|
||||
let example = Example("↓T↓E↓S↓T")
|
||||
XCTAssertEqual(example.removingViolationMarkers(), Example("TEST"))
|
||||
#expect(example.removingViolationMarkers() == Example("TEST"))
|
||||
}
|
||||
|
||||
func testComparable() {
|
||||
XCTAssertLessThan(Example("a"), Example("b"))
|
||||
@Test
|
||||
func comparable() {
|
||||
#expect(Example("a") < Example("b"))
|
||||
}
|
||||
|
||||
func testWithCode() {
|
||||
@Test
|
||||
func withCode() {
|
||||
let original = Example("original code")
|
||||
XCTAssertNotNil(original.file)
|
||||
XCTAssertNotNil(original.line)
|
||||
#expect(original.code == "original code")
|
||||
|
||||
let new = original.with(code: "new code")
|
||||
XCTAssertEqual(new.code, "new code")
|
||||
XCTAssertNotNil(new.file)
|
||||
XCTAssertNotNil(new.line)
|
||||
#expect(new.code == "new code")
|
||||
|
||||
// When modifying the code, it's important that the file and line
|
||||
// numbers remain intact
|
||||
XCTAssertEqual(new.file.description, original.file.description)
|
||||
XCTAssertEqual(new.line, original.line)
|
||||
#expect(new.file.description == original.file.description)
|
||||
#expect(new.line == original.line)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import SourceKittenFramework
|
||||
import TestHelpers
|
||||
import XCTest
|
||||
import Testing
|
||||
|
||||
final class ExtendedNSStringTests: SwiftLintTestCase {
|
||||
func testLineAndCharacterForByteOffset_forContentsContainingMultibyteCharacters() {
|
||||
@Suite
|
||||
struct ExtendedNSStringTests {
|
||||
@Test
|
||||
func lineAndCharacterForByteOffset_forContentsContainingMultibyteCharacters() {
|
||||
let contents = "" +
|
||||
"import Foundation\n" + // 18 characters
|
||||
"class Test {\n" + // 13 characters
|
||||
@@ -14,10 +15,10 @@ final class ExtendedNSStringTests: SwiftLintTestCase {
|
||||
"}"
|
||||
// A character placed on 80 offset indicates a white-space before 'do' at 5th line.
|
||||
if let lineAndCharacter = StringView(contents).lineAndCharacter(forCharacterOffset: 80) {
|
||||
XCTAssertEqual(lineAndCharacter.line, 5)
|
||||
XCTAssertEqual(lineAndCharacter.character, 3)
|
||||
#expect(lineAndCharacter.line == 5)
|
||||
#expect(lineAndCharacter.character == 3)
|
||||
} else {
|
||||
XCTFail("NSString.lineAndCharacterForByteOffset should return non-nil tuple.")
|
||||
Issue.record("NSString.lineAndCharacterForByteOffset should return non-nil tuple.")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import TestHelpers
|
||||
import XCTest
|
||||
import Testing
|
||||
|
||||
final class ExtendedStringTests: SwiftLintTestCase {
|
||||
func testCountOccurrences() {
|
||||
XCTAssertEqual("aabbabaaba".countOccurrences(of: "a"), 6)
|
||||
XCTAssertEqual("".countOccurrences(of: "a"), 0)
|
||||
XCTAssertEqual("\n\n".countOccurrences(of: "\n"), 2)
|
||||
@Suite
|
||||
struct ExtendedStringTests {
|
||||
@Test
|
||||
func countOccurrences() {
|
||||
#expect("aabbabaaba".countOccurrences(of: "a") == 6)
|
||||
#expect("".countOccurrences(of: "a") == 0)
|
||||
#expect("\n\n".countOccurrences(of: "\n") == 2)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +1,16 @@
|
||||
import SwiftLintCore
|
||||
import TestHelpers
|
||||
import XCTest
|
||||
import Testing
|
||||
|
||||
final class LineEndingTests: SwiftLintTestCase {
|
||||
func testCarriageReturnDoesNotCauseError() {
|
||||
XCTAssert(
|
||||
@Suite
|
||||
struct LineEndingTests {
|
||||
@Test
|
||||
func carriageReturnDoesNotCauseError() {
|
||||
#expect(
|
||||
violations(
|
||||
Example(
|
||||
"// swiftlint:disable:next blanket_disable_command\r\n" +
|
||||
"// swiftlint:disable all\r\nprint(123)\r\n"
|
||||
"// swiftlint:disable:next blanket_disable_command\r\n"
|
||||
+ "// swiftlint:disable all\r\nprint(123)\r\n"
|
||||
)
|
||||
).isEmpty
|
||||
)
|
||||
|
||||
@@ -1,25 +1,29 @@
|
||||
@testable import SwiftLintCore
|
||||
import SwiftLintCore
|
||||
import TestHelpers
|
||||
import XCTest
|
||||
import Testing
|
||||
|
||||
final class RegexConfigurationTests: SwiftLintTestCase {
|
||||
func testShouldValidateIsTrueByDefault() {
|
||||
@Suite
|
||||
struct RegexConfigurationTests {
|
||||
@Test
|
||||
func shouldValidateIsTrueByDefault() {
|
||||
let config = RegexConfiguration<RuleMock>(identifier: "example")
|
||||
XCTAssertTrue(config.shouldValidate(filePath: "App/file.swift"))
|
||||
#expect(config.shouldValidate(filePath: "App/file.swift"))
|
||||
}
|
||||
|
||||
func testShouldValidateWithSingleExluded() throws {
|
||||
@Test
|
||||
func shouldValidateWithSingleExluded() throws {
|
||||
var config = RegexConfiguration<RuleMock>(identifier: "example")
|
||||
try config.apply(configuration: [
|
||||
"regex": "try!",
|
||||
"excluded": "Tests/.*\\.swift",
|
||||
])
|
||||
|
||||
XCTAssertFalse(config.shouldValidate(filePath: "Tests/file.swift"))
|
||||
XCTAssertTrue(config.shouldValidate(filePath: "App/file.swift"))
|
||||
#expect(!config.shouldValidate(filePath: "Tests/file.swift"))
|
||||
#expect(config.shouldValidate(filePath: "App/file.swift"))
|
||||
}
|
||||
|
||||
func testShouldValidateWithArrayExluded() throws {
|
||||
@Test
|
||||
func shouldValidateWithArrayExluded() throws {
|
||||
var config = RegexConfiguration<RuleMock>(identifier: "example")
|
||||
try config.apply(configuration: [
|
||||
"regex": "try!",
|
||||
@@ -29,24 +33,26 @@ final class RegexConfigurationTests: SwiftLintTestCase {
|
||||
] as Any,
|
||||
])
|
||||
|
||||
XCTAssertFalse(config.shouldValidate(filePath: "Tests/file.swift"))
|
||||
XCTAssertFalse(config.shouldValidate(filePath: "MyFramework/Tests/file.swift"))
|
||||
XCTAssertTrue(config.shouldValidate(filePath: "App/file.swift"))
|
||||
#expect(!config.shouldValidate(filePath: "Tests/file.swift"))
|
||||
#expect(!config.shouldValidate(filePath: "MyFramework/Tests/file.swift"))
|
||||
#expect(config.shouldValidate(filePath: "App/file.swift"))
|
||||
}
|
||||
|
||||
func testShouldValidateWithSingleIncluded() throws {
|
||||
@Test
|
||||
func shouldValidateWithSingleIncluded() throws {
|
||||
var config = RegexConfiguration<RuleMock>(identifier: "example")
|
||||
try config.apply(configuration: [
|
||||
"regex": "try!",
|
||||
"included": "App/.*\\.swift",
|
||||
])
|
||||
|
||||
XCTAssertFalse(config.shouldValidate(filePath: "Tests/file.swift"))
|
||||
XCTAssertFalse(config.shouldValidate(filePath: "MyFramework/Tests/file.swift"))
|
||||
XCTAssertTrue(config.shouldValidate(filePath: "App/file.swift"))
|
||||
#expect(!config.shouldValidate(filePath: "Tests/file.swift"))
|
||||
#expect(!config.shouldValidate(filePath: "MyFramework/Tests/file.swift"))
|
||||
#expect(config.shouldValidate(filePath: "App/file.swift"))
|
||||
}
|
||||
|
||||
func testShouldValidateWithArrayIncluded() throws {
|
||||
@Test
|
||||
func shouldValidateWithArrayIncluded() throws {
|
||||
var config = RegexConfiguration<RuleMock>(identifier: "example")
|
||||
try config.apply(configuration: [
|
||||
"regex": "try!",
|
||||
@@ -56,12 +62,13 @@ final class RegexConfigurationTests: SwiftLintTestCase {
|
||||
] as Any,
|
||||
])
|
||||
|
||||
XCTAssertFalse(config.shouldValidate(filePath: "Tests/file.swift"))
|
||||
XCTAssertTrue(config.shouldValidate(filePath: "App/file.swift"))
|
||||
XCTAssertTrue(config.shouldValidate(filePath: "MyFramework/file.swift"))
|
||||
#expect(!config.shouldValidate(filePath: "Tests/file.swift"))
|
||||
#expect(config.shouldValidate(filePath: "App/file.swift"))
|
||||
#expect(config.shouldValidate(filePath: "MyFramework/file.swift"))
|
||||
}
|
||||
|
||||
func testShouldValidateWithIncludedAndExcluded() throws {
|
||||
@Test
|
||||
func shouldValidateWithIncludedAndExcluded() throws {
|
||||
var config = RegexConfiguration<RuleMock>(identifier: "example")
|
||||
try config.apply(configuration: [
|
||||
"regex": "try!",
|
||||
@@ -75,11 +82,11 @@ final class RegexConfigurationTests: SwiftLintTestCase {
|
||||
] as Any,
|
||||
])
|
||||
|
||||
XCTAssertTrue(config.shouldValidate(filePath: "App/file.swift"))
|
||||
XCTAssertTrue(config.shouldValidate(filePath: "MyFramework/file.swift"))
|
||||
#expect(config.shouldValidate(filePath: "App/file.swift"))
|
||||
#expect(config.shouldValidate(filePath: "MyFramework/file.swift"))
|
||||
|
||||
XCTAssertFalse(config.shouldValidate(filePath: "App/Fixtures/file.swift"))
|
||||
XCTAssertFalse(config.shouldValidate(filePath: "Tests/file.swift"))
|
||||
XCTAssertFalse(config.shouldValidate(filePath: "MyFramework/Tests/file.swift"))
|
||||
#expect(!config.shouldValidate(filePath: "App/Fixtures/file.swift"))
|
||||
#expect(!config.shouldValidate(filePath: "Tests/file.swift"))
|
||||
#expect(!config.shouldValidate(filePath: "MyFramework/Tests/file.swift"))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,79 +1,89 @@
|
||||
import SwiftLintCore
|
||||
import TestHelpers
|
||||
import XCTest
|
||||
import Testing
|
||||
|
||||
final class RegionTests: SwiftLintTestCase {
|
||||
// MARK: Regions From Files
|
||||
|
||||
func testNoRegionsInEmptyFile() {
|
||||
@Suite
|
||||
struct RegionTests {
|
||||
@Test
|
||||
func noRegionsInEmptyFile() {
|
||||
let file = SwiftLintFile(contents: "")
|
||||
XCTAssertEqual(file.regions(), [])
|
||||
#expect(file.regions().isEmpty)
|
||||
}
|
||||
|
||||
func testNoRegionsInFileWithNoCommands() {
|
||||
@Test
|
||||
func noRegionsInFileWithNoCommands() {
|
||||
let file = SwiftLintFile(contents: String(repeating: "\n", count: 100))
|
||||
XCTAssertEqual(file.regions(), [])
|
||||
#expect(file.regions().isEmpty)
|
||||
}
|
||||
|
||||
func testRegionsFromSingleCommand() {
|
||||
@Test
|
||||
func regionsFromSingleCommand() {
|
||||
// disable
|
||||
do {
|
||||
let file = SwiftLintFile(contents: "// swiftlint:disable rule_id\n")
|
||||
let start = Location(file: nil, line: 1, character: 29)
|
||||
let end = Location(file: nil, line: .max, character: .max)
|
||||
XCTAssertEqual(file.regions(), [Region(start: start, end: end, disabledRuleIdentifiers: ["rule_id"])])
|
||||
#expect(file.regions() == [Region(start: start, end: end, disabledRuleIdentifiers: ["rule_id"])])
|
||||
}
|
||||
// enable
|
||||
do {
|
||||
let file = SwiftLintFile(contents: "// swiftlint:enable rule_id\n")
|
||||
let start = Location(file: nil, line: 1, character: 28)
|
||||
let end = Location(file: nil, line: .max, character: .max)
|
||||
XCTAssertEqual(file.regions(), [Region(start: start, end: end, disabledRuleIdentifiers: [])])
|
||||
#expect(file.regions() == [Region(start: start, end: end, disabledRuleIdentifiers: [])])
|
||||
}
|
||||
}
|
||||
|
||||
func testRegionsFromMatchingPairCommands() {
|
||||
@Test
|
||||
func regionsFromMatchingPairCommands() {
|
||||
// disable/enable
|
||||
do {
|
||||
let file = SwiftLintFile(contents: "// swiftlint:disable rule_id\n// swiftlint:enable rule_id\n")
|
||||
XCTAssertEqual(file.regions(), [
|
||||
Region(start: Location(file: nil, line: 1, character: 29),
|
||||
end: Location(file: nil, line: 2, character: 27),
|
||||
disabledRuleIdentifiers: ["rule_id"]),
|
||||
Region(start: Location(file: nil, line: 2, character: 28),
|
||||
end: Location(file: nil, line: .max, character: .max),
|
||||
disabledRuleIdentifiers: []),
|
||||
#expect(file.regions() == [
|
||||
Region(
|
||||
start: Location(file: nil, line: 1, character: 29),
|
||||
end: Location(file: nil, line: 2, character: 27),
|
||||
disabledRuleIdentifiers: ["rule_id"]),
|
||||
Region(
|
||||
start: Location(file: nil, line: 2, character: 28),
|
||||
end: Location(file: nil, line: .max, character: .max),
|
||||
disabledRuleIdentifiers: []),
|
||||
])
|
||||
}
|
||||
// enable/disable
|
||||
do {
|
||||
let file = SwiftLintFile(contents: "// swiftlint:enable rule_id\n// swiftlint:disable rule_id\n")
|
||||
XCTAssertEqual(file.regions(), [
|
||||
Region(start: Location(file: nil, line: 1, character: 28),
|
||||
end: Location(file: nil, line: 2, character: 28),
|
||||
disabledRuleIdentifiers: []),
|
||||
Region(start: Location(file: nil, line: 2, character: 29),
|
||||
end: Location(file: nil, line: .max, character: .max),
|
||||
disabledRuleIdentifiers: ["rule_id"]),
|
||||
#expect(file.regions() == [
|
||||
Region(
|
||||
start: Location(file: nil, line: 1, character: 28),
|
||||
end: Location(file: nil, line: 2, character: 28),
|
||||
disabledRuleIdentifiers: []),
|
||||
Region(
|
||||
start: Location(file: nil, line: 2, character: 29),
|
||||
end: Location(file: nil, line: .max, character: .max),
|
||||
disabledRuleIdentifiers: ["rule_id"]),
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
func testRegionsFromThreeCommandForSingleLine() {
|
||||
let file = SwiftLintFile(contents: "// swiftlint:disable:next 1\n" +
|
||||
"// swiftlint:disable:this 2\n" +
|
||||
"// swiftlint:disable:previous 3\n")
|
||||
XCTAssertEqual(file.regions(), [
|
||||
Region(start: Location(file: nil, line: 2, character: nil),
|
||||
end: Location(file: nil, line: 2, character: .max - 1),
|
||||
disabledRuleIdentifiers: ["1", "2", "3"]),
|
||||
Region(start: Location(file: nil, line: 2, character: .max),
|
||||
end: Location(file: nil, line: .max, character: .max),
|
||||
disabledRuleIdentifiers: []),
|
||||
@Test
|
||||
func regionsFromThreeCommandForSingleLine() {
|
||||
let file = SwiftLintFile(
|
||||
contents: "// swiftlint:disable:next 1\n" + "// swiftlint:disable:this 2\n"
|
||||
+ "// swiftlint:disable:previous 3\n")
|
||||
#expect(file.regions() == [
|
||||
Region(
|
||||
start: Location(file: nil, line: 2, character: nil),
|
||||
end: Location(file: nil, line: 2, character: .max - 1),
|
||||
disabledRuleIdentifiers: ["1", "2", "3"]),
|
||||
Region(
|
||||
start: Location(file: nil, line: 2, character: .max),
|
||||
end: Location(file: nil, line: .max, character: .max),
|
||||
disabledRuleIdentifiers: []),
|
||||
])
|
||||
}
|
||||
|
||||
func testSeveralRegionsFromSeveralCommands() {
|
||||
@Test
|
||||
func severalRegionsFromSeveralCommands() {
|
||||
let file = SwiftLintFile(contents: """
|
||||
// swiftlint:disable 1
|
||||
// swiftlint:disable 2
|
||||
@@ -83,25 +93,31 @@ final class RegionTests: SwiftLintTestCase {
|
||||
// swiftlint:enable 3
|
||||
"""
|
||||
)
|
||||
XCTAssertEqual(file.regions(), [
|
||||
Region(start: Location(file: nil, line: 1, character: 23),
|
||||
end: Location(file: nil, line: 2, character: 22),
|
||||
disabledRuleIdentifiers: ["1"]),
|
||||
Region(start: Location(file: nil, line: 2, character: 23),
|
||||
end: Location(file: nil, line: 3, character: 22),
|
||||
disabledRuleIdentifiers: ["1", "2"]),
|
||||
Region(start: Location(file: nil, line: 3, character: 23),
|
||||
end: Location(file: nil, line: 4, character: 21),
|
||||
disabledRuleIdentifiers: ["1", "2", "3"]),
|
||||
Region(start: Location(file: nil, line: 4, character: 22),
|
||||
end: Location(file: nil, line: 5, character: 21),
|
||||
disabledRuleIdentifiers: ["2", "3"]),
|
||||
Region(start: Location(file: nil, line: 5, character: 22),
|
||||
end: Location(file: nil, line: 6, character: 21),
|
||||
disabledRuleIdentifiers: ["3"]),
|
||||
Region(start: Location(file: nil, line: 6, character: 22),
|
||||
end: Location(file: nil, line: .max, character: .max),
|
||||
disabledRuleIdentifiers: []),
|
||||
#expect(file.regions() == [
|
||||
Region(
|
||||
start: Location(file: nil, line: 1, character: 23),
|
||||
end: Location(file: nil, line: 2, character: 22),
|
||||
disabledRuleIdentifiers: ["1"]),
|
||||
Region(
|
||||
start: Location(file: nil, line: 2, character: 23),
|
||||
end: Location(file: nil, line: 3, character: 22),
|
||||
disabledRuleIdentifiers: ["1", "2"]),
|
||||
Region(
|
||||
start: Location(file: nil, line: 3, character: 23),
|
||||
end: Location(file: nil, line: 4, character: 21),
|
||||
disabledRuleIdentifiers: ["1", "2", "3"]),
|
||||
Region(
|
||||
start: Location(file: nil, line: 4, character: 22),
|
||||
end: Location(file: nil, line: 5, character: 21),
|
||||
disabledRuleIdentifiers: ["2", "3"]),
|
||||
Region(
|
||||
start: Location(file: nil, line: 5, character: 22),
|
||||
end: Location(file: nil, line: 6, character: 21),
|
||||
disabledRuleIdentifiers: ["3"]),
|
||||
Region(
|
||||
start: Location(file: nil, line: 6, character: 22),
|
||||
end: Location(file: nil, line: .max, character: .max),
|
||||
disabledRuleIdentifiers: []),
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,21 +1,21 @@
|
||||
@testable import SwiftLintCore
|
||||
import TestHelpers
|
||||
import XCTest
|
||||
import Testing
|
||||
|
||||
// swiftlint:disable file_length
|
||||
|
||||
// swiftlint:disable:next type_body_length
|
||||
final class RuleConfigurationDescriptionTests: SwiftLintTestCase {
|
||||
@Suite
|
||||
struct RuleConfigurationDescriptionTests { // swiftlint:disable:this type_body_length
|
||||
@AutoConfigParser
|
||||
private struct TestConfiguration: RuleConfiguration {
|
||||
typealias Parent = RuleMock // swiftlint:disable:this nesting
|
||||
typealias Parent = RuleMock // swiftlint:disable:this nesting
|
||||
|
||||
@ConfigurationElement(key: "flag")
|
||||
var flag = true
|
||||
@ConfigurationElement(key: "string")
|
||||
var string = "value"
|
||||
@ConfigurationElement(key: "symbol")
|
||||
var symbol = try! Symbol(fromAny: "value", context: "rule") // swiftlint:disable:this force_try
|
||||
var symbol = try! Symbol(fromAny: "value", context: "rule") // swiftlint:disable:this force_try
|
||||
@ConfigurationElement(key: "integer")
|
||||
var integer = 2
|
||||
@ConfigurationElement(key: "null")
|
||||
@@ -45,186 +45,190 @@ final class RuleConfigurationDescriptionTests: SwiftLintTestCase {
|
||||
func isEqualTo(_: some RuleConfiguration) -> Bool { false }
|
||||
}
|
||||
|
||||
// swiftlint:disable:next function_body_length
|
||||
func testDescriptionFromConfiguration() throws {
|
||||
@Test
|
||||
func descriptionFromConfiguration() throws { // swiftlint:disable:this function_body_length
|
||||
var configuration = TestConfiguration()
|
||||
try configuration.apply(configuration: Void()) // Configure to set keys.
|
||||
try configuration.apply(configuration: Void()) // Configure to set keys.
|
||||
let description = RuleConfigurationDescription.from(configuration: configuration)
|
||||
|
||||
XCTAssertEqual(description.oneLiner(), """
|
||||
flag: true; \
|
||||
string: "value"; \
|
||||
symbol: value; \
|
||||
integer: 2; \
|
||||
my_double: 2.1; \
|
||||
severity: warning; \
|
||||
list: ["STRING1", "STRING2"]; \
|
||||
set: [1, 2, 3]; \
|
||||
set_of_doubles: [1.0, 2.0, 3.0, 4.7]; \
|
||||
severity: error; \
|
||||
SEVERITY: warning; \
|
||||
warning: 1; \
|
||||
levels: warning: 3, error: 2
|
||||
""")
|
||||
#expect(
|
||||
description.oneLiner() == """
|
||||
flag: true; \
|
||||
string: "value"; \
|
||||
symbol: value; \
|
||||
integer: 2; \
|
||||
my_double: 2.1; \
|
||||
severity: warning; \
|
||||
list: ["STRING1", "STRING2"]; \
|
||||
set: [1, 2, 3]; \
|
||||
set_of_doubles: [1.0, 2.0, 3.0, 4.7]; \
|
||||
severity: error; \
|
||||
SEVERITY: warning; \
|
||||
warning: 1; \
|
||||
levels: warning: 3, error: 2
|
||||
""")
|
||||
|
||||
XCTAssertEqual(description.markdown(), """
|
||||
<table>
|
||||
<thead>
|
||||
<tr><th>Key</th><th>Value</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
flag
|
||||
</td>
|
||||
<td>
|
||||
true
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
string
|
||||
</td>
|
||||
<td>
|
||||
"value"
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
symbol
|
||||
</td>
|
||||
<td>
|
||||
value
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
integer
|
||||
</td>
|
||||
<td>
|
||||
2
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
my_double
|
||||
</td>
|
||||
<td>
|
||||
2.1
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
severity
|
||||
</td>
|
||||
<td>
|
||||
warning
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
list
|
||||
</td>
|
||||
<td>
|
||||
["STRING1", "STRING2"]
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
set
|
||||
</td>
|
||||
<td>
|
||||
[1, 2, 3]
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
set_of_doubles
|
||||
</td>
|
||||
<td>
|
||||
[1.0, 2.0, 3.0, 4.7]
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
severity
|
||||
</td>
|
||||
<td>
|
||||
error
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
SEVERITY
|
||||
</td>
|
||||
<td>
|
||||
warning
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
warning
|
||||
</td>
|
||||
<td>
|
||||
1
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
levels
|
||||
</td>
|
||||
<td>
|
||||
<table>
|
||||
<thead>
|
||||
<tr><th>Key</th><th>Value</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
warning
|
||||
</td>
|
||||
<td>
|
||||
3
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
error
|
||||
</td>
|
||||
<td>
|
||||
2
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
""")
|
||||
#expect(
|
||||
description.markdown() == """
|
||||
<table>
|
||||
<thead>
|
||||
<tr><th>Key</th><th>Value</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
flag
|
||||
</td>
|
||||
<td>
|
||||
true
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
string
|
||||
</td>
|
||||
<td>
|
||||
"value"
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
symbol
|
||||
</td>
|
||||
<td>
|
||||
value
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
integer
|
||||
</td>
|
||||
<td>
|
||||
2
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
my_double
|
||||
</td>
|
||||
<td>
|
||||
2.1
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
severity
|
||||
</td>
|
||||
<td>
|
||||
warning
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
list
|
||||
</td>
|
||||
<td>
|
||||
["STRING1", "STRING2"]
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
set
|
||||
</td>
|
||||
<td>
|
||||
[1, 2, 3]
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
set_of_doubles
|
||||
</td>
|
||||
<td>
|
||||
[1.0, 2.0, 3.0, 4.7]
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
severity
|
||||
</td>
|
||||
<td>
|
||||
error
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
SEVERITY
|
||||
</td>
|
||||
<td>
|
||||
warning
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
warning
|
||||
</td>
|
||||
<td>
|
||||
1
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
levels
|
||||
</td>
|
||||
<td>
|
||||
<table>
|
||||
<thead>
|
||||
<tr><th>Key</th><th>Value</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
warning
|
||||
</td>
|
||||
<td>
|
||||
3
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
error
|
||||
</td>
|
||||
<td>
|
||||
2
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
""")
|
||||
|
||||
XCTAssertEqual(description.yaml(), """
|
||||
flag: true
|
||||
string: "value"
|
||||
symbol: value
|
||||
integer: 2
|
||||
my_double: 2.1
|
||||
severity: warning
|
||||
list: ["STRING1", "STRING2"]
|
||||
set: [1, 2, 3]
|
||||
set_of_doubles: [1.0, 2.0, 3.0, 4.7]
|
||||
severity: error
|
||||
SEVERITY: warning
|
||||
warning: 1
|
||||
levels:
|
||||
warning: 3
|
||||
error: 2
|
||||
""")
|
||||
#expect(
|
||||
description.yaml() == """
|
||||
flag: true
|
||||
string: "value"
|
||||
symbol: value
|
||||
integer: 2
|
||||
my_double: 2.1
|
||||
severity: warning
|
||||
list: ["STRING1", "STRING2"]
|
||||
set: [1, 2, 3]
|
||||
set_of_doubles: [1.0, 2.0, 3.0, 4.7]
|
||||
severity: error
|
||||
SEVERITY: warning
|
||||
warning: 1
|
||||
levels:
|
||||
warning: 3
|
||||
error: 2
|
||||
""")
|
||||
}
|
||||
|
||||
func testPrefersParameterDescription() {
|
||||
@Test
|
||||
func prefersParameterDescription() {
|
||||
struct Config: RuleConfiguration {
|
||||
typealias Parent = RuleMock // swiftlint:disable:this nesting
|
||||
typealias Parent = RuleMock // swiftlint:disable:this nesting
|
||||
|
||||
var parameterDescription: RuleConfigurationDescription? {
|
||||
"visible" => .flag(true)
|
||||
@@ -233,43 +237,45 @@ final class RuleConfigurationDescriptionTests: SwiftLintTestCase {
|
||||
@ConfigurationElement(key: "invisible")
|
||||
var invisible = true
|
||||
|
||||
mutating func apply(configuration _: Any) throws(Issue) { /* conformance for test */ }
|
||||
mutating func apply(configuration _: Any) throws(SwiftLintCore.Issue) { /* conformance for test */ }
|
||||
|
||||
func isEqualTo(_: some RuleConfiguration) -> Bool { false }
|
||||
}
|
||||
|
||||
let description = RuleConfigurationDescription.from(configuration: Config())
|
||||
XCTAssertEqual(description.oneLiner(), "visible: true")
|
||||
XCTAssertEqual(description.markdown(), """
|
||||
<table>
|
||||
<thead>
|
||||
<tr><th>Key</th><th>Value</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
visible
|
||||
</td>
|
||||
<td>
|
||||
true
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
""")
|
||||
XCTAssertEqual(description.yaml(), "visible: true")
|
||||
#expect(description.oneLiner() == "visible: true")
|
||||
#expect(
|
||||
description.markdown() == """
|
||||
<table>
|
||||
<thead>
|
||||
<tr><th>Key</th><th>Value</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
visible
|
||||
</td>
|
||||
<td>
|
||||
true
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
""")
|
||||
#expect(description.yaml() == "visible: true")
|
||||
}
|
||||
|
||||
func testEmptyDescription() {
|
||||
@Test
|
||||
func emptyDescription() {
|
||||
let description = description { RuleConfigurationOption.noOptions }
|
||||
|
||||
XCTAssertTrue(description.oneLiner().isEmpty)
|
||||
XCTAssertTrue(description.markdown().isEmpty)
|
||||
XCTAssertTrue(description.yaml().isEmpty)
|
||||
#expect(description.oneLiner().isEmpty)
|
||||
#expect(description.markdown().isEmpty)
|
||||
#expect(description.yaml().isEmpty)
|
||||
}
|
||||
|
||||
// swiftlint:disable:next function_body_length
|
||||
func testBasicTypes() {
|
||||
@Test
|
||||
func basicTypes() { // swiftlint:disable:this function_body_length
|
||||
let description = description {
|
||||
"flag" => .flag(true)
|
||||
"string" => .string("value")
|
||||
@@ -280,196 +286,205 @@ final class RuleConfigurationDescriptionTests: SwiftLintTestCase {
|
||||
"list" => .list([.symbol("value"), .string("value"), .float(12.8)])
|
||||
}
|
||||
|
||||
XCTAssertEqual(description.markdown(), """
|
||||
<table>
|
||||
<thead>
|
||||
<tr><th>Key</th><th>Value</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
flag
|
||||
</td>
|
||||
<td>
|
||||
true
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
string
|
||||
</td>
|
||||
<td>
|
||||
"value"
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
symbol
|
||||
</td>
|
||||
<td>
|
||||
value
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
integer
|
||||
</td>
|
||||
<td>
|
||||
-12
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
float
|
||||
</td>
|
||||
<td>
|
||||
42.0
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
severity
|
||||
</td>
|
||||
<td>
|
||||
error
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
list
|
||||
</td>
|
||||
<td>
|
||||
[value, "value", 12.8]
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
""")
|
||||
#expect(
|
||||
description.markdown() == """
|
||||
<table>
|
||||
<thead>
|
||||
<tr><th>Key</th><th>Value</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
flag
|
||||
</td>
|
||||
<td>
|
||||
true
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
string
|
||||
</td>
|
||||
<td>
|
||||
"value"
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
symbol
|
||||
</td>
|
||||
<td>
|
||||
value
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
integer
|
||||
</td>
|
||||
<td>
|
||||
-12
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
float
|
||||
</td>
|
||||
<td>
|
||||
42.0
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
severity
|
||||
</td>
|
||||
<td>
|
||||
error
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
list
|
||||
</td>
|
||||
<td>
|
||||
[value, "value", 12.8]
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
""")
|
||||
|
||||
XCTAssertEqual(description.oneLiner(), """
|
||||
flag: true; string: "value"; symbol: value; integer: -12; float: 42.0; \
|
||||
severity: error; list: [value, "value", 12.8]
|
||||
""")
|
||||
#expect(
|
||||
description.oneLiner() == """
|
||||
flag: true; string: "value"; symbol: value; integer: -12; float: 42.0; \
|
||||
severity: error; list: [value, "value", 12.8]
|
||||
""")
|
||||
|
||||
XCTAssertEqual(description.yaml(), """
|
||||
flag: true
|
||||
string: "value"
|
||||
symbol: value
|
||||
integer: -12
|
||||
float: 42.0
|
||||
severity: error
|
||||
list: [value, "value", 12.8]
|
||||
""")
|
||||
#expect(
|
||||
description.yaml() == """
|
||||
flag: true
|
||||
string: "value"
|
||||
symbol: value
|
||||
integer: -12
|
||||
float: 42.0
|
||||
severity: error
|
||||
list: [value, "value", 12.8]
|
||||
""")
|
||||
}
|
||||
|
||||
// swiftlint:disable:next function_body_length
|
||||
func testNestedDescription() {
|
||||
@Test
|
||||
func nestedDescription() { // swiftlint:disable:this function_body_length
|
||||
let description = description {
|
||||
"flag" => .flag(true)
|
||||
"nested 1" => .nest {
|
||||
"integer" => .integer(2)
|
||||
"nested 2" => .nest {
|
||||
"float" => .float(42.1)
|
||||
"nested 1"
|
||||
=> .nest {
|
||||
"integer" => .integer(2)
|
||||
"nested 2"
|
||||
=> .nest {
|
||||
"float" => .float(42.1)
|
||||
}
|
||||
"symbol" => .symbol("value")
|
||||
}
|
||||
"symbol" => .symbol("value")
|
||||
}
|
||||
"string" => .string("value")
|
||||
}
|
||||
|
||||
XCTAssertEqual(description.markdown(), """
|
||||
<table>
|
||||
<thead>
|
||||
<tr><th>Key</th><th>Value</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
flag
|
||||
</td>
|
||||
<td>
|
||||
true
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
nested 1
|
||||
</td>
|
||||
<td>
|
||||
<table>
|
||||
<thead>
|
||||
<tr><th>Key</th><th>Value</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
integer
|
||||
</td>
|
||||
<td>
|
||||
2
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
nested 2
|
||||
</td>
|
||||
<td>
|
||||
<table>
|
||||
<thead>
|
||||
<tr><th>Key</th><th>Value</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
float
|
||||
</td>
|
||||
<td>
|
||||
42.1
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
symbol
|
||||
</td>
|
||||
<td>
|
||||
value
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
string
|
||||
</td>
|
||||
<td>
|
||||
"value"
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
""")
|
||||
#expect(
|
||||
description.markdown() == """
|
||||
<table>
|
||||
<thead>
|
||||
<tr><th>Key</th><th>Value</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
flag
|
||||
</td>
|
||||
<td>
|
||||
true
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
nested 1
|
||||
</td>
|
||||
<td>
|
||||
<table>
|
||||
<thead>
|
||||
<tr><th>Key</th><th>Value</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
integer
|
||||
</td>
|
||||
<td>
|
||||
2
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
nested 2
|
||||
</td>
|
||||
<td>
|
||||
<table>
|
||||
<thead>
|
||||
<tr><th>Key</th><th>Value</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
float
|
||||
</td>
|
||||
<td>
|
||||
42.1
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
symbol
|
||||
</td>
|
||||
<td>
|
||||
value
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
string
|
||||
</td>
|
||||
<td>
|
||||
"value"
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
""")
|
||||
|
||||
XCTAssertEqual(description.oneLiner(), """
|
||||
flag: true; nested 1: integer: 2, nested 2: float: 42.1, symbol: value; string: "value"
|
||||
""")
|
||||
#expect(
|
||||
description.oneLiner() == """
|
||||
flag: true; nested 1: integer: 2, nested 2: float: 42.1, symbol: value; string: "value"
|
||||
""")
|
||||
|
||||
XCTAssertEqual(description.yaml(), """
|
||||
flag: true
|
||||
nested 1:
|
||||
integer: 2
|
||||
nested 2:
|
||||
float: 42.1
|
||||
symbol: value
|
||||
string: "value"
|
||||
""")
|
||||
#expect(
|
||||
description.yaml() == """
|
||||
flag: true
|
||||
nested 1:
|
||||
integer: 2
|
||||
nested 2:
|
||||
float: 42.1
|
||||
symbol: value
|
||||
string: "value"
|
||||
""")
|
||||
}
|
||||
|
||||
func testUpdate() throws {
|
||||
@Test
|
||||
func update() throws {
|
||||
var configuration = TestConfiguration()
|
||||
|
||||
try configuration.apply(configuration: [
|
||||
@@ -487,41 +502,44 @@ final class RuleConfigurationDescriptionTests: SwiftLintTestCase {
|
||||
"levels": ["warning": 6, "error": 7],
|
||||
])
|
||||
|
||||
XCTAssertFalse(configuration.flag)
|
||||
XCTAssertEqual(configuration.string, "new value")
|
||||
XCTAssertEqual(configuration.symbol, try Symbol(fromAny: "new symbol", context: "rule"))
|
||||
XCTAssertEqual(configuration.integer, 5)
|
||||
XCTAssertEqual(configuration.null, 0)
|
||||
XCTAssertEqual(configuration.myDouble, 5.1)
|
||||
XCTAssertEqual(configuration.severity, .error)
|
||||
XCTAssertEqual(configuration.list, ["STRING3", "STRING4"])
|
||||
XCTAssertEqual(configuration.set, [4, 5, 6])
|
||||
XCTAssertEqual(configuration.severityConfig, .error)
|
||||
XCTAssertEqual(configuration.renamedSeverityConfig, .error)
|
||||
XCTAssertEqual(configuration.inlinedSeverityLevels, SeverityLevelsConfiguration(warning: 12))
|
||||
XCTAssertEqual(configuration.nestedSeverityLevels, SeverityLevelsConfiguration(warning: 6, error: 7))
|
||||
#expect(!configuration.flag)
|
||||
#expect(configuration.string == "new value")
|
||||
#expect(configuration.symbol == (try Symbol(fromAny: "new symbol", context: "rule")))
|
||||
#expect(configuration.integer == 5)
|
||||
#expect(configuration.null == 0)
|
||||
#expect(configuration.myDouble == 5.1)
|
||||
#expect(configuration.severity == .error)
|
||||
#expect(configuration.list == ["STRING3", "STRING4"])
|
||||
#expect(configuration.set == [4, 5, 6])
|
||||
#expect(configuration.severityConfig == .error)
|
||||
#expect(configuration.renamedSeverityConfig == .error)
|
||||
#expect(configuration.inlinedSeverityLevels == SeverityLevelsConfiguration(warning: 12))
|
||||
#expect(configuration.nestedSeverityLevels == SeverityLevelsConfiguration(warning: 6, error: 7))
|
||||
}
|
||||
|
||||
func testDeprecationWarning() async throws {
|
||||
@Test
|
||||
func deprecationWarning() async throws {
|
||||
let console = try await Issue.captureConsole {
|
||||
var configuration = TestConfiguration()
|
||||
try configuration.apply(configuration: ["set": [6, 7]])
|
||||
}
|
||||
XCTAssertEqual(
|
||||
console,
|
||||
"warning: Configuration option 'set' in 'my_rule' rule is deprecated. Use the option 'other_opt' instead."
|
||||
#expect(console == """
|
||||
warning: Configuration option 'set' in 'my_rule' rule is deprecated. Use the option 'other_opt' instead.
|
||||
"""
|
||||
)
|
||||
}
|
||||
|
||||
func testNoDeprecationWarningIfNoDeprecatedPropertySet() async throws {
|
||||
@Test
|
||||
func noDeprecationWarningIfNoDeprecatedPropertySet() async throws {
|
||||
let console = try await Issue.captureConsole {
|
||||
var configuration = TestConfiguration()
|
||||
try configuration.apply(configuration: ["flag": false])
|
||||
}
|
||||
XCTAssertTrue(console.isEmpty)
|
||||
#expect(console.isEmpty)
|
||||
}
|
||||
|
||||
func testInvalidKeys() async throws {
|
||||
@Test
|
||||
func invalidKeys() async throws {
|
||||
let console = try await Issue.captureConsole {
|
||||
var configuration = TestConfiguration()
|
||||
try configuration.apply(configuration: [
|
||||
@@ -531,9 +549,9 @@ final class RuleConfigurationDescriptionTests: SwiftLintTestCase {
|
||||
"unsupported": true,
|
||||
])
|
||||
}
|
||||
XCTAssertEqual(
|
||||
console,
|
||||
"warning: Configuration for 'RuleMock' rule contains the invalid key(s) 'unknown', 'unsupported'."
|
||||
#expect(
|
||||
console
|
||||
== "warning: Configuration for 'RuleMock' rule contains the invalid key(s) 'unknown', 'unsupported'."
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,15 +1,37 @@
|
||||
import SwiftLintCore
|
||||
import TestHelpers
|
||||
import XCTest
|
||||
import Testing
|
||||
|
||||
final class RuleTests: SwiftLintTestCase {
|
||||
struct RuleWithLevelsMock: Rule {
|
||||
var configuration = SeverityLevelsConfiguration<Self>(warning: 2, error: 3)
|
||||
|
||||
static let description = RuleDescription(
|
||||
identifier: "severity_level_mock",
|
||||
name: "",
|
||||
description: "",
|
||||
kind: .style,
|
||||
deprecatedAliases: ["mock"]
|
||||
)
|
||||
|
||||
init() { /* conformance for test */ }
|
||||
init(configuration: Any) throws {
|
||||
self.init()
|
||||
try self.configuration.apply(configuration: configuration)
|
||||
}
|
||||
|
||||
func validate(file _: SwiftLintFile) -> [StyleViolation] { [] }
|
||||
}
|
||||
|
||||
@Suite
|
||||
struct RuleTests {
|
||||
fileprivate struct RuleMock1: Rule {
|
||||
var configuration = SeverityConfiguration<Self>(.warning)
|
||||
var configurationDescription: some Documentable { RuleConfigurationOption.noOptions }
|
||||
static let description = RuleDescription(identifier: "RuleMock1", name: "",
|
||||
description: "", kind: .style)
|
||||
static let description = RuleDescription(
|
||||
identifier: "RuleMock1", name: "",
|
||||
description: "", kind: .style
|
||||
)
|
||||
|
||||
init() { /* conformance for test */ }
|
||||
init() { /* conformance for test */ }
|
||||
init(configuration _: Any) throws { self.init() }
|
||||
|
||||
func validate(file _: SwiftLintFile) -> [StyleViolation] {
|
||||
@@ -20,10 +42,12 @@ final class RuleTests: SwiftLintTestCase {
|
||||
fileprivate struct RuleMock2: Rule {
|
||||
var configuration = SeverityConfiguration<Self>(.warning)
|
||||
var configurationDescription: some Documentable { RuleConfigurationOption.noOptions }
|
||||
static let description = RuleDescription(identifier: "RuleMock2", name: "",
|
||||
description: "", kind: .style)
|
||||
static let description = RuleDescription(
|
||||
identifier: "RuleMock2", name: "",
|
||||
description: "", kind: .style
|
||||
)
|
||||
|
||||
init() { /* conformance for test */ }
|
||||
init() { /* conformance for test */ }
|
||||
init(configuration _: Any) throws { self.init() }
|
||||
|
||||
func validate(file _: SwiftLintFile) -> [StyleViolation] {
|
||||
@@ -34,11 +58,13 @@ final class RuleTests: SwiftLintTestCase {
|
||||
fileprivate struct RuleWithLevelsMock2: Rule {
|
||||
var configuration = SeverityLevelsConfiguration<Self>(warning: 2, error: 3)
|
||||
|
||||
static let description = RuleDescription(identifier: "violation_level_mock2",
|
||||
name: "",
|
||||
description: "", kind: .style)
|
||||
static let description = RuleDescription(
|
||||
identifier: "violation_level_mock2",
|
||||
name: "",
|
||||
description: "", kind: .style
|
||||
)
|
||||
|
||||
init() { /* conformance for test */ }
|
||||
init() { /* conformance for test */ }
|
||||
init(configuration: Any) throws {
|
||||
self.init()
|
||||
try self.configuration.apply(configuration: configuration)
|
||||
@@ -47,79 +73,89 @@ final class RuleTests: SwiftLintTestCase {
|
||||
func validate(file _: SwiftLintFile) -> [StyleViolation] { [] }
|
||||
}
|
||||
|
||||
func testRuleIsEqualTo() {
|
||||
XCTAssertTrue(RuleMock1().isEqualTo(RuleMock1()))
|
||||
@Test
|
||||
func ruleIsEqualTo() {
|
||||
#expect(RuleMock1().isEqualTo(RuleMock1()))
|
||||
}
|
||||
|
||||
func testRuleIsNotEqualTo() {
|
||||
XCTAssertFalse(RuleMock1().isEqualTo(RuleMock2()))
|
||||
@Test
|
||||
func ruleIsNotEqualTo() {
|
||||
#expect(!RuleMock1().isEqualTo(RuleMock2()))
|
||||
}
|
||||
|
||||
func testRuleArraysWithDifferentCountsNotEqual() {
|
||||
// swiftlint:disable:next xct_specific_matcher
|
||||
XCTAssertFalse([RuleMock1(), RuleMock2()] == [RuleMock1()])
|
||||
@Test
|
||||
func ruleArraysWithDifferentCountsNotEqual() {
|
||||
#expect(!([RuleMock1(), RuleMock2()] == [RuleMock1()]))
|
||||
}
|
||||
|
||||
func testSeverityLevelRuleInitsWithConfigDictionary() {
|
||||
@Test
|
||||
func severityLevelRuleInitsWithConfigDictionary() {
|
||||
let config = ["warning": 17, "error": 7]
|
||||
let rule = try? RuleWithLevelsMock(configuration: config)
|
||||
var comp = RuleWithLevelsMock()
|
||||
comp.configuration.warning = 17
|
||||
comp.configuration.error = 7
|
||||
XCTAssertEqual(rule?.isEqualTo(comp), true)
|
||||
#expect(rule?.isEqualTo(comp) == true)
|
||||
}
|
||||
|
||||
func testSeverityLevelRuleInitsWithWarningOnlyConfigDictionary() {
|
||||
@Test
|
||||
func severityLevelRuleInitsWithWarningOnlyConfigDictionary() {
|
||||
let config = ["warning": 17]
|
||||
let rule = try? RuleWithLevelsMock(configuration: config)
|
||||
var comp = RuleWithLevelsMock()
|
||||
comp.configuration.warning = 17
|
||||
comp.configuration.error = nil
|
||||
XCTAssertEqual(rule?.isEqualTo(comp), true)
|
||||
#expect(rule?.isEqualTo(comp) == true)
|
||||
}
|
||||
|
||||
func testSeverityLevelRuleInitsWithErrorOnlyConfigDictionary() {
|
||||
@Test
|
||||
func severityLevelRuleInitsWithErrorOnlyConfigDictionary() {
|
||||
let config = ["error": 17]
|
||||
let rule = try? RuleWithLevelsMock(configuration: config)
|
||||
var comp = RuleWithLevelsMock()
|
||||
comp.configuration.error = 17
|
||||
XCTAssertEqual(rule?.isEqualTo(comp), true)
|
||||
#expect(rule?.isEqualTo(comp) == true)
|
||||
}
|
||||
|
||||
func testSeverityLevelRuleInitsWithConfigArray() {
|
||||
@Test
|
||||
func severityLevelRuleInitsWithConfigArray() {
|
||||
let config = [17, 7] as Any
|
||||
let rule = try? RuleWithLevelsMock(configuration: config)
|
||||
var comp = RuleWithLevelsMock()
|
||||
comp.configuration.warning = 17
|
||||
comp.configuration.error = 7
|
||||
XCTAssertEqual(rule?.isEqualTo(comp), true)
|
||||
#expect(rule?.isEqualTo(comp) == true)
|
||||
}
|
||||
|
||||
func testSeverityLevelRuleInitsWithSingleValueConfigArray() {
|
||||
@Test
|
||||
func severityLevelRuleInitsWithSingleValueConfigArray() {
|
||||
let config = [17] as Any
|
||||
let rule = try? RuleWithLevelsMock(configuration: config)
|
||||
var comp = RuleWithLevelsMock()
|
||||
comp.configuration.warning = 17
|
||||
comp.configuration.error = nil
|
||||
XCTAssertEqual(rule?.isEqualTo(comp), true)
|
||||
#expect(rule?.isEqualTo(comp) == true)
|
||||
}
|
||||
|
||||
func testSeverityLevelRuleInitsWithLiteral() {
|
||||
@Test
|
||||
func severityLevelRuleInitsWithLiteral() {
|
||||
let config = 17 as Any
|
||||
let rule = try? RuleWithLevelsMock(configuration: config)
|
||||
var comp = RuleWithLevelsMock()
|
||||
comp.configuration.warning = 17
|
||||
comp.configuration.error = nil
|
||||
XCTAssertEqual(rule?.isEqualTo(comp), true)
|
||||
#expect(rule?.isEqualTo(comp) == true)
|
||||
}
|
||||
|
||||
func testSeverityLevelRuleNotEqual() {
|
||||
@Test
|
||||
func severityLevelRuleNotEqual() {
|
||||
let config = 17 as Any
|
||||
let rule = try? RuleWithLevelsMock(configuration: config)
|
||||
XCTAssertEqual(rule?.isEqualTo(RuleWithLevelsMock()), false)
|
||||
#expect(rule?.isEqualTo(RuleWithLevelsMock()) == false)
|
||||
}
|
||||
|
||||
func testDifferentSeverityLevelRulesNotEqual() {
|
||||
XCTAssertFalse(RuleWithLevelsMock().isEqualTo(RuleWithLevelsMock2()))
|
||||
@Test
|
||||
func differentSeverityLevelRulesNotEqual() {
|
||||
#expect(!RuleWithLevelsMock().isEqualTo(RuleWithLevelsMock2()))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
@testable import SwiftLintCore
|
||||
import TestHelpers
|
||||
import XCTest
|
||||
import Testing
|
||||
|
||||
struct MockSeverityLevelsRule: Rule {
|
||||
static let identifier = "test_severity_levels"
|
||||
@@ -18,149 +18,166 @@ struct MockSeverityLevelsRule: Rule {
|
||||
}
|
||||
}
|
||||
|
||||
final class SeverityLevelsConfigurationTests: SwiftLintTestCase {
|
||||
func testInitializationWithWarningOnly() {
|
||||
@Suite
|
||||
struct SeverityLevelsConfigurationTests {
|
||||
@Test
|
||||
func initializationWithWarningOnly() {
|
||||
let config = SeverityLevelsConfiguration<MockSeverityLevelsRule>(warning: 10)
|
||||
XCTAssertEqual(config.warning, 10)
|
||||
XCTAssertNil(config.error)
|
||||
#expect(config.warning == 10)
|
||||
#expect(config.error == nil)
|
||||
|
||||
let params = config.params
|
||||
XCTAssertEqual(params.count, 1)
|
||||
XCTAssertEqual(params[0].severity, .warning)
|
||||
XCTAssertEqual(params[0].value, 10)
|
||||
#expect(params.count == 1)
|
||||
#expect(params[0].severity == .warning)
|
||||
#expect(params[0].value == 10)
|
||||
}
|
||||
|
||||
func testInitializationWithWarningAndError() {
|
||||
@Test
|
||||
func initializationWithWarningAndError() {
|
||||
let config = SeverityLevelsConfiguration<MockSeverityLevelsRule>(warning: 10, error: 20)
|
||||
XCTAssertEqual(config.warning, 10)
|
||||
XCTAssertEqual(config.error, 20)
|
||||
#expect(config.warning == 10)
|
||||
#expect(config.error == 20)
|
||||
|
||||
let params = config.params
|
||||
XCTAssertEqual(params.count, 2)
|
||||
XCTAssertEqual(params[0].severity, .error)
|
||||
XCTAssertEqual(params[0].value, 20)
|
||||
XCTAssertEqual(params[1].severity, .warning)
|
||||
XCTAssertEqual(params[1].value, 10)
|
||||
#expect(params.count == 2)
|
||||
#expect(params[0].severity == .error)
|
||||
#expect(params[0].value == 20)
|
||||
#expect(params[1].severity == .warning)
|
||||
#expect(params[1].value == 10)
|
||||
}
|
||||
|
||||
func testApplyConfigurationWithSingleElementArray() throws {
|
||||
@Test
|
||||
func applyConfigurationWithSingleElementArray() throws {
|
||||
var config = SeverityLevelsConfiguration<MockSeverityLevelsRule>(warning: 0, error: 0)
|
||||
|
||||
try config.apply(configuration: [15])
|
||||
|
||||
XCTAssertEqual(config.warning, 15)
|
||||
XCTAssertNil(config.error)
|
||||
#expect(config.warning == 15)
|
||||
#expect(config.error == nil)
|
||||
}
|
||||
|
||||
func testApplyConfigurationWithTwoElementArray() throws {
|
||||
@Test
|
||||
func applyConfigurationWithTwoElementArray() throws {
|
||||
var config = SeverityLevelsConfiguration<MockSeverityLevelsRule>(warning: 0, error: 0)
|
||||
|
||||
try config.apply(configuration: [10, 25])
|
||||
|
||||
XCTAssertEqual(config.warning, 10)
|
||||
XCTAssertEqual(config.error, 25)
|
||||
#expect(config.warning == 10)
|
||||
#expect(config.error == 25)
|
||||
}
|
||||
|
||||
func testApplyConfigurationWithMultipleElementArray() throws {
|
||||
@Test
|
||||
func applyConfigurationWithMultipleElementArray() throws {
|
||||
var config = SeverityLevelsConfiguration<MockSeverityLevelsRule>(warning: 0, error: 0)
|
||||
|
||||
try config.apply(configuration: [10, 25, 50])
|
||||
|
||||
XCTAssertEqual(config.warning, 10)
|
||||
XCTAssertEqual(config.error, 25) // Only first two elements are used
|
||||
#expect(config.warning == 10)
|
||||
#expect(config.error == 25) // Only first two elements are used // Only first two elements are used
|
||||
}
|
||||
|
||||
func testApplyConfigurationWithEmptyArray() {
|
||||
@Test
|
||||
func applyConfigurationWithEmptyArray() {
|
||||
var config = SeverityLevelsConfiguration<MockSeverityLevelsRule>(warning: 12, error: nil)
|
||||
|
||||
checkError(Issue.nothingApplied(ruleID: MockSeverityLevelsRule.identifier)) {
|
||||
#expect(throws: Issue.nothingApplied(ruleID: MockSeverityLevelsRule.identifier)) {
|
||||
try config.apply(configuration: [] as [Int])
|
||||
}
|
||||
}
|
||||
|
||||
func testApplyConfigurationWithInvalidArrayType() {
|
||||
@Test
|
||||
func applyConfigurationWithInvalidArrayType() {
|
||||
var config = SeverityLevelsConfiguration<MockSeverityLevelsRule>(warning: 12, error: nil)
|
||||
|
||||
checkError(Issue.nothingApplied(ruleID: MockSeverityLevelsRule.identifier)) {
|
||||
#expect(throws: Issue.nothingApplied(ruleID: MockSeverityLevelsRule.identifier)) {
|
||||
try config.apply(configuration: ["invalid"])
|
||||
}
|
||||
}
|
||||
|
||||
func testApplyConfigurationWithWarningOnlyDictionary() throws {
|
||||
@Test
|
||||
func applyConfigurationWithWarningOnlyDictionary() throws {
|
||||
var config = SeverityLevelsConfiguration<MockSeverityLevelsRule>(warning: 0, error: 0)
|
||||
|
||||
try config.apply(configuration: ["warning": 15])
|
||||
|
||||
XCTAssertEqual(config.warning, 15)
|
||||
XCTAssertNil(config.error)
|
||||
#expect(config.warning == 15)
|
||||
#expect(config.error == nil)
|
||||
}
|
||||
|
||||
func testApplyConfigurationWithWarningAndErrorDictionary() throws {
|
||||
@Test
|
||||
func applyConfigurationWithWarningAndErrorDictionary() throws {
|
||||
var config = SeverityLevelsConfiguration<MockSeverityLevelsRule>(warning: 0, error: 0)
|
||||
|
||||
try config.apply(configuration: ["warning": 10, "error": 25])
|
||||
|
||||
XCTAssertEqual(config.warning, 10)
|
||||
XCTAssertEqual(config.error, 25)
|
||||
#expect(config.warning == 10)
|
||||
#expect(config.error == 25)
|
||||
}
|
||||
|
||||
func testApplyConfigurationWithErrorOnlyDictionary() throws {
|
||||
@Test
|
||||
func applyConfigurationWithErrorOnlyDictionary() throws {
|
||||
var config = SeverityLevelsConfiguration<MockSeverityLevelsRule>(warning: 12, error: nil)
|
||||
|
||||
try config.apply(configuration: ["error": 25])
|
||||
|
||||
XCTAssertEqual(config.warning, 12) // Should remain unchanged
|
||||
XCTAssertEqual(config.error, 25)
|
||||
#expect(config.warning == 12) // Should remain unchanged // Should remain unchanged
|
||||
#expect(config.error == 25)
|
||||
}
|
||||
|
||||
func testApplyConfigurationWithNilErrorDictionary() throws {
|
||||
@Test
|
||||
func applyConfigurationWithNilErrorDictionary() throws {
|
||||
var config = SeverityLevelsConfiguration<MockSeverityLevelsRule>(warning: 10, error: 20)
|
||||
|
||||
try config.apply(configuration: ["error": nil as Int?])
|
||||
|
||||
XCTAssertEqual(config.warning, 10)
|
||||
XCTAssertNil(config.error)
|
||||
#expect(config.warning == 10)
|
||||
#expect(config.error == nil)
|
||||
}
|
||||
|
||||
func testApplyConfigurationWithWarningSetToNilError() throws {
|
||||
@Test
|
||||
func applyConfigurationWithWarningSetToNilError() throws {
|
||||
var config = SeverityLevelsConfiguration<MockSeverityLevelsRule>(warning: 10, error: 20)
|
||||
|
||||
try config.apply(configuration: ["warning": 15])
|
||||
|
||||
XCTAssertEqual(config.warning, 15)
|
||||
XCTAssertNil(config.error) // Should be set to nil when warning is specified without error
|
||||
#expect(config.warning == 15)
|
||||
#expect(config.error == nil) // Should be set to nil when warning is specified without error
|
||||
}
|
||||
|
||||
func testApplyConfigurationWithInvalidWarningType() {
|
||||
@Test
|
||||
func applyConfigurationWithInvalidWarningType() {
|
||||
var config = SeverityLevelsConfiguration<MockSeverityLevelsRule>(warning: 12, error: nil)
|
||||
|
||||
checkError(Issue.invalidConfiguration(ruleID: MockSeverityLevelsRule.identifier)) {
|
||||
#expect(throws: Issue.invalidConfiguration(ruleID: MockSeverityLevelsRule.identifier)) {
|
||||
try config.apply(configuration: ["warning": "invalid"])
|
||||
}
|
||||
}
|
||||
|
||||
func testApplyConfigurationWithInvalidErrorType() {
|
||||
@Test
|
||||
func applyConfigurationWithInvalidErrorType() {
|
||||
var config = SeverityLevelsConfiguration<MockSeverityLevelsRule>(warning: 12, error: nil)
|
||||
|
||||
checkError(Issue.invalidConfiguration(ruleID: MockSeverityLevelsRule.identifier)) {
|
||||
#expect(throws: Issue.invalidConfiguration(ruleID: MockSeverityLevelsRule.identifier)) {
|
||||
try config.apply(configuration: ["error": "invalid"])
|
||||
}
|
||||
}
|
||||
|
||||
func testApplyConfigurationWithInvalidConfigurationType() {
|
||||
@Test
|
||||
func applyConfigurationWithInvalidConfigurationType() {
|
||||
var config = SeverityLevelsConfiguration<MockSeverityLevelsRule>(warning: 12, error: nil)
|
||||
|
||||
checkError(Issue.nothingApplied(ruleID: MockSeverityLevelsRule.identifier)) {
|
||||
#expect(throws: Issue.nothingApplied(ruleID: MockSeverityLevelsRule.identifier)) {
|
||||
try config.apply(configuration: "invalid")
|
||||
}
|
||||
}
|
||||
|
||||
func testApplyConfigurationWithEmptyDictionary() throws {
|
||||
@Test
|
||||
func applyConfigurationWithEmptyDictionary() throws {
|
||||
var config = SeverityLevelsConfiguration<MockSeverityLevelsRule>(warning: 12, error: 15)
|
||||
|
||||
try config.apply(configuration: [:] as [String: Any])
|
||||
|
||||
XCTAssertEqual(config.warning, 12)
|
||||
XCTAssertEqual(config.error, 15) // Should remain unchanged when nothing is applied
|
||||
#expect(config.warning == 12)
|
||||
#expect(config.error == 15) // Should remain unchanged when nothing is applied
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,48 +1,52 @@
|
||||
import TestHelpers
|
||||
import XCTest
|
||||
import Testing
|
||||
|
||||
final class StringExtensionTests: SwiftLintTestCase {
|
||||
func testRelativePathExpression() {
|
||||
XCTAssertEqual("Folder/Test", "Root/Folder/Test".path(relativeTo: "Root"))
|
||||
XCTAssertEqual("Test", "Root/Folder/Test".path(relativeTo: "Root/Folder"))
|
||||
XCTAssertEqual("", "Root/Folder/Test".path(relativeTo: "Root/Folder/Test"))
|
||||
XCTAssertEqual("../Test", "Root/Folder/Test".path(relativeTo: "Root/Folder/SubFolder"))
|
||||
XCTAssertEqual("../..", "Root".path(relativeTo: "Root/Folder/SubFolder"))
|
||||
XCTAssertEqual("../../OtherFolder/Test", "Root/OtherFolder/Test".path(relativeTo: "Root/Folder/SubFolder"))
|
||||
XCTAssertEqual("../MyFolder123", "Folder/MyFolder123".path(relativeTo: "Folder/MyFolder"))
|
||||
XCTAssertEqual("../MyFolder123", "Folder/MyFolder123".path(relativeTo: "Folder/MyFolder/"))
|
||||
XCTAssertEqual("Test", "Root////Folder///Test/".path(relativeTo: "Root//Folder////"))
|
||||
XCTAssertEqual("Root/Folder/Test", "Root/Folder/Test/".path(relativeTo: ""))
|
||||
@Suite
|
||||
struct StringExtensionTests {
|
||||
@Test
|
||||
func relativePathExpression() {
|
||||
#expect("Folder/Test" == "Root/Folder/Test".path(relativeTo: "Root"))
|
||||
#expect("Test" == "Root/Folder/Test".path(relativeTo: "Root/Folder"))
|
||||
#expect("" == "Root/Folder/Test".path(relativeTo: "Root/Folder/Test"))
|
||||
#expect("../Test" == "Root/Folder/Test".path(relativeTo: "Root/Folder/SubFolder"))
|
||||
#expect("../.." == "Root".path(relativeTo: "Root/Folder/SubFolder"))
|
||||
#expect("../../OtherFolder/Test" == "Root/OtherFolder/Test".path(relativeTo: "Root/Folder/SubFolder"))
|
||||
#expect("../MyFolder123" == "Folder/MyFolder123".path(relativeTo: "Folder/MyFolder"))
|
||||
#expect("../MyFolder123" == "Folder/MyFolder123".path(relativeTo: "Folder/MyFolder/"))
|
||||
#expect("Test" == "Root////Folder///Test/".path(relativeTo: "Root//Folder////"))
|
||||
#expect("Root/Folder/Test" == "Root/Folder/Test/".path(relativeTo: ""))
|
||||
}
|
||||
|
||||
func testIndent() {
|
||||
XCTAssertEqual("string".indent(by: 3), " string")
|
||||
XCTAssertEqual(" string".indent(by: 2), " string")
|
||||
XCTAssertEqual("""
|
||||
@Test
|
||||
func indent() {
|
||||
#expect("string".indent(by: 3) == " string")
|
||||
#expect(" string".indent(by: 2) == " string")
|
||||
#expect(
|
||||
"""
|
||||
1
|
||||
2
|
||||
3
|
||||
""".indent(by: 2), """
|
||||
1
|
||||
2
|
||||
3
|
||||
"""
|
||||
""".indent(by: 2) == """
|
||||
1
|
||||
2
|
||||
3
|
||||
"""
|
||||
)
|
||||
}
|
||||
|
||||
func testCharacterPosition() {
|
||||
XCTAssertNil("string".characterPosition(of: -1))
|
||||
XCTAssertEqual("string".characterPosition(of: 0), 0)
|
||||
XCTAssertEqual("string".characterPosition(of: 1), 1)
|
||||
XCTAssertNil("string".characterPosition(of: 6))
|
||||
XCTAssertNil("string".characterPosition(of: 7))
|
||||
@Test
|
||||
func characterPosition() {
|
||||
#expect("string".characterPosition(of: -1) == nil)
|
||||
#expect("string".characterPosition(of: 0) == 0)
|
||||
#expect("string".characterPosition(of: 1) == 1)
|
||||
#expect("string".characterPosition(of: 6) == nil)
|
||||
#expect("string".characterPosition(of: 7) == nil)
|
||||
|
||||
XCTAssertEqual("s🤵🏼♀️s".characterPosition(of: 0), 0)
|
||||
XCTAssertEqual("s🤵🏼♀️s".characterPosition(of: 1), 1)
|
||||
#expect("s🤵🏼♀️s".characterPosition(of: 0) == 0)
|
||||
#expect("s🤵🏼♀️s".characterPosition(of: 1) == 1)
|
||||
for bytes in 2...17 {
|
||||
XCTAssertNil("s🤵🏼♀️s".characterPosition(of: bytes))
|
||||
#expect("s🤵🏼♀️s".characterPosition(of: bytes) == nil)
|
||||
}
|
||||
XCTAssertEqual("s🤵🏼♀️s".characterPosition(of: 18), 2)
|
||||
XCTAssertNil("s🤵🏼♀️s".characterPosition(of: 19))
|
||||
#expect("s🤵🏼♀️s".characterPosition(of: 18) == 2)
|
||||
#expect("s🤵🏼♀️s".characterPosition(of: 19) == nil)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,69 +1,79 @@
|
||||
@testable import SwiftLintCore
|
||||
import TestHelpers
|
||||
import XCTest
|
||||
import Foundation
|
||||
import Testing
|
||||
|
||||
final class SwiftLintFileTests: SwiftLintTestCase {
|
||||
@testable import SwiftLintCore
|
||||
|
||||
@Suite
|
||||
final class SwiftLintFileTests {
|
||||
private let tempFile = FileManager.default.temporaryDirectory.appendingPathComponent(UUID().uuidString)
|
||||
|
||||
override func setUp() async throws {
|
||||
try await super.setUp()
|
||||
init() throws {
|
||||
try Data("let i = 2".utf8).write(to: tempFile)
|
||||
}
|
||||
|
||||
override func tearDown() async throws {
|
||||
try FileManager.default.removeItem(at: tempFile)
|
||||
try await super.tearDown()
|
||||
deinit {
|
||||
do {
|
||||
try FileManager.default.removeItem(at: tempFile)
|
||||
} catch {
|
||||
Issue.record("Failed to remove temporary file: \(error)")
|
||||
}
|
||||
}
|
||||
|
||||
func testFileFromStringUpdate() {
|
||||
@Test
|
||||
func fileFromStringUpdate() {
|
||||
let file = SwiftLintFile(contents: "let i = 1")
|
||||
|
||||
XCTAssertTrue(file.isVirtual)
|
||||
XCTAssertNil(file.path)
|
||||
XCTAssertEqual(file.contents, "let i = 1")
|
||||
#expect(file.isVirtual)
|
||||
#expect(file.path == nil)
|
||||
#expect(file.contents == "let i = 1")
|
||||
|
||||
file.write("let j = 2")
|
||||
|
||||
XCTAssertEqual(file.contents, "let j = 2")
|
||||
#expect(file.contents == "let j = 2")
|
||||
|
||||
file.append("2")
|
||||
|
||||
XCTAssertEqual(file.contents, "let j = 22")
|
||||
#expect(file.contents == "let j = 22")
|
||||
}
|
||||
|
||||
func testFileUpdate() throws {
|
||||
@Test
|
||||
func fileUpdate() throws {
|
||||
let file = SwiftLintFile(path: tempFile.path)!
|
||||
|
||||
XCTAssertFalse(file.isVirtual)
|
||||
XCTAssertNotNil(file.path)
|
||||
XCTAssertEqual(file.contents, "let i = 2")
|
||||
#expect(!file.isVirtual)
|
||||
#expect(file.path != nil)
|
||||
#expect(file.contents == "let i = 2")
|
||||
|
||||
file.write("let j = 2")
|
||||
|
||||
XCTAssertEqual(file.contents, "let j = 2")
|
||||
XCTAssertEqual(FileManager.default.contents(atPath: tempFile.path), Data("let j = 2".utf8))
|
||||
#expect(file.contents == "let j = 2")
|
||||
#expect(FileManager.default.contents(atPath: tempFile.path) == Data("let j = 2".utf8))
|
||||
|
||||
file.append("2")
|
||||
|
||||
XCTAssertEqual(file.contents, "let j = 22")
|
||||
XCTAssertEqual(FileManager.default.contents(atPath: tempFile.path), Data("let j = 22".utf8))
|
||||
#expect(file.contents == "let j = 22")
|
||||
#expect(FileManager.default.contents(atPath: tempFile.path) == Data("let j = 22".utf8))
|
||||
}
|
||||
|
||||
func testFileNotTouchedIfNothingAppended() throws {
|
||||
@Test
|
||||
func fileNotTouchedIfNothingAppended() throws {
|
||||
let file = SwiftLintFile(path: tempFile.path)!
|
||||
let initialModificationData = FileManager.default.modificationDate(forFileAtPath: tempFile.path)
|
||||
let initialModificationData = FileManager.default.modificationDate(
|
||||
forFileAtPath: tempFile.path)
|
||||
|
||||
file.append("")
|
||||
|
||||
XCTAssertEqual(initialModificationData, FileManager.default.modificationDate(forFileAtPath: tempFile.path))
|
||||
#expect(initialModificationData == FileManager.default.modificationDate(forFileAtPath: tempFile.path))
|
||||
}
|
||||
|
||||
func testFileNotTouchedIfNothingNewWritten() throws {
|
||||
@Test
|
||||
func fileNotTouchedIfNothingNewWritten() throws {
|
||||
let file = SwiftLintFile(path: tempFile.path)!
|
||||
let initialModificationData = FileManager.default.modificationDate(forFileAtPath: tempFile.path)
|
||||
let initialModificationData = FileManager.default.modificationDate(
|
||||
forFileAtPath: tempFile.path)
|
||||
|
||||
file.write("let i = 2")
|
||||
|
||||
XCTAssertEqual(initialModificationData, FileManager.default.modificationDate(forFileAtPath: tempFile.path))
|
||||
#expect(initialModificationData == FileManager.default.modificationDate(forFileAtPath: tempFile.path))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,42 +1,37 @@
|
||||
import Foundation
|
||||
import TestHelpers
|
||||
import XCTest
|
||||
import Testing
|
||||
import Yams
|
||||
|
||||
final class YamlSwiftLintTests: SwiftLintTestCase {
|
||||
func testFlattenYaml() throws {
|
||||
do {
|
||||
guard let yamlDict = try Yams.load(yaml: try getTestYaml()) as? [String: Any] else {
|
||||
XCTFail("Failed to load YAML from file")
|
||||
return
|
||||
}
|
||||
|
||||
let dict1 = (yamlDict["dictionary1"] as? [Swift.String: Any])!
|
||||
let dict2 = (yamlDict["dictionary2"] as? [Swift.String: Any])!
|
||||
XCTAssertTrue(dict1["bool"] as? Bool == true && dict2["bool"] as? Bool == true)
|
||||
XCTAssertTrue(dict1["int"] as? Int == 1 && dict2["int"] as? Int == 1)
|
||||
XCTAssertTrue(dict1["double"] as? Double == 1.0 && dict2["double"] as? Double == 1.0)
|
||||
XCTAssertTrue(dict1["string"] as? String == "string" &&
|
||||
dict2["string"] as? String == "string")
|
||||
|
||||
let array1 = (dict1["array"] as? [Any])!
|
||||
let array2 = (dict1["array"] as? [Any])!
|
||||
XCTAssertTrue(array1[0] as? Bool == true && array2[0] as? Bool == true)
|
||||
XCTAssertTrue(array1[1] as? Int == 1 && array2[1] as? Int == 1)
|
||||
XCTAssertTrue(array1[2] as? Double == 1.0 && array2[2] as? Double == 1.0)
|
||||
XCTAssertTrue(array1[3] as? String == "string" && array2[3] as? String == "string")
|
||||
|
||||
let dictFromArray1 = (array1[4] as? [Swift.String: Any])!
|
||||
let dictFromArray2 = (array2[4] as? [Swift.String: Any])!
|
||||
XCTAssertTrue(dictFromArray1["bool"] as? Bool == true && dictFromArray2["bool"] as? Bool == true)
|
||||
XCTAssertTrue(dictFromArray1["int"] as? Int == 1 && dictFromArray2["int"] as? Int == 1)
|
||||
XCTAssertTrue(dictFromArray1["double"] as? Double == 1.0 &&
|
||||
dictFromArray2["double"] as? Double == 1.0)
|
||||
XCTAssertTrue(dictFromArray1["string"] as? String == "string" &&
|
||||
dictFromArray2["string"] as? String == "string")
|
||||
} catch {
|
||||
XCTFail(error.localizedDescription)
|
||||
@Suite
|
||||
struct YamlSwiftLintTests {
|
||||
@Test
|
||||
func flattenYaml() throws {
|
||||
guard let yamlDict = try Yams.load(yaml: try getTestYaml()) as? [String: Any] else {
|
||||
Issue.record("Failed to load YAML from file")
|
||||
return
|
||||
}
|
||||
|
||||
let dict1 = (yamlDict["dictionary1"] as? [Swift.String: Any])!
|
||||
let dict2 = (yamlDict["dictionary2"] as? [Swift.String: Any])!
|
||||
#expect(dict1["bool"] as? Bool == true && dict2["bool"] as? Bool == true)
|
||||
#expect(dict1["int"] as? Int == 1 && dict2["int"] as? Int == 1)
|
||||
#expect(dict1["double"] as? Double == 1.0 && dict2["double"] as? Double == 1.0)
|
||||
#expect(dict1["string"] as? String == "string" && dict2["string"] as? String == "string")
|
||||
|
||||
let array1 = (dict1["array"] as? [Any])!
|
||||
let array2 = (dict1["array"] as? [Any])!
|
||||
#expect(array1[0] as? Bool == true && array2[0] as? Bool == true)
|
||||
#expect(array1[1] as? Int == 1 && array2[1] as? Int == 1)
|
||||
#expect(array1[2] as? Double == 1.0 && array2[2] as? Double == 1.0)
|
||||
#expect(array1[3] as? String == "string" && array2[3] as? String == "string")
|
||||
|
||||
let dictFromArray1 = (array1[4] as? [Swift.String: Any])!
|
||||
let dictFromArray2 = (array2[4] as? [Swift.String: Any])!
|
||||
#expect(dictFromArray1["bool"] as? Bool == true && dictFromArray2["bool"] as? Bool == true)
|
||||
#expect(dictFromArray1["int"] as? Int == 1 && dictFromArray2["int"] as? Int == 1)
|
||||
#expect(dictFromArray1["double"] as? Double == 1.0 && dictFromArray2["double"] as? Double == 1.0)
|
||||
#expect(dictFromArray1["string"] as? String == "string" && dictFromArray2["string"] as? String == "string")
|
||||
}
|
||||
|
||||
private func getTestYaml() throws -> String {
|
||||
|
||||
@@ -7,26 +7,13 @@ filegroup(
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
|
||||
genrule(
|
||||
name = "ExtraRulesLinuxMain",
|
||||
outs = ["main.swift"],
|
||||
cmd = """
|
||||
echo "import XCTest
|
||||
|
||||
XCTMain([testCase(ExtraRulesTests.allTests)])" >> $(OUTS)
|
||||
""",
|
||||
)
|
||||
|
||||
swift_library(
|
||||
name = "ExtraRulesTests.library",
|
||||
package_name = "SwiftLint",
|
||||
testonly = True,
|
||||
srcs = [
|
||||
"ExtraRulesTests.swift",
|
||||
] + select({
|
||||
"@platforms//os:linux": [":ExtraRulesLinuxMain"],
|
||||
"//conditions:default": [],
|
||||
}),
|
||||
],
|
||||
copts = STRICT_COPTS,
|
||||
module_name = "ExtraRulesTests",
|
||||
visibility = ["//visibility:public"],
|
||||
|
||||
@@ -1,16 +1,14 @@
|
||||
@testable import SwiftLintExtraRules
|
||||
import TestHelpers
|
||||
import Testing
|
||||
|
||||
final class ExtraRulesTests: SwiftLintTestCase, @unchecked Sendable {
|
||||
func testWithDefaultConfiguration() {
|
||||
@testable import SwiftLintExtraRules
|
||||
|
||||
@Suite
|
||||
struct ExtraRulesTests {
|
||||
@Test
|
||||
func withDefaultConfiguration() {
|
||||
for ruleType in extraRules() {
|
||||
verifyRule(ruleType.description)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension ExtraRulesTests {
|
||||
static var allTests: [(String, (ExtraRulesTests) -> () throws -> Void)] {
|
||||
[("testWithDefaultConfiguration", testWithDefaultConfiguration)]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,45 +1,37 @@
|
||||
@testable import SwiftLintBuiltInRules
|
||||
import XCTest
|
||||
import Foundation
|
||||
import TestHelpers
|
||||
import Testing
|
||||
|
||||
@testable import SwiftLintBuiltInRules
|
||||
@testable import SwiftLintCore
|
||||
|
||||
private var temporaryDirectoryPath: String {
|
||||
let result = URL(
|
||||
fileURLWithPath: NSTemporaryDirectory(),
|
||||
isDirectory: true
|
||||
).path
|
||||
// swiftlint:disable:next blanket_disable_command
|
||||
// swiftlint:disable contains_over_filter_is_empty
|
||||
|
||||
#if os(macOS)
|
||||
return "/private" + result
|
||||
#else
|
||||
return result
|
||||
#endif
|
||||
}
|
||||
|
||||
final class BaselineTests: XCTestCase {
|
||||
extension FileSystemAccessTestSuite.BaselineTests {
|
||||
private static let example = """
|
||||
import Foundation
|
||||
import SwiftLintFramework
|
||||
import Foundation
|
||||
import SwiftLintFramework
|
||||
|
||||
class Example: NSObject {
|
||||
private var foo: Int
|
||||
private var bar: String
|
||||
class Example: NSObject {
|
||||
private var foo: Int
|
||||
private var bar: String
|
||||
|
||||
init(foo: Int, bar: String) {
|
||||
self.foo = foo
|
||||
self.bar = bar
|
||||
} // init
|
||||
func someFunction() -> Int {
|
||||
foo * 10
|
||||
} // someFunction
|
||||
func someOtherFunction() -> String {
|
||||
bar
|
||||
} // someOtherFunction
|
||||
func yetAnotherFunction() -> (Int, String) {
|
||||
(foo, bar)
|
||||
} // yetAnotherFunction
|
||||
}
|
||||
"""
|
||||
init(foo: Int, bar: String) {
|
||||
self.foo = foo
|
||||
self.bar = bar
|
||||
} // init
|
||||
func someFunction() -> Int {
|
||||
foo * 10
|
||||
} // someFunction
|
||||
func someOtherFunction() -> String {
|
||||
bar
|
||||
} // someOtherFunction
|
||||
func yetAnotherFunction() -> (Int, String) {
|
||||
(foo, bar)
|
||||
} // yetAnotherFunction
|
||||
}
|
||||
"""
|
||||
|
||||
private static let ruleDescriptions = [
|
||||
ArrayInitRule.description,
|
||||
@@ -56,46 +48,40 @@ final class BaselineTests: XCTestCase {
|
||||
Baseline(violations: ruleDescriptions.violations(for: filePath))
|
||||
}
|
||||
|
||||
private nonisolated(unsafe) static var currentDirectoryPath: String?
|
||||
|
||||
override static func setUp() {
|
||||
super.setUp()
|
||||
currentDirectoryPath = FileManager.default.currentDirectoryPath
|
||||
XCTAssertTrue(FileManager.default.changeCurrentDirectoryPath(temporaryDirectoryPath))
|
||||
}
|
||||
|
||||
override static func tearDown() {
|
||||
XCTAssertTrue(FileManager.default.changeCurrentDirectoryPath(currentDirectoryPath!))
|
||||
super.tearDown()
|
||||
}
|
||||
|
||||
func testWritingAndReading() throws {
|
||||
@Test
|
||||
@TemporaryDirectory
|
||||
func writingAndReading() throws {
|
||||
try withExampleFileCreated { sourceFilePath in
|
||||
let baselinePath = temporaryDirectoryPath.stringByAppendingPathComponent(UUID().uuidString)
|
||||
try Baseline(violations: Self.violations(for: sourceFilePath)).write(toPath: baselinePath)
|
||||
let baselinePath = FileManager.default.currentDirectoryPath.stringByAppendingPathComponent(
|
||||
UUID().uuidString)
|
||||
try Baseline(violations: Self.violations(for: sourceFilePath)).write(
|
||||
toPath: baselinePath)
|
||||
defer {
|
||||
try? FileManager.default.removeItem(atPath: baselinePath)
|
||||
}
|
||||
let newBaseline = try Baseline(fromPath: baselinePath)
|
||||
XCTAssertEqual(newBaseline, Self.baseline(for: sourceFilePath))
|
||||
#expect(newBaseline == Self.baseline(for: sourceFilePath))
|
||||
}
|
||||
}
|
||||
|
||||
func testUnchangedViolations() throws {
|
||||
@Test
|
||||
func unchangedViolations() throws {
|
||||
try withExampleFileCreated { sourceFilePath in
|
||||
XCTAssertEqual(Self.baseline(for: sourceFilePath).filter(Self.violations(for: sourceFilePath)), [])
|
||||
#expect(Self.baseline(for: sourceFilePath).filter(Self.violations(for: sourceFilePath)).isEmpty)
|
||||
}
|
||||
}
|
||||
|
||||
func testShiftedViolations() throws {
|
||||
@Test
|
||||
func shiftedViolations() throws {
|
||||
try withExampleFileCreated { sourceFilePath in
|
||||
let baseline = Self.baseline(for: sourceFilePath)
|
||||
let violations = try Self.violations(for: sourceFilePath).lineShifted(by: 2, path: sourceFilePath)
|
||||
XCTAssertEqual(baseline.filter(violations), [])
|
||||
#expect(baseline.filter(violations).isEmpty)
|
||||
}
|
||||
}
|
||||
|
||||
func testNewViolation() throws {
|
||||
@Test
|
||||
func newViolation() throws {
|
||||
try testViolationDetection(
|
||||
violationRuleDescriptions: Self.ruleDescriptions,
|
||||
newViolationRuleDescription: EmptyCollectionLiteralRule.description,
|
||||
@@ -103,7 +89,15 @@ final class BaselineTests: XCTestCase {
|
||||
)
|
||||
}
|
||||
|
||||
func testViolationDetection() throws {
|
||||
@Test(
|
||||
arguments: [
|
||||
ArrayInitRule.description,
|
||||
BlockBasedKVORule.description,
|
||||
ClosingBraceRule.description,
|
||||
DirectReturnRule.description,
|
||||
]
|
||||
)
|
||||
func violationDetection(_ ruleDescription: RuleDescription) throws {
|
||||
let violationRuleDescriptions = [
|
||||
ArrayInitRule.description,
|
||||
BlockBasedKVORule.description,
|
||||
@@ -117,36 +111,30 @@ final class BaselineTests: XCTestCase {
|
||||
ClosingBraceRule.description,
|
||||
]
|
||||
|
||||
let ruleDescriptions = [
|
||||
ArrayInitRule.description,
|
||||
BlockBasedKVORule.description,
|
||||
ClosingBraceRule.description,
|
||||
DirectReturnRule.description,
|
||||
]
|
||||
|
||||
for ruleDescription in ruleDescriptions {
|
||||
for insertionIndex in 0..<violationRuleDescriptions.count {
|
||||
try testViolationDetection(
|
||||
violationRuleDescriptions: violationRuleDescriptions,
|
||||
newViolationRuleDescription: ruleDescription,
|
||||
insertionIndex: insertionIndex
|
||||
)
|
||||
}
|
||||
for insertionIndex in 0..<violationRuleDescriptions.count {
|
||||
try testViolationDetection(
|
||||
violationRuleDescriptions: violationRuleDescriptions,
|
||||
newViolationRuleDescription: ruleDescription,
|
||||
insertionIndex: insertionIndex
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
func testCompare() throws {
|
||||
@Test
|
||||
func compare() throws {
|
||||
try withExampleFileCreated { sourceFilePath in
|
||||
let ruleDescriptions = Self.ruleDescriptions + Self.ruleDescriptions
|
||||
let violations = ruleDescriptions.violations(for: sourceFilePath)
|
||||
let numberofViolationsToDrop = 3
|
||||
let oldBaseline = Baseline(violations: Array(violations.dropFirst(numberofViolationsToDrop)).reversed())
|
||||
let oldBaseline = Baseline(
|
||||
violations: Array(violations.dropFirst(numberofViolationsToDrop)).reversed()
|
||||
)
|
||||
let newViolations = Array(
|
||||
try violations.lineShifted(by: 2, path: sourceFilePath).dropLast(numberofViolationsToDrop)
|
||||
)
|
||||
let newBaseline = Baseline(violations: newViolations.reversed())
|
||||
XCTAssertEqual(oldBaseline.compare(newBaseline), Array(newViolations.prefix(numberofViolationsToDrop)))
|
||||
XCTAssertEqual(newBaseline.compare(oldBaseline), Array(violations.suffix(numberofViolationsToDrop)))
|
||||
#expect(oldBaseline.compare(newBaseline) == Array(newViolations.prefix(numberofViolationsToDrop)))
|
||||
#expect(newBaseline.compare(oldBaseline) == Array(violations.suffix(numberofViolationsToDrop)))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -170,14 +158,16 @@ final class BaselineTests: XCTestCase {
|
||||
location: Location(file: sourceFilePath, line: line, character: 1)
|
||||
)
|
||||
newViolations.insert(violation, at: insertionIndex)
|
||||
XCTAssertEqual(baseline.filter(newViolations), [violation])
|
||||
#expect(baseline.filter(newViolations) == [violation])
|
||||
}
|
||||
}
|
||||
|
||||
private func withExampleFileCreated(_ block: (String) throws -> Void) throws {
|
||||
let sourceFilePath = temporaryDirectoryPath.stringByAppendingPathComponent("\(UUID().uuidString).swift")
|
||||
let sourceFilePath = FileManager.default.currentDirectoryPath.stringByAppendingPathComponent(
|
||||
"\(UUID().uuidString).swift"
|
||||
)
|
||||
guard let data = Self.example.data(using: .utf8) else {
|
||||
XCTFail("Could not convert example code to data using UTF-8 encoding")
|
||||
Issue.record("Could not convert example code to data using UTF-8 encoding")
|
||||
return
|
||||
}
|
||||
try data.write(to: URL(fileURLWithPath: sourceFilePath))
|
||||
@@ -191,7 +181,7 @@ final class BaselineTests: XCTestCase {
|
||||
private extension [StyleViolation] {
|
||||
func lineShifted(by shift: Int, path: String) throws -> [StyleViolation] {
|
||||
guard shift > 0 else {
|
||||
XCTFail("Shift must be positive")
|
||||
Issue.record("Shift must be positive")
|
||||
return self
|
||||
}
|
||||
var lines = SwiftLintFile(path: path)?.lines.map(\.content) ?? []
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user