diff --git a/.bazelrc b/.bazelrc index 0304307c3c..af0cfb72fa 100644 --- a/.bazelrc +++ b/.bazelrc @@ -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 diff --git a/.swift-format b/.swift-format new file mode 100644 index 0000000000..fd95550b34 --- /dev/null +++ b/.swift-format @@ -0,0 +1,9 @@ +{ + "indentation" : { + "spaces" : 4 + }, + "lineLength": 120, + "rules" : { + "NoAccessLevelOnExtensionDeclaration": false + } +} diff --git a/.swift-version b/.swift-version new file mode 100644 index 0000000000..0cda48ac61 --- /dev/null +++ b/.swift-version @@ -0,0 +1 @@ +6.2 diff --git a/.swiftlint.yml b/.swiftlint.yml index 40b137e624..611d98539d 100644 --- a/.swiftlint.yml +++ b/.swiftlint.yml @@ -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 diff --git a/Source/SwiftLintCore/Helpers/Macros.swift b/Source/SwiftLintCore/Helpers/Macros.swift index e4d3f02057..3ab7558c18 100644 --- a/Source/SwiftLintCore/Helpers/Macros.swift +++ b/Source/SwiftLintCore/Helpers/Macros.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" ) diff --git a/Source/SwiftLintCoreMacros/DisabledWithoutSourceKit.swift b/Source/SwiftLintCoreMacros/DisabledWithoutSourceKit.swift index 5c346f6991..18675671db 100644 --- a/Source/SwiftLintCoreMacros/DisabledWithoutSourceKit.swift +++ b/Source/SwiftLintCoreMacros/DisabledWithoutSourceKit.swift @@ -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() { diff --git a/Source/SwiftLintCoreMacros/RuleConfigurationMacros.swift b/Source/SwiftLintCoreMacros/RuleConfigurationMacros.swift index fc29e8267e..64621267f1 100644 --- a/Source/SwiftLintCoreMacros/RuleConfigurationMacros.swift +++ b/Source/SwiftLintCoreMacros/RuleConfigurationMacros.swift @@ -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 { diff --git a/Source/SwiftLintFramework/Configuration/Configuration+Remote.swift b/Source/SwiftLintFramework/Configuration/Configuration+Remote.swift index bd27bce998..74f3779f08 100644 --- a/Source/SwiftLintFramework/Configuration/Configuration+Remote.swift +++ b/Source/SwiftLintFramework/Configuration/Configuration+Remote.swift @@ -58,11 +58,6 @@ internal extension Configuration.FileGraph.FilePath { if let mockedValue = Configuration.FileGraph.FilePath.mockedNetworkResults[urlString] { configString = mockedValue } else { - // Handle missing network - guard Reachability.connectivityStatus != .disconnected else { - return try handleMissingNetwork(urlString: urlString, cachedFilePath: cachedFilePath) - } - // Handle wrong url format guard let url = URL(string: urlString) else { throw Issue.genericWarning("Invalid configuration entry: \"\(urlString)\" isn't a valid url.") @@ -117,21 +112,6 @@ internal extension Configuration.FileGraph.FilePath { return filePath } - private mutating func handleMissingNetwork(urlString: String, cachedFilePath: String?) throws -> String { - if let cachedFilePath { - queuedPrintError( - "warning: No internet connectivity: Unable to load remote config from \"\(urlString)\". " - + "Using cached version as a fallback." - ) - self = .existing(path: cachedFilePath) - return cachedFilePath - } - throw Issue.genericWarning( - "No internet connectivity: Unable to load remote config from \"\(urlString)\". " - + "Also didn't found cached version to fallback to." - ) - } - private mutating func handleWrongData( urlString: String, cachedFilePath: String?, diff --git a/Source/SwiftLintFramework/Helpers/Reachability.swift b/Source/SwiftLintFramework/Helpers/Reachability.swift deleted file mode 100644 index 1731588826..0000000000 --- a/Source/SwiftLintFramework/Helpers/Reachability.swift +++ /dev/null @@ -1,44 +0,0 @@ -#if !os(Linux) -import SystemConfiguration -#endif - -/// Helper enum providing the static var `connectivityStatus` -enum Reachability { - enum ConnectivityStatus { - case connected, disconnected, unknown - } - - /// Returns whether the device is connected to a network, if known. - /// On Linux, this always evaluates to `nil`. - static var connectivityStatus: ConnectivityStatus { -#if os(Linux) - return .unknown -#else - var zeroAddress = sockaddr_in() - zeroAddress.sin_len = UInt8(MemoryLayout.size) - zeroAddress.sin_family = sa_family_t(AF_INET) - - guard let defaultRouteReachability = withUnsafePointer(to: &zeroAddress, { - $0.withMemoryRebound(to: sockaddr.self, capacity: 1) { - SCNetworkReachabilityCreateWithAddress(nil, $0) - } - }) else { - return .unknown - } - - var flags: SCNetworkReachabilityFlags = [] - if !SCNetworkReachabilityGetFlags(defaultRouteReachability, &flags) { - return .unknown - } - - if flags.isEmpty { - return .disconnected - } - - let isReachable = flags.contains(.reachable) - let needsConnection = flags.contains(.connectionRequired) - - return (isReachable && !needsConnection) ? .connected : .disconnected -#endif - } -} diff --git a/Source/SwiftLintFramework/LintOrAnalyzeCommand.swift b/Source/SwiftLintFramework/LintOrAnalyzeCommand.swift index 4af32083a4..b6702135b6 100644 --- a/Source/SwiftLintFramework/LintOrAnalyzeCommand.swift +++ b/Source/SwiftLintFramework/LintOrAnalyzeCommand.swift @@ -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: """ diff --git a/Source/swiftlint-dev/Rules+Register.swift b/Source/swiftlint-dev/Rules+Register.swift index 56619554ea..8456e6b01e 100644 --- a/Source/swiftlint-dev/Rules+Register.swift +++ b/Source/swiftlint-dev/Rules+Register.swift @@ -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) } } diff --git a/Tests/BuiltInRulesTests/AttributesRuleTests.swift b/Tests/BuiltInRulesTests/AttributesRuleTests.swift index ec8a993573..b8799dd94b 100644 --- a/Tests/BuiltInRulesTests/AttributesRuleTests.swift +++ b/Tests/BuiltInRulesTests/AttributesRuleTests.swift @@ -1,22 +1,28 @@ -@testable import SwiftLintBuiltInRules import TestHelpers +import Testing + +@testable import SwiftLintBuiltInRules -final class AttributesRuleTests: SwiftLintTestCase { - func testAttributesWithAlwaysOnSameLine() { +@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]) } } diff --git a/Tests/BuiltInRulesTests/BlanketDisableCommandRuleTests.swift b/Tests/BuiltInRulesTests/BlanketDisableCommandRuleTests.swift index 061f7a637e..284ac43425 100644 --- a/Tests/BuiltInRulesTests/BlanketDisableCommandRuleTests.swift +++ b/Tests/BuiltInRulesTests/BlanketDisableCommandRuleTests.swift @@ -1,15 +1,18 @@ -@testable import SwiftLintBuiltInRules import TestHelpers -import XCTest +import Testing + +@testable import SwiftLintBuiltInRules -final class BlanketDisableCommandRuleTests: SwiftLintTestCase { - private lazy var emptyDescription = BlanketDisableCommandRule.description +@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)) } } diff --git a/Tests/BuiltInRulesTests/ChildOptionSeverityConfigurationTests.swift b/Tests/BuiltInRulesTests/ChildOptionSeverityConfigurationTests.swift index 71d82b74e9..c406c9c34d 100644 --- a/Tests/BuiltInRulesTests/ChildOptionSeverityConfigurationTests.swift +++ b/Tests/BuiltInRulesTests/ChildOptionSeverityConfigurationTests.swift @@ -1,33 +1,42 @@ -@testable import SwiftLintBuiltInRules import TestHelpers -import XCTest +import Testing + +@testable import SwiftLintBuiltInRules -final class ChildOptionSeverityConfigurationTests: SwiftLintTestCase { +@Suite(.rulesRegistered) +struct ChildOptionSeverityConfigurationTests { typealias TesteeType = ChildOptionSeverityConfiguration - 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) + } } } diff --git a/Tests/BuiltInRulesTests/CollectionAlignmentRuleTests.swift b/Tests/BuiltInRulesTests/CollectionAlignmentRuleTests.swift index 13b63a3b82..88f117cba9 100644 --- a/Tests/BuiltInRulesTests/CollectionAlignmentRuleTests.swift +++ b/Tests/BuiltInRulesTests/CollectionAlignmentRuleTests.swift @@ -1,8 +1,12 @@ -@testable import SwiftLintBuiltInRules import TestHelpers +import Testing + +@testable import SwiftLintBuiltInRules -final class CollectionAlignmentRuleTests: SwiftLintTestCase { - func testCollectionAlignmentWithAlignLeft() { +@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) diff --git a/Tests/BuiltInRulesTests/ColonRuleTests.swift b/Tests/BuiltInRulesTests/ColonRuleTests.swift index cc3c45f7cf..d3e1db6453 100644 --- a/Tests/BuiltInRulesTests/ColonRuleTests.swift +++ b/Tests/BuiltInRulesTests/ColonRuleTests.swift @@ -1,8 +1,12 @@ -@testable import SwiftLintBuiltInRules import TestHelpers +import Testing + +@testable import SwiftLintBuiltInRules -final class ColonRuleTests: SwiftLintTestCase { - func testColonWithFlexibleRightSpace() { +@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"), diff --git a/Tests/BuiltInRulesTests/CompilerProtocolInitRuleTests.swift b/Tests/BuiltInRulesTests/CompilerProtocolInitRuleTests.swift index 27ddecd07f..4d707f8cd6 100644 --- a/Tests/BuiltInRulesTests/CompilerProtocolInitRuleTests.swift +++ b/Tests/BuiltInRulesTests/CompilerProtocolInitRuleTests.swift @@ -1,22 +1,20 @@ -@testable import SwiftLintBuiltInRules import TestHelpers -import XCTest +import Testing + +@testable import SwiftLintBuiltInRules -final class CompilerProtocolInitRuleTests: SwiftLintTestCase { +@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" ) } } diff --git a/Tests/BuiltInRulesTests/ComputedAccessorsOrderRuleTests.swift b/Tests/BuiltInRulesTests/ComputedAccessorsOrderRuleTests.swift index 878814f0b3..e24b68661e 100644 --- a/Tests/BuiltInRulesTests/ComputedAccessorsOrderRuleTests.swift +++ b/Tests/BuiltInRulesTests/ComputedAccessorsOrderRuleTests.swift @@ -1,9 +1,12 @@ -@testable import SwiftLintBuiltInRules import TestHelpers -import XCTest +import Testing + +@testable import SwiftLintBuiltInRules -final class ComputedAccessorsOrderRuleTests: SwiftLintTestCase { - func testSetGetConfiguration() { +@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) } } diff --git a/Tests/BuiltInRulesTests/ConditionalReturnsOnNewlineRuleTests.swift b/Tests/BuiltInRulesTests/ConditionalReturnsOnNewlineRuleTests.swift index 96a31dbd7e..3397394653 100644 --- a/Tests/BuiltInRulesTests/ConditionalReturnsOnNewlineRuleTests.swift +++ b/Tests/BuiltInRulesTests/ConditionalReturnsOnNewlineRuleTests.swift @@ -1,8 +1,12 @@ -@testable import SwiftLintBuiltInRules import TestHelpers +import Testing + +@testable import SwiftLintBuiltInRules -final class ConditionalReturnsOnNewlineRuleTests: SwiftLintTestCase { - func testConditionalReturnsOnNewlineWithIfOnly() { +@Suite(.rulesRegistered) +struct ConditionalReturnsOnNewlineRuleTests { + @Test + func conditionalReturnsOnNewlineWithIfOnly() { // Test with `if_only` set to true let nonTriggeringExamples = [ Example("guard true else {\n return true\n}"), diff --git a/Tests/BuiltInRulesTests/ContainsOverFirstNotNilRuleTests.swift b/Tests/BuiltInRulesTests/ContainsOverFirstNotNilRuleTests.swift index c2657af060..2584933078 100644 --- a/Tests/BuiltInRulesTests/ContainsOverFirstNotNilRuleTests.swift +++ b/Tests/BuiltInRulesTests/ContainsOverFirstNotNilRuleTests.swift @@ -1,22 +1,26 @@ -@testable import SwiftLintBuiltInRules import TestHelpers -import XCTest +import Testing + +@testable import SwiftLintBuiltInRules -final class ContainsOverFirstNotNilRuleTests: SwiftLintTestCase { - func testFirstReason() { +@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) } } diff --git a/Tests/BuiltInRulesTests/CyclomaticComplexityConfigurationTests.swift b/Tests/BuiltInRulesTests/CyclomaticComplexityConfigurationTests.swift index 0bc2d69291..152cfd3f87 100644 --- a/Tests/BuiltInRulesTests/CyclomaticComplexityConfigurationTests.swift +++ b/Tests/BuiltInRulesTests/CyclomaticComplexityConfigurationTests.swift @@ -1,34 +1,39 @@ -@testable import SwiftLintBuiltInRules import TestHelpers -import XCTest +import Testing + +@testable import SwiftLintBuiltInRules -final class CyclomaticComplexityConfigurationTests: SwiftLintTestCase { - func testCyclomaticComplexityConfigurationInitializerSetsLevels() { +@Suite(.rulesRegistered) +struct CyclomaticComplexityConfigurationTests { + @Test + func cyclomaticComplexityConfigurationInitializerSetsLevels() { let warning = 10 let error = 30 let level = SeverityLevelsConfiguration(warning: warning, error: error) let configuration1 = CyclomaticComplexityConfiguration(length: level) - XCTAssertEqual(configuration1.length, level) + #expect(configuration1.length == level) let length2 = SeverityLevelsConfiguration(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) } } diff --git a/Tests/BuiltInRulesTests/CyclomaticComplexityRuleTests.swift b/Tests/BuiltInRulesTests/CyclomaticComplexityRuleTests.swift index 4b6e28bb64..608a1270a1 100644 --- a/Tests/BuiltInRulesTests/CyclomaticComplexityRuleTests.swift +++ b/Tests/BuiltInRulesTests/CyclomaticComplexityRuleTests.swift @@ -1,8 +1,11 @@ -@testable import SwiftLintBuiltInRules import TestHelpers +import Testing + +@testable import SwiftLintBuiltInRules -final class CyclomaticComplexityRuleTests: SwiftLintTestCase { - private lazy var complexSwitchExample: Example = { +@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) diff --git a/Tests/BuiltInRulesTests/DeploymentTargetConfigurationTests.swift b/Tests/BuiltInRulesTests/DeploymentTargetConfigurationTests.swift index f5ee0e659b..89694cf7df 100644 --- a/Tests/BuiltInRulesTests/DeploymentTargetConfigurationTests.swift +++ b/Tests/BuiltInRulesTests/DeploymentTargetConfigurationTests.swift @@ -1,92 +1,70 @@ -@testable import SwiftLintBuiltInRules import TestHelpers -import XCTest +import Testing + +@testable import SwiftLintBuiltInRules -final class DeploymentTargetConfigurationTests: SwiftLintTestCase { +@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) - ) - XCTAssertEqual( - configuration.iOSAppExtensionDeploymentTarget, - Version(platform: .iOSApplicationExtension, major: 13, minor: 0) + #expect(configuration.iOSDeploymentTarget == Version(platform: .iOS, major: 10, minor: 1)) + #expect( + 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) - ) - XCTAssertEqual( - configuration.iOSAppExtensionDeploymentTarget, - Version(platform: .iOSApplicationExtension, major: 13, minor: 0) + #expect(configuration.iOSDeploymentTarget == Version(platform: .iOS, major: 10, minor: 1)) + #expect( + configuration.iOSAppExtensionDeploymentTarget + == Version(platform: .iOSApplicationExtension, major: 13, minor: 0) ) - XCTAssertEqual( - configuration.macOSDeploymentTarget, - Version(platform: .macOS, major: 10, minor: 11, patch: 3) + #expect(configuration.macOSDeploymentTarget == Version(platform: .macOS, major: 10, minor: 11, patch: 3)) + #expect( + configuration.macOSAppExtensionDeploymentTarget + == Version(platform: .macOSApplicationExtension, major: 12, minor: 4) ) - 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) - ) - XCTAssertEqual( - configuration.iOSAppExtensionDeploymentTarget, - Version(platform: .iOSApplicationExtension, major: 13, minor: 0) + #expect(configuration.iOSDeploymentTarget == Version(platform: .iOS, major: 10, minor: 1)) + #expect( + configuration.iOSAppExtensionDeploymentTarget + == Version(platform: .iOSApplicationExtension, major: 13, minor: 0) ) - XCTAssertEqual( - configuration.macOSDeploymentTarget, - Version(platform: .macOS, major: 10, minor: 11, patch: 3) + #expect(configuration.macOSDeploymentTarget == Version(platform: .macOS, major: 10, minor: 11, patch: 3)) + #expect( + configuration.macOSAppExtensionDeploymentTarget + == Version(platform: .macOSApplicationExtension, major: 12, minor: 4) ) - 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) - ) - XCTAssertEqual( - configuration.iOSAppExtensionDeploymentTarget, - Version(platform: .iOSApplicationExtension, major: 13, minor: 0) - ) - XCTAssertEqual( - configuration.macOSDeploymentTarget, - Version(platform: .macOS, major: 10, minor: 11, patch: 3) - ) - XCTAssertEqual( - configuration.macOSAppExtensionDeploymentTarget, - Version(platform: .macOSApplicationExtension, major: 12, minor: 4) - ) - 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.iOSDeploymentTarget == Version(platform: .iOS, major: 10, minor: 1)) + #expect( + 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) + ) + #expect(configuration.tvOSDeploymentTarget == Version(platform: .tvOS, major: 10, minor: 2)) + #expect( + configuration.tvOSAppExtensionDeploymentTarget + == Version(platform: .tvOSApplicationExtension, major: 9, minor: 1) + ) + #expect(configuration.watchOSDeploymentTarget == Version(platform: .watchOS, major: 5)) + #expect( + configuration.watchOSAppExtensionDeploymentTarget + == Version(platform: .watchOSApplicationExtension, major: 2, minor: 2) + ) + #expect(configuration.severityConfiguration.severity == .warning) } - func testThrowsOnBadConfig() { + @Test + func throwsOnBadConfig() { let badConfigs: [[String: Any]] = [ ["iOS_deployment_target": "foo"], ["iOS_deployment_target": ""], diff --git a/Tests/BuiltInRulesTests/DeploymentTargetRuleTests.swift b/Tests/BuiltInRulesTests/DeploymentTargetRuleTests.swift index 15c81e378a..9510114790 100644 --- a/Tests/BuiltInRulesTests/DeploymentTargetRuleTests.swift +++ b/Tests/BuiltInRulesTests/DeploymentTargetRuleTests.swift @@ -1,45 +1,53 @@ -@testable import SwiftLintBuiltInRules import TestHelpers -import XCTest +import Testing + +@testable import SwiftLintBuiltInRules -final class DeploymentTargetRuleTests: SwiftLintTestCase { - func testMacOSAttributeReason() { +@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) } } diff --git a/Tests/BuiltInRulesTests/DiscouragedDirectInitRuleTests.swift b/Tests/BuiltInRulesTests/DiscouragedDirectInitRuleTests.swift index 35897dec9c..a215c0f55e 100644 --- a/Tests/BuiltInRulesTests/DiscouragedDirectInitRuleTests.swift +++ b/Tests/BuiltInRulesTests/DiscouragedDirectInitRuleTests.swift @@ -1,14 +1,19 @@ -@testable import SwiftLintBuiltInRules import TestHelpers +import Testing + +@testable import SwiftLintBuiltInRules -final class DiscouragedDirectInitRuleTests: SwiftLintTestCase { +@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()") ] diff --git a/Tests/BuiltInRulesTests/DiscouragedObjectLiteralRuleTests.swift b/Tests/BuiltInRulesTests/DiscouragedObjectLiteralRuleTests.swift index fe90df77e4..ce79e68efe 100644 --- a/Tests/BuiltInRulesTests/DiscouragedObjectLiteralRuleTests.swift +++ b/Tests/BuiltInRulesTests/DiscouragedObjectLiteralRuleTests.swift @@ -1,33 +1,44 @@ -@testable import SwiftLintBuiltInRules import TestHelpers +import Testing + +@testable import SwiftLintBuiltInRules -final class DiscouragedObjectLiteralRuleTests: SwiftLintTestCase { - func testWithImageLiteral() { +@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]) } diff --git a/Tests/BuiltInRulesTests/DuplicateImportsRuleTests.swift b/Tests/BuiltInRulesTests/DuplicateImportsRuleTests.swift index 5a125b426b..697c8d29e3 100644 --- a/Tests/BuiltInRulesTests/DuplicateImportsRuleTests.swift +++ b/Tests/BuiltInRulesTests/DuplicateImportsRuleTests.swift @@ -1,8 +1,11 @@ +import Testing + @testable import SwiftLintBuiltInRules -import XCTest -final class DuplicateImportsRuleTests: XCTestCase { - func testDisableCommand() { +@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) } } diff --git a/Tests/BuiltInRulesTests/EmptyCountRuleTests.swift b/Tests/BuiltInRulesTests/EmptyCountRuleTests.swift index 75d50cf456..15e46d1b23 100644 --- a/Tests/BuiltInRulesTests/EmptyCountRuleTests.swift +++ b/Tests/BuiltInRulesTests/EmptyCountRuleTests.swift @@ -1,8 +1,12 @@ -@testable import SwiftLintBuiltInRules import TestHelpers +import Testing + +@testable import SwiftLintBuiltInRules -final class EmptyCountRuleTests: SwiftLintTestCase { - func testEmptyCountWithOnlyAfterDot() { +@Suite(.rulesRegistered) +struct EmptyCountRuleTests { + @Test + func emptyCountWithOnlyAfterDot() { // Test with `only_after_dot` set to true let nonTriggeringExamples = [ Example("var count = 0\n"), diff --git a/Tests/BuiltInRulesTests/ExpiringTodoRuleTests.swift b/Tests/BuiltInRulesTests/ExpiringTodoRuleTests.swift index bfbe34d150..b6482a2422 100644 --- a/Tests/BuiltInRulesTests/ExpiringTodoRuleTests.swift +++ b/Tests/BuiltInRulesTests/ExpiringTodoRuleTests.swift @@ -1,49 +1,59 @@ -@testable import SwiftLintBuiltInRules +import Foundation import TestHelpers -import XCTest +import Testing + +@testable import SwiftLintBuiltInRules -final class ExpiringTodoRuleTests: SwiftLintTestCase { - func testExpiringTodo() { +@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] { diff --git a/Tests/BuiltInRulesTests/ExplicitInitRuleTests.swift b/Tests/BuiltInRulesTests/ExplicitInitRuleTests.swift index 407efbe3bc..6933bde76f 100644 --- a/Tests/BuiltInRulesTests/ExplicitInitRuleTests.swift +++ b/Tests/BuiltInRulesTests/ExplicitInitRuleTests.swift @@ -1,8 +1,12 @@ -@testable import SwiftLintBuiltInRules import TestHelpers +import Testing + +@testable import SwiftLintBuiltInRules -final class ExplicitInitRuleTests: SwiftLintTestCase { - func testIncludeBareInit() { +@Suite(.rulesRegistered) +struct ExplicitInitRuleTests { + @Test + func includeBareInit() { let nonTriggeringExamples = [ Example("let foo = Foo()"), Example("let foo = init()"), diff --git a/Tests/BuiltInRulesTests/ExplicitTypeInterfaceConfigurationTests.swift b/Tests/BuiltInRulesTests/ExplicitTypeInterfaceConfigurationTests.swift index 3fe7ace943..81d674cc9b 100644 --- a/Tests/BuiltInRulesTests/ExplicitTypeInterfaceConfigurationTests.swift +++ b/Tests/BuiltInRulesTests/ExplicitTypeInterfaceConfigurationTests.swift @@ -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" ) } } diff --git a/Tests/BuiltInRulesTests/ExplicitTypeInterfaceRuleTests.swift b/Tests/BuiltInRulesTests/ExplicitTypeInterfaceRuleTests.swift index 99c9120ec3..7b228e4e9d 100644 --- a/Tests/BuiltInRulesTests/ExplicitTypeInterfaceRuleTests.swift +++ b/Tests/BuiltInRulesTests/ExplicitTypeInterfaceRuleTests.swift @@ -1,8 +1,12 @@ -@testable import SwiftLintBuiltInRules import TestHelpers +import Testing + +@testable import SwiftLintBuiltInRules -final class ExplicitTypeInterfaceRuleTests: SwiftLintTestCase { - func testLocalVars() { +@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 { diff --git a/Tests/BuiltInRulesTests/FileHeaderRuleTests.swift b/Tests/BuiltInRulesTests/FileHeaderRuleTests.swift index 9d38e96843..1754244ee0 100644 --- a/Tests/BuiltInRulesTests/FileHeaderRuleTests.swift +++ b/Tests/BuiltInRulesTests/FileHeaderRuleTests.swift @@ -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(""" diff --git a/Tests/BuiltInRulesTests/FileLengthRuleTests.swift b/Tests/BuiltInRulesTests/FileLengthRuleTests.swift index 490377caac..840c41339a 100644 --- a/Tests/BuiltInRulesTests/FileLengthRuleTests.swift +++ b/Tests/BuiltInRulesTests/FileLengthRuleTests.swift @@ -1,13 +1,18 @@ -@testable import SwiftLintBuiltInRules import TestHelpers +import Testing + +@testable import SwiftLintBuiltInRules -final class FileLengthRuleTests: SwiftLintTestCase { - func testFileLengthWithDefaultConfiguration() { +@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()) ] diff --git a/Tests/BuiltInRulesTests/FileNameNoSpaceRuleTests.swift b/Tests/BuiltInRulesTests/FileNameNoSpaceRuleTests.swift index 9c0b3a1d01..32d1697ef7 100644 --- a/Tests/BuiltInRulesTests/FileNameNoSpaceRuleTests.swift +++ b/Tests/BuiltInRulesTests/FileNameNoSpaceRuleTests.swift @@ -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 + ) } } diff --git a/Tests/BuiltInRulesTests/FileNameRuleTests.swift b/Tests/BuiltInRulesTests/FileNameRuleTests.swift index d81ede7ffa..284cdcf7a9 100644 --- a/Tests/BuiltInRulesTests/FileNameRuleTests.swift +++ b/Tests/BuiltInRulesTests/FileNameRuleTests.swift @@ -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"] ) - ) + } } } diff --git a/Tests/BuiltInRulesTests/FileTypesOrderRuleTests.swift b/Tests/BuiltInRulesTests/FileTypesOrderRuleTests.swift index 4632cd32f7..32c628ffe2 100644 --- a/Tests/BuiltInRulesTests/FileTypesOrderRuleTests.swift +++ b/Tests/BuiltInRulesTests/FileTypesOrderRuleTests.swift @@ -1,9 +1,12 @@ -@testable import SwiftLintBuiltInRules import TestHelpers +import Testing + +@testable import SwiftLintBuiltInRules -final class FileTypesOrderRuleTests: SwiftLintTestCase { - // swiftlint:disable:next function_body_length - func testFileTypesOrderReversedOrder() { +@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(""" diff --git a/Tests/BuiltInRulesTests/FunctionBodyLengthRuleTests.swift b/Tests/BuiltInRulesTests/FunctionBodyLengthRuleTests.swift index 41422a8dd1..b99c80bf0f 100644 --- a/Tests/BuiltInRulesTests/FunctionBodyLengthRuleTests.swift +++ b/Tests/BuiltInRulesTests/FunctionBodyLengthRuleTests.swift @@ -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"] ) } diff --git a/Tests/BuiltInRulesTests/FunctionNameWhitespaceRuleTests.swift b/Tests/BuiltInRulesTests/FunctionNameWhitespaceRuleTests.swift index 7e94a2a161..0ab872aab4 100644 --- a/Tests/BuiltInRulesTests/FunctionNameWhitespaceRuleTests.swift +++ b/Tests/BuiltInRulesTests/FunctionNameWhitespaceRuleTests.swift @@ -1,8 +1,10 @@ -@testable import SwiftLintBuiltInRules import TestHelpers -import XCTest +import Testing + +@testable import SwiftLintBuiltInRules -final class FunctionNameWhitespaceRuleTests: SwiftLintTestCase { +@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 <|<(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 (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(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(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(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 (lhs: Int) {}", configuration: ["generic_spacing": "leading_trailing_space"], diff --git a/Tests/BuiltInRulesTests/FunctionParameterCountRuleTests.swift b/Tests/BuiltInRulesTests/FunctionParameterCountRuleTests.swift index 0c9b24d21c..6a9d0ca8dc 100644 --- a/Tests/BuiltInRulesTests/FunctionParameterCountRuleTests.swift +++ b/Tests/BuiltInRulesTests/FunctionParameterCountRuleTests.swift @@ -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") diff --git a/Tests/BuiltInRulesTests/GenericTypeNameRuleTests.swift b/Tests/BuiltInRulesTests/GenericTypeNameRuleTests.swift index 105600aafb..0324d6e500 100644 --- a/Tests/BuiltInRulesTests/GenericTypeNameRuleTests.swift +++ b/Tests/BuiltInRulesTests/GenericTypeNameRuleTests.swift @@ -1,8 +1,12 @@ -@testable import SwiftLintBuiltInRules import TestHelpers +import Testing + +@testable import SwiftLintBuiltInRules -final class GenericTypeNameRuleTests: SwiftLintTestCase { - func testGenericTypeNameWithExcluded() { +@Suite(.rulesRegistered) +struct GenericTypeNameRuleTests { + @Test + func genericTypeNameWithExcluded() { let baseDescription = GenericTypeNameRule.description let nonTriggeringExamples = baseDescription.nonTriggeringExamples + [ Example("func foo {}"), @@ -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() {}"), @@ -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>() {}"), diff --git a/Tests/BuiltInRulesTests/IdentifierNameRuleTests.swift b/Tests/BuiltInRulesTests/IdentifierNameRuleTests.swift index 2e0ebd5489..287ac21824 100644 --- a/Tests/BuiltInRulesTests/IdentifierNameRuleTests.swift +++ b/Tests/BuiltInRulesTests/IdentifierNameRuleTests.swift @@ -1,9 +1,12 @@ -@testable import SwiftLintBuiltInRules import TestHelpers -import XCTest +import Testing + +@testable import SwiftLintBuiltInRules -final class IdentifierNameRuleTests: SwiftLintTestCase { - func testIdentifierNameWithExcluded() { +@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"] ) } } diff --git a/Tests/BuiltInRulesTests/ImplicitGetterRuleTests.swift b/Tests/BuiltInRulesTests/ImplicitGetterRuleTests.swift index 105b55c98c..d61b66682e 100644 --- a/Tests/BuiltInRulesTests/ImplicitGetterRuleTests.swift +++ b/Tests/BuiltInRulesTests/ImplicitGetterRuleTests.swift @@ -1,39 +1,43 @@ -@testable import SwiftLintBuiltInRules import TestHelpers -import XCTest +import Testing + +@testable import SwiftLintBuiltInRules -final class ImplicitGetterRuleTests: SwiftLintTestCase { - func testPropertyReason() throws { - let config = try XCTUnwrap(makeConfig(nil, ImplicitGetterRule.identifier)) +@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") } } diff --git a/Tests/BuiltInRulesTests/ImplicitReturnConfigurationTests.swift b/Tests/BuiltInRulesTests/ImplicitReturnConfigurationTests.swift index f3d2e82a5c..07f63ddcf2 100644 --- a/Tests/BuiltInRulesTests/ImplicitReturnConfigurationTests.swift +++ b/Tests/BuiltInRulesTests/ImplicitReturnConfigurationTests.swift @@ -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()) 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] diff --git a/Tests/BuiltInRulesTests/ImplicitReturnRuleTests.swift b/Tests/BuiltInRulesTests/ImplicitReturnRuleTests.swift index 97f480f59e..37cc6b8000 100644 --- a/Tests/BuiltInRulesTests/ImplicitReturnRuleTests.swift +++ b/Tests/BuiltInRulesTests/ImplicitReturnRuleTests.swift @@ -1,8 +1,12 @@ -@testable import SwiftLintBuiltInRules import TestHelpers +import Testing + +@testable import SwiftLintBuiltInRules -final class ImplicitReturnRuleTests: SwiftLintTestCase { - func testOnlyClosureKindIncluded() { +@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]]) } } diff --git a/Tests/BuiltInRulesTests/ImplicitlyUnwrappedOptionalConfigurationTests.swift b/Tests/BuiltInRulesTests/ImplicitlyUnwrappedOptionalConfigurationTests.swift index 4e2b716b19..b20f594d96 100644 --- a/Tests/BuiltInRulesTests/ImplicitlyUnwrappedOptionalConfigurationTests.swift +++ b/Tests/BuiltInRulesTests/ImplicitlyUnwrappedOptionalConfigurationTests.swift @@ -1,33 +1,37 @@ -@testable import SwiftLintBuiltInRules import TestHelpers -import XCTest +import Testing + +@testable import SwiftLintBuiltInRules + +@Suite(.rulesRegistered) +struct ImplicitlyUnwrappedOptionalConfigurationTests { // swiftlint:disable:this type_name -// swiftlint:disable:next type_name -final class ImplicitlyUnwrappedOptionalConfigurationTests: SwiftLintTestCase { - func testImplicitlyUnwrappedOptionalConfigurationProperlyAppliesConfigurationFromDictionary() throws { + @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) } } diff --git a/Tests/BuiltInRulesTests/ImplicitlyUnwrappedOptionalRuleTests.swift b/Tests/BuiltInRulesTests/ImplicitlyUnwrappedOptionalRuleTests.swift index e840f3da0d..b7ab405e3c 100644 --- a/Tests/BuiltInRulesTests/ImplicitlyUnwrappedOptionalRuleTests.swift +++ b/Tests/BuiltInRulesTests/ImplicitlyUnwrappedOptionalRuleTests.swift @@ -1,15 +1,19 @@ -@testable import SwiftLintBuiltInRules import TestHelpers -import XCTest +import Testing + +@testable import SwiftLintBuiltInRules -final class ImplicitlyUnwrappedOptionalRuleTests: SwiftLintTestCase { - func testImplicitlyUnwrappedOptionalRuleDefaultConfiguration() { +@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!"), diff --git a/Tests/BuiltInRulesTests/InclusiveLanguageRuleTests.swift b/Tests/BuiltInRulesTests/InclusiveLanguageRuleTests.swift index a2b291fad1..ed8e87ed92 100644 --- a/Tests/BuiltInRulesTests/InclusiveLanguageRuleTests.swift +++ b/Tests/BuiltInRulesTests/InclusiveLanguageRuleTests.swift @@ -1,8 +1,12 @@ -@testable import SwiftLintBuiltInRules import TestHelpers +import Testing + +@testable import SwiftLintBuiltInRules -final class InclusiveLanguageRuleTests: SwiftLintTestCase { - func testNonTriggeringExamplesWithNonDefaultConfig() { +@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: []) diff --git a/Tests/BuiltInRulesTests/IndentationWidthRuleTests.swift b/Tests/BuiltInRulesTests/IndentationWidthRuleTests.swift index 936dd77bfc..8edc72cd5b 100644 --- a/Tests/BuiltInRulesTests/IndentationWidthRuleTests.swift +++ b/Tests/BuiltInRulesTests/IndentationWidthRuleTests.swift @@ -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 + ) ) } diff --git a/Tests/BuiltInRulesTests/LineLengthConfigurationTests.swift b/Tests/BuiltInRulesTests/LineLengthConfigurationTests.swift index 2f4dd25ec3..1e81f987c3 100644 --- a/Tests/BuiltInRulesTests/LineLengthConfigurationTests.swift +++ b/Tests/BuiltInRulesTests/LineLengthConfigurationTests.swift @@ -1,83 +1,95 @@ -@testable import SwiftLintBuiltInRules import TestHelpers -import XCTest +import Testing + +@testable import SwiftLintBuiltInRules -final class LineLengthConfigurationTests: SwiftLintTestCase { +@Suite(.rulesRegistered) +struct LineLengthConfigurationTests { private let severityLevels = SeverityLevelsConfiguration(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(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) } } diff --git a/Tests/BuiltInRulesTests/LineLengthRuleTests.swift b/Tests/BuiltInRulesTests/LineLengthRuleTests.swift index 13acbf6d7c..0db5dfde4b 100644 --- a/Tests/BuiltInRulesTests/LineLengthRuleTests.swift +++ b/Tests/BuiltInRulesTests/LineLengthRuleTests.swift @@ -1,7 +1,10 @@ -@testable import SwiftLintBuiltInRules import TestHelpers +import Testing + +@testable import SwiftLintBuiltInRules -final class LineLengthRuleTests: SwiftLintTestCase { +@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 diff --git a/Tests/BuiltInRulesTests/MissingDocsRuleTests.swift b/Tests/BuiltInRulesTests/MissingDocsRuleTests.swift index 8255c1693d..58969288ab 100644 --- a/Tests/BuiltInRulesTests/MissingDocsRuleTests.swift +++ b/Tests/BuiltInRulesTests/MissingDocsRuleTests.swift @@ -1,207 +1,230 @@ -@testable import SwiftLintBuiltInRules import TestHelpers -import XCTest +import Testing + +@testable import SwiftLintBuiltInRules -final class MissingDocsRuleTests: SwiftLintTestCase { - func testDescriptionEmpty() { +@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(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(severity: .error, value: .open), RuleParameter(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(severity: .warning, value: .open), RuleParameter(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(severity: .warning, value: .open)] + #expect( + configuration.parameters == [RuleParameter(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(severity: .warning, value: .public), RuleParameter(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(severity: .warning, value: .public), RuleParameter(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(severity: .warning, value: .public), RuleParameter(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(severity: .warning, value: .public), RuleParameter(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(severity: .warning, value: .public), RuleParameter(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(severity: .warning, value: .public), RuleParameter(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(severity: .error, value: .public)] + #expect(configuration.excludesExtensions) + #expect(!configuration.excludesInheritedTypes) + #expect( + configuration.parameters.sorted { $0.value.rawValue > $1.value.rawValue } + == [RuleParameter(severity: .error, value: .public)] ) } } diff --git a/Tests/FrameworkTests/ModifierOrderTests.swift b/Tests/BuiltInRulesTests/ModifierOrderTests.swift similarity index 93% rename from Tests/FrameworkTests/ModifierOrderTests.swift rename to Tests/BuiltInRulesTests/ModifierOrderTests.swift index 74fdd92001..4f15f82c36 100644 --- a/Tests/FrameworkTests/ModifierOrderTests.swift +++ b/Tests/BuiltInRulesTests/ModifierOrderTests.swift @@ -1,9 +1,14 @@ -@testable import SwiftLintBuiltInRules import TestHelpers -import XCTest +import Testing + +@testable import SwiftLintBuiltInRules + +// swiftlint:disable file_length -final class ModifierOrderTests: SwiftLintTestCase { - func testAttributeTypeMethod() { +@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!") } } } diff --git a/Tests/BuiltInRulesTests/MultilineArgumentsRuleTests.swift b/Tests/BuiltInRulesTests/MultilineArgumentsRuleTests.swift index fe0a9faf44..fc522d4767 100644 --- a/Tests/BuiltInRulesTests/MultilineArgumentsRuleTests.swift +++ b/Tests/BuiltInRulesTests/MultilineArgumentsRuleTests.swift @@ -1,8 +1,12 @@ -@testable import SwiftLintBuiltInRules import TestHelpers +import Testing + +@testable import SwiftLintBuiltInRules -final class MultilineArgumentsRuleTests: SwiftLintTestCase { - func testMultilineArgumentsWithWithNextLine() { +@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)"), diff --git a/Tests/BuiltInRulesTests/MultilineParametersConfigurationTests.swift b/Tests/BuiltInRulesTests/MultilineParametersConfigurationTests.swift index 2915e344d4..de7b38fae2 100644 --- a/Tests/BuiltInRulesTests/MultilineParametersConfigurationTests.swift +++ b/Tests/BuiltInRulesTests/MultilineParametersConfigurationTests.swift @@ -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. + """ ) } } diff --git a/Tests/BuiltInRulesTests/NameConfigurationTests.swift b/Tests/BuiltInRulesTests/NameConfigurationTests.swift index fabcc9b847..70e9246281 100644 --- a/Tests/BuiltInRulesTests/NameConfigurationTests.swift +++ b/Tests/BuiltInRulesTests/NameConfigurationTests.swift @@ -1,11 +1,14 @@ -@testable import SwiftLintBuiltInRules import TestHelpers -import XCTest +import Testing + +@testable import SwiftLintBuiltInRules -final class NameConfigurationTests: SwiftLintTestCase { +@Suite(.rulesRegistered) +struct NameConfigurationTests { typealias TesteeType = NameConfiguration - 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) } } diff --git a/Tests/BuiltInRulesTests/NestingRuleTests.swift b/Tests/BuiltInRulesTests/NestingRuleTests.swift index b41082edb4..02b881eeea 100644 --- a/Tests/BuiltInRulesTests/NestingRuleTests.swift +++ b/Tests/BuiltInRulesTests/NestingRuleTests.swift @@ -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 [ diff --git a/Tests/BuiltInRulesTests/NoEmptyBlockConfigurationTests.swift b/Tests/BuiltInRulesTests/NoEmptyBlockConfigurationTests.swift index 737172b732..8b1c66b822 100644 --- a/Tests/BuiltInRulesTests/NoEmptyBlockConfigurationTests.swift +++ b/Tests/BuiltInRulesTests/NoEmptyBlockConfigurationTests.swift @@ -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]" ) } } diff --git a/Tests/BuiltInRulesTests/NumberSeparatorRuleTests.swift b/Tests/BuiltInRulesTests/NumberSeparatorRuleTests.swift index 362e55ce4f..109383a863 100644 --- a/Tests/BuiltInRulesTests/NumberSeparatorRuleTests.swift +++ b/Tests/BuiltInRulesTests/NumberSeparatorRuleTests.swift @@ -1,10 +1,13 @@ -@testable import SwiftLintBuiltInRules import SwiftParser import TestHelpers -import XCTest +import Testing + +@testable import SwiftLintBuiltInRules -final class NumberSeparatorRuleTests: SwiftLintTestCase { - func testNumberSeparatorWithMinimumLength() { +@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"), - [] - ) - XCTAssertEqual( - violations(in: "1000"), - [NumberSeparatorRule.missingSeparatorsReason] - ) - 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] + @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: "10_00", config: ["minimum_length": 5]), - [NumberSeparatorRule.misplacedSeparatorsReason] + #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: "1000.0_00", config: ["minimum_fraction_length": 5]), - [NumberSeparatorRule.misplacedSeparatorsReason] + #expect( + violations(in: "1000.0_00", config: ["minimum_fraction_length": 5]) + == [NumberSeparatorRule.misplacedSeparatorsReason] ) } diff --git a/Tests/BuiltInRulesTests/ObjectLiteralRuleTests.swift b/Tests/BuiltInRulesTests/ObjectLiteralRuleTests.swift index 988b8a9a93..24e9c127d7 100644 --- a/Tests/BuiltInRulesTests/ObjectLiteralRuleTests.swift +++ b/Tests/BuiltInRulesTests/ObjectLiteralRuleTests.swift @@ -1,7 +1,10 @@ -@testable import SwiftLintBuiltInRules import TestHelpers +import Testing + +@testable import SwiftLintBuiltInRules -final class ObjectLiteralRuleTests: SwiftLintTestCase { +@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]) diff --git a/Tests/BuiltInRulesTests/OpeningBraceRuleTests.swift b/Tests/BuiltInRulesTests/OpeningBraceRuleTests.swift index a2246f8261..deaf6262cc 100644 --- a/Tests/BuiltInRulesTests/OpeningBraceRuleTests.swift +++ b/Tests/BuiltInRulesTests/OpeningBraceRuleTests.swift @@ -1,8 +1,12 @@ -@testable import SwiftLintBuiltInRules import TestHelpers +import Testing + +@testable import SwiftLintBuiltInRules -final class OpeningBraceRuleTests: SwiftLintTestCase { - func testDefaultNonTriggeringExamplesWithMultilineOptionsTrue() { +@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( diff --git a/Tests/BuiltInRulesTests/PreferKeyPathRuleTests.swift b/Tests/BuiltInRulesTests/PreferKeyPathRuleTests.swift index f1d1b06264..7ed23bdfc3 100644 --- a/Tests/BuiltInRulesTests/PreferKeyPathRuleTests.swift +++ b/Tests/BuiltInRulesTests/PreferKeyPathRuleTests.swift @@ -1,8 +1,10 @@ -@testable import SwiftLintBuiltInRules import TestHelpers -import XCTest +import Testing + +@testable import SwiftLintBuiltInRules -final class PreferKeyPathRuleTests: SwiftLintTestCase { +@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 }"), diff --git a/Tests/BuiltInRulesTests/PrefixedTopLevelConstantRuleTests.swift b/Tests/BuiltInRulesTests/PrefixedTopLevelConstantRuleTests.swift index bbe836d3a7..55994ffcac 100644 --- a/Tests/BuiltInRulesTests/PrefixedTopLevelConstantRuleTests.swift +++ b/Tests/BuiltInRulesTests/PrefixedTopLevelConstantRuleTests.swift @@ -1,8 +1,12 @@ -@testable import SwiftLintBuiltInRules import TestHelpers +import Testing + +@testable import SwiftLintBuiltInRules -final class PrefixedTopLevelConstantRuleTests: SwiftLintTestCase { - func testPrivateOnly() { +@Suite(.rulesRegistered) +struct PrefixedTopLevelConstantRuleTests { + @Test + func privateOnly() { let triggeringExamples = [ Example("private let ↓Foo = 20.0"), Example("fileprivate let ↓foo = 20.0"), diff --git a/Tests/BuiltInRulesTests/PrivateOverFilePrivateRuleTests.swift b/Tests/BuiltInRulesTests/PrivateOverFilePrivateRuleTests.swift index baa77f7ee0..3b4746979a 100644 --- a/Tests/BuiltInRulesTests/PrivateOverFilePrivateRuleTests.swift +++ b/Tests/BuiltInRulesTests/PrivateOverFilePrivateRuleTests.swift @@ -1,8 +1,12 @@ -@testable import SwiftLintBuiltInRules import TestHelpers +import Testing + +@testable import SwiftLintBuiltInRules -final class PrivateOverFilePrivateRuleTests: SwiftLintTestCase { - func testPrivateOverFilePrivateValidatingExtensions() { +@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 {}") diff --git a/Tests/BuiltInRulesTests/RequiredEnumCaseConfigurationTests.swift b/Tests/BuiltInRulesTests/RequiredEnumCaseConfigurationTests.swift index bad8e2e969..f94f3586f2 100644 --- a/Tests/BuiltInRulesTests/RequiredEnumCaseConfigurationTests.swift +++ b/Tests/BuiltInRulesTests/RequiredEnumCaseConfigurationTests.swift @@ -1,8 +1,10 @@ -@testable import SwiftLintBuiltInRules import TestHelpers -import XCTest +import Testing + +@testable import SwiftLintBuiltInRules -final class RequiredEnumCaseConfigurationTests: SwiftLintTestCase { +@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) } } diff --git a/Tests/BuiltInRulesTests/StatementPositionRuleTests.swift b/Tests/BuiltInRulesTests/StatementPositionRuleTests.swift index ab4b81f353..36c3ce7018 100644 --- a/Tests/BuiltInRulesTests/StatementPositionRuleTests.swift +++ b/Tests/BuiltInRulesTests/StatementPositionRuleTests.swift @@ -1,8 +1,12 @@ -@testable import SwiftLintBuiltInRules import TestHelpers +import Testing + +@testable import SwiftLintBuiltInRules -final class StatementPositionRuleTests: SwiftLintTestCase { - func testStatementPositionUncuddled() { +@Suite(.rulesRegistered) +struct StatementPositionRuleTests { + @Test + func statementPositionUncuddled() { let configuration = ["statement_mode": "uncuddled_else"] verifyRule(StatementPositionRule.uncuddledDescription, ruleConfiguration: configuration) } diff --git a/Tests/BuiltInRulesTests/SwitchCaseAlignmentRuleTests.swift b/Tests/BuiltInRulesTests/SwitchCaseAlignmentRuleTests.swift index 9bada421fa..5662353ee3 100644 --- a/Tests/BuiltInRulesTests/SwitchCaseAlignmentRuleTests.swift +++ b/Tests/BuiltInRulesTests/SwitchCaseAlignmentRuleTests.swift @@ -1,8 +1,12 @@ -@testable import SwiftLintBuiltInRules import TestHelpers +import Testing + +@testable import SwiftLintBuiltInRules -final class SwitchCaseAlignmentRuleTests: SwiftLintTestCase { - func testSwitchCaseAlignmentWithoutIndentedCases() { +@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) diff --git a/Tests/BuiltInRulesTests/TodoRuleTests.swift b/Tests/BuiltInRulesTests/TodoRuleTests.swift index aebfec9dbe..e302ca18fa 100644 --- a/Tests/BuiltInRulesTests/TodoRuleTests.swift +++ b/Tests/BuiltInRulesTests/TodoRuleTests.swift @@ -1,44 +1,51 @@ -@testable import SwiftLintBuiltInRules import TestHelpers -import XCTest +import Testing + +@testable import SwiftLintBuiltInRules -final class TodoRuleTests: SwiftLintTestCase { - func testTodo() { +@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] { diff --git a/Tests/BuiltInRulesTests/TrailingClosureConfigurationTests.swift b/Tests/BuiltInRulesTests/TrailingClosureConfigurationTests.swift index 0baef0beb9..d530cfce3b 100644 --- a/Tests/BuiltInRulesTests/TrailingClosureConfigurationTests.swift +++ b/Tests/BuiltInRulesTests/TrailingClosureConfigurationTests.swift @@ -1,15 +1,19 @@ -@testable import SwiftLintBuiltInRules import TestHelpers -import XCTest +import Testing + +@testable import SwiftLintBuiltInRules -final class TrailingClosureConfigurationTests: SwiftLintTestCase { - func testDefaultConfiguration() { +@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) } } diff --git a/Tests/BuiltInRulesTests/TrailingClosureRuleTests.swift b/Tests/BuiltInRulesTests/TrailingClosureRuleTests.swift index 4ffd56a096..9b0ea6e3b9 100644 --- a/Tests/BuiltInRulesTests/TrailingClosureRuleTests.swift +++ b/Tests/BuiltInRulesTests/TrailingClosureRuleTests.swift @@ -1,8 +1,12 @@ -@testable import SwiftLintBuiltInRules import TestHelpers +import Testing + +@testable import SwiftLintBuiltInRules -final class TrailingClosureRuleTests: SwiftLintTestCase { - func testWithOnlySingleMutedParameterEnabled() { +@Suite(.rulesRegistered) +struct TrailingClosureRuleTests { + @Test + func withOnlySingleMutedParameterEnabled() { let originalDescription = TrailingClosureRule.description let description = originalDescription .with(nonTriggeringExamples: originalDescription.nonTriggeringExamples + [ diff --git a/Tests/BuiltInRulesTests/TrailingCommaRuleTests.swift b/Tests/BuiltInRulesTests/TrailingCommaRuleTests.swift index a4aa896a31..5be83d17e2 100644 --- a/Tests/BuiltInRulesTests/TrailingCommaRuleTests.swift +++ b/Tests/BuiltInRulesTests/TrailingCommaRuleTests.swift @@ -1,9 +1,12 @@ -@testable import SwiftLintBuiltInRules import TestHelpers -import XCTest +import Testing + +@testable import SwiftLintBuiltInRules -final class TrailingCommaRuleTests: SwiftLintTestCase { - func testTrailingCommaRuleWithDefaultConfiguration() { +@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] { diff --git a/Tests/BuiltInRulesTests/TrailingWhitespaceRuleTests.swift b/Tests/BuiltInRulesTests/TrailingWhitespaceRuleTests.swift index e79c400467..8ab82707b0 100644 --- a/Tests/BuiltInRulesTests/TrailingWhitespaceRuleTests.swift +++ b/Tests/BuiltInRulesTests/TrailingWhitespaceRuleTests.swift @@ -1,8 +1,12 @@ -@testable import SwiftLintBuiltInRules import TestHelpers +import Testing + +@testable import SwiftLintBuiltInRules -final class TrailingWhitespaceRuleTests: SwiftLintTestCase { - func testWithIgnoresEmptyLinesEnabled() { +@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 = [ diff --git a/Tests/BuiltInRulesTests/TypeBodyLengthConfigurationTests.swift b/Tests/BuiltInRulesTests/TypeBodyLengthConfigurationTests.swift index bf1b72ce93..2249c90b51 100644 --- a/Tests/BuiltInRulesTests/TypeBodyLengthConfigurationTests.swift +++ b/Tests/BuiltInRulesTests/TypeBodyLengthConfigurationTests.swift @@ -1,16 +1,20 @@ -@testable import SwiftLintBuiltInRules import TestHelpers -import XCTest +import Testing + +@testable import SwiftLintBuiltInRules -final class TypeBodyLengthConfigurationTests: SwiftLintTestCase { - func testDefaultConfiguration() { +@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] ) } } diff --git a/Tests/BuiltInRulesTests/TypeBodyLengthRuleTests.swift b/Tests/BuiltInRulesTests/TypeBodyLengthRuleTests.swift index 9b2e04c769..9fc24481f6 100644 --- a/Tests/BuiltInRulesTests/TypeBodyLengthRuleTests.swift +++ b/Tests/BuiltInRulesTests/TypeBodyLengthRuleTests.swift @@ -1,9 +1,12 @@ -@testable import SwiftLintBuiltInRules import TestHelpers -import XCTest +import Testing + +@testable import SwiftLintBuiltInRules -final class TypeBodyLengthRuleTests: SwiftLintTestCase { - func testWarning() { +@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"] ) } diff --git a/Tests/BuiltInRulesTests/TypeContentsOrderRuleTests.swift b/Tests/BuiltInRulesTests/TypeContentsOrderRuleTests.swift index 8f4b0bd1c0..0cd436af4e 100644 --- a/Tests/BuiltInRulesTests/TypeContentsOrderRuleTests.swift +++ b/Tests/BuiltInRulesTests/TypeContentsOrderRuleTests.swift @@ -1,9 +1,12 @@ -@testable import SwiftLintBuiltInRules import TestHelpers +import Testing + +@testable import SwiftLintBuiltInRules -final class TypeContentsOrderRuleTests: SwiftLintTestCase { - // swiftlint:disable:next function_body_length - func testTypeContentsOrderReversedOrder() { +@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(""" diff --git a/Tests/BuiltInRulesTests/TypeNameRuleTests.swift b/Tests/BuiltInRulesTests/TypeNameRuleTests.swift index cd8aa9abec..957bd33454 100644 --- a/Tests/BuiltInRulesTests/TypeNameRuleTests.swift +++ b/Tests/BuiltInRulesTests/TypeNameRuleTests.swift @@ -1,8 +1,12 @@ -@testable import SwiftLintBuiltInRules import TestHelpers +import Testing + +@testable import SwiftLintBuiltInRules -final class TypeNameRuleTests: SwiftLintTestCase { - func testTypeNameWithExcluded() { +@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"), diff --git a/Tests/BuiltInRulesTests/TypesafeArrayInitRuleTests.swift b/Tests/BuiltInRulesTests/TypesafeArrayInitRuleTests.swift index 792f8090db..affeeb7e77 100644 --- a/Tests/BuiltInRulesTests/TypesafeArrayInitRuleTests.swift +++ b/Tests/BuiltInRulesTests/TypesafeArrayInitRuleTests.swift @@ -1,20 +1,16 @@ -@testable import SwiftLintBuiltInRules import TestHelpers -import XCTest +import Testing + +@testable import SwiftLintBuiltInRules -final class TypesafeArrayInitRuleTests: SwiftLintTestCase { - func testViolationRuleIdentifier() { +@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) } } diff --git a/Tests/BuiltInRulesTests/UnneededOverrideRuleTests.swift b/Tests/BuiltInRulesTests/UnneededOverrideRuleTests.swift index f32bea1598..4a550cf134 100644 --- a/Tests/BuiltInRulesTests/UnneededOverrideRuleTests.swift +++ b/Tests/BuiltInRulesTests/UnneededOverrideRuleTests.swift @@ -1,8 +1,12 @@ -@testable import SwiftLintBuiltInRules import TestHelpers +import Testing + +@testable import SwiftLintBuiltInRules -final class UnneededOverrideRuleTests: SwiftLintTestCase { - func testIncludeAffectInits() { +@Suite(.rulesRegistered) +struct UnneededOverrideRuleTests { + @Test + func includeAffectInits() { let nonTriggeringExamples = [ Example(""" override init() { diff --git a/Tests/BuiltInRulesTests/UnusedDeclarationConfigurationTests.swift b/Tests/BuiltInRulesTests/UnusedDeclarationConfigurationTests.swift index 8b1e4dc492..1449d36903 100644 --- a/Tests/BuiltInRulesTests/UnusedDeclarationConfigurationTests.swift +++ b/Tests/BuiltInRulesTests/UnusedDeclarationConfigurationTests.swift @@ -1,8 +1,11 @@ +import Testing + @testable import SwiftLintBuiltInRules -import XCTest -final class UnusedDeclarationConfigurationTests: XCTestCase { - func testParseConfiguration() throws { +@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"]) } } diff --git a/Tests/BuiltInRulesTests/UnusedOptionalBindingRuleTests.swift b/Tests/BuiltInRulesTests/UnusedOptionalBindingRuleTests.swift index 801efc8842..39ba41c9a3 100644 --- a/Tests/BuiltInRulesTests/UnusedOptionalBindingRuleTests.swift +++ b/Tests/BuiltInRulesTests/UnusedOptionalBindingRuleTests.swift @@ -1,8 +1,12 @@ -@testable import SwiftLintBuiltInRules import TestHelpers +import Testing + +@testable import SwiftLintBuiltInRules -final class UnusedOptionalBindingRuleTests: SwiftLintTestCase { - func testDefaultConfiguration() { +@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 + [ diff --git a/Tests/BuiltInRulesTests/VerticalWhitespaceRuleTests.swift b/Tests/BuiltInRulesTests/VerticalWhitespaceRuleTests.swift index f3fd7ad4e4..690419cb4a 100644 --- a/Tests/BuiltInRulesTests/VerticalWhitespaceRuleTests.swift +++ b/Tests/BuiltInRulesTests/VerticalWhitespaceRuleTests.swift @@ -1,11 +1,14 @@ -@testable import SwiftLintBuiltInRules import TestHelpers -import XCTest +import Testing + +@testable import SwiftLintBuiltInRules -final class VerticalWhitespaceRuleTests: SwiftLintTestCase { +@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") } } diff --git a/Tests/BuiltInRulesTests/XCTSpecificMatcherRuleTests.swift b/Tests/BuiltInRulesTests/XCTSpecificMatcherRuleTests.swift index 808a737a19..723b5b7dbb 100644 --- a/Tests/BuiltInRulesTests/XCTSpecificMatcherRuleTests.swift +++ b/Tests/BuiltInRulesTests/XCTSpecificMatcherRuleTests.swift @@ -1,234 +1,265 @@ -@testable import SwiftLintBuiltInRules import TestHelpers -import XCTest +import Testing + +@testable import SwiftLintBuiltInRules -final class XCTSpecificMatcherRuleTests: SwiftLintTestCase { - func testEqualTrue() { +@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] { diff --git a/Tests/CoreTests/AccessControlLevelTests.swift b/Tests/CoreTests/AccessControlLevelTests.swift index 5c41080f2a..5385075ec3 100644 --- a/Tests/CoreTests/AccessControlLevelTests.swift +++ b/Tests/CoreTests/AccessControlLevelTests.swift @@ -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) } } diff --git a/Tests/CoreTests/CodeIndentingRewriterTests.swift b/Tests/CoreTests/CodeIndentingRewriterTests.swift index 071b6aff8d..f847329e67 100644 --- a/Tests/CoreTests/CodeIndentingRewriterTests.swift +++ b/Tests/CoreTests/CodeIndentingRewriterTests.swift @@ -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) } } diff --git a/Tests/CoreTests/CommentLinesVisitorTests.swift b/Tests/CoreTests/CommentLinesVisitorTests.swift index 4a52981348..4429f669c6 100644 --- a/Tests/CoreTests/CommentLinesVisitorTests.swift +++ b/Tests/CoreTests/CommentLinesVisitorTests.swift @@ -1,35 +1,41 @@ -@testable import SwiftLintCore -import XCTest - -final class CommentLinesVisitorTests: XCTestCase { - func testEmptyFile() { - XCTAssertEqual(commentOnlyLines(in: ""), []) +import SwiftLintCore +import Testing + +@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] { diff --git a/Tests/CoreTests/ConditionallySourceKitFreeTests.swift b/Tests/CoreTests/ConditionallySourceKitFreeTests.swift index 6ba7aa806d..7ea6388ddf 100644 --- a/Tests/CoreTests/ConditionallySourceKitFreeTests.swift +++ b/Tests/CoreTests/ConditionallySourceKitFreeTests.swift @@ -1,86 +1,88 @@ -@testable import SwiftLintCore -import XCTest - -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(.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(.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 - ) +import SwiftLintCore +import Testing - var configuration = SeverityConfiguration(.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(.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(.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(.warning) + + func validate(file _: SwiftLintFile) -> [StyleViolation] { + [] } } diff --git a/Tests/CoreTests/DisableAllTests.swift b/Tests/CoreTests/DisableAllTests.swift index 83b6c36ed4..62fcdcc1d1 100644 --- a/Tests/CoreTests/DisableAllTests.swift +++ b/Tests/CoreTests/DisableAllTests.swift @@ -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) } } diff --git a/Tests/CoreTests/ExampleTests.swift b/Tests/CoreTests/ExampleTests.swift index 9053fb9705..fe605121ba 100644 --- a/Tests/CoreTests/ExampleTests.swift +++ b/Tests/CoreTests/ExampleTests.swift @@ -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) } } diff --git a/Tests/CoreTests/ExtendedNSStringTests.swift b/Tests/CoreTests/ExtendedNSStringTests.swift index 8deb6609a4..f80c205a06 100644 --- a/Tests/CoreTests/ExtendedNSStringTests.swift +++ b/Tests/CoreTests/ExtendedNSStringTests.swift @@ -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.") } } } diff --git a/Tests/CoreTests/ExtendedStringTests.swift b/Tests/CoreTests/ExtendedStringTests.swift index 16c28ca70a..e83ba060bc 100644 --- a/Tests/CoreTests/ExtendedStringTests.swift +++ b/Tests/CoreTests/ExtendedStringTests.swift @@ -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) } } diff --git a/Tests/CoreTests/LineEndingTests.swift b/Tests/CoreTests/LineEndingTests.swift index 7cf2cbaa7b..28e85f785b 100644 --- a/Tests/CoreTests/LineEndingTests.swift +++ b/Tests/CoreTests/LineEndingTests.swift @@ -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 ) diff --git a/Tests/CoreTests/RegexConfigurationTests.swift b/Tests/CoreTests/RegexConfigurationTests.swift index 75f38d1092..0cd502e183 100644 --- a/Tests/CoreTests/RegexConfigurationTests.swift +++ b/Tests/CoreTests/RegexConfigurationTests.swift @@ -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(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(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(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(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(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(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")) } } diff --git a/Tests/CoreTests/RegionTests.swift b/Tests/CoreTests/RegionTests.swift index 7eb84cb52f..38bd2901b9 100644 --- a/Tests/CoreTests/RegionTests.swift +++ b/Tests/CoreTests/RegionTests.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: []), ]) } } diff --git a/Tests/CoreTests/RuleConfigurationDescriptionTests.swift b/Tests/CoreTests/RuleConfigurationDescriptionTests.swift index 4d83677ff4..729791c34c 100644 --- a/Tests/CoreTests/RuleConfigurationDescriptionTests.swift +++ b/Tests/CoreTests/RuleConfigurationDescriptionTests.swift @@ -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(), """ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
KeyValue
- 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 - - - - - - - - - - - - - - - -
KeyValue
- warning - - 3 -
- error - - 2 -
-
- """) + #expect( + description.markdown() == """ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
KeyValue
+ 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 + + + + + + + + + + + + + + + +
KeyValue
+ warning + + 3 +
+ error + + 2 +
+
+ """) - 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(), """ - - - - - - - - - - -
KeyValue
- visible - - true -
- """) - XCTAssertEqual(description.yaml(), "visible: true") + #expect(description.oneLiner() == "visible: true") + #expect( + description.markdown() == """ + + + + + + + + + + +
KeyValue
+ visible + + true +
+ """) + #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(), """ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
KeyValue
- flag - - true -
- string - - "value" -
- symbol - - value -
- integer - - -12 -
- float - - 42.0 -
- severity - - error -
- list - - [value, "value", 12.8] -
- """) + #expect( + description.markdown() == """ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
KeyValue
+ flag + + true +
+ string + + "value" +
+ symbol + + value +
+ integer + + -12 +
+ float + + 42.0 +
+ severity + + error +
+ list + + [value, "value", 12.8] +
+ """) - 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(), """ - - - - - - - - - - - - - - - - - - -
KeyValue
- flag - - true -
- nested 1 - - - - - - - - - - - - - - - - - - - -
KeyValue
- integer - - 2 -
- nested 2 - - - - - - - - - - - -
KeyValue
- float - - 42.1 -
-
- symbol - - value -
-
- string - - "value" -
- """) + #expect( + description.markdown() == """ + + + + + + + + + + + + + + + + + + +
KeyValue
+ flag + + true +
+ nested 1 + + + + + + + + + + + + + + + + + + + +
KeyValue
+ integer + + 2 +
+ nested 2 + + + + + + + + + + + +
KeyValue
+ float + + 42.1 +
+
+ symbol + + value +
+
+ string + + "value" +
+ """) - 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'." ) } diff --git a/Tests/CoreTests/RuleTests.swift b/Tests/CoreTests/RuleTests.swift index 79c930c42a..9c8a732316 100644 --- a/Tests/CoreTests/RuleTests.swift +++ b/Tests/CoreTests/RuleTests.swift @@ -1,15 +1,37 @@ import SwiftLintCore -import TestHelpers -import XCTest +import Testing + +struct RuleWithLevelsMock: Rule { + var configuration = SeverityLevelsConfiguration(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] { [] } +} -final class RuleTests: SwiftLintTestCase { +@Suite +struct RuleTests { fileprivate struct RuleMock1: Rule { var configuration = SeverityConfiguration(.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(.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(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())) } } diff --git a/Tests/CoreTests/SeverityLevelsConfigurationTests.swift b/Tests/CoreTests/SeverityLevelsConfigurationTests.swift index 43c248e1dc..32dbe75612 100644 --- a/Tests/CoreTests/SeverityLevelsConfigurationTests.swift +++ b/Tests/CoreTests/SeverityLevelsConfigurationTests.swift @@ -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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(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 } } diff --git a/Tests/CoreTests/StringExtensionTests.swift b/Tests/CoreTests/StringExtensionTests.swift index 8a093fac6f..5b1778757e 100644 --- a/Tests/CoreTests/StringExtensionTests.swift +++ b/Tests/CoreTests/StringExtensionTests.swift @@ -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) } } diff --git a/Tests/CoreTests/SwiftLintFileTests.swift b/Tests/CoreTests/SwiftLintFileTests.swift index e08ee5175b..c80802f3d7 100644 --- a/Tests/CoreTests/SwiftLintFileTests.swift +++ b/Tests/CoreTests/SwiftLintFileTests.swift @@ -1,69 +1,79 @@ +import Foundation +import Testing + @testable import SwiftLintCore -import TestHelpers -import XCTest -final class SwiftLintFileTests: SwiftLintTestCase { +@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)) } } diff --git a/Tests/CoreTests/YamlSwiftLintTests.swift b/Tests/CoreTests/YamlSwiftLintTests.swift index 0cfce0f323..ea47e9c033 100644 --- a/Tests/CoreTests/YamlSwiftLintTests.swift +++ b/Tests/CoreTests/YamlSwiftLintTests.swift @@ -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 - } +@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])! - 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 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])! - 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 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])! - 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) - } + 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 { diff --git a/Tests/ExtraRulesTests/BUILD b/Tests/ExtraRulesTests/BUILD index ec4ecf3fee..327de99660 100644 --- a/Tests/ExtraRulesTests/BUILD +++ b/Tests/ExtraRulesTests/BUILD @@ -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"], diff --git a/Tests/ExtraRulesTests/ExtraRulesTests.swift b/Tests/ExtraRulesTests/ExtraRulesTests.swift index 6f063f8fc1..4b83bffe9f 100644 --- a/Tests/ExtraRulesTests/ExtraRulesTests.swift +++ b/Tests/ExtraRulesTests/ExtraRulesTests.swift @@ -1,16 +1,14 @@ -@testable import SwiftLintExtraRules import TestHelpers +import Testing + +@testable import SwiftLintExtraRules -final class ExtraRulesTests: SwiftLintTestCase, @unchecked Sendable { - func testWithDefaultConfiguration() { +@Suite +struct ExtraRulesTests { + @Test + func withDefaultConfiguration() { for ruleType in extraRules() { verifyRule(ruleType.description) } } } - -extension ExtraRulesTests { - static var allTests: [(String, (ExtraRulesTests) -> () throws -> Void)] { - [("testWithDefaultConfiguration", testWithDefaultConfiguration)] - } -} diff --git a/Tests/FileSystemAccessTests/BaselineTests.swift b/Tests/FileSystemAccessTests/BaselineTests.swift index cbaef347d2..51033b3586 100644 --- a/Tests/FileSystemAccessTests/BaselineTests.swift +++ b/Tests/FileSystemAccessTests/BaselineTests.swift @@ -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 - -#if os(macOS) - return "/private" + result -#else - return result -#endif -} +// swiftlint:disable:next blanket_disable_command +// swiftlint:disable contains_over_filter_is_empty -final class BaselineTests: XCTestCase { +extension FileSystemAccessTestSuite.BaselineTests { private static let example = """ - import Foundation - import SwiftLintFramework - - 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 - } - """ + import Foundation + import SwiftLintFramework + + 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 + } + """ 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.. 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) ?? [] diff --git a/Tests/FileSystemAccessTests/ConfigurationTests+Constants.swift b/Tests/FileSystemAccessTests/ConfigurationTests+Constants.swift new file mode 100644 index 0000000000..b6455dc3fb --- /dev/null +++ b/Tests/FileSystemAccessTests/ConfigurationTests+Constants.swift @@ -0,0 +1,84 @@ +import SwiftLintFramework +import TestHelpers + +enum Constants { + // MARK: Test Resources Path + static let testResourcesPath: String = TestResources.path() + + // MARK: Directory Paths + enum Dir { + static var level0: String { testResourcesPath.stringByAppendingPathComponent("ProjectMock") } + static var level1: String { level0.stringByAppendingPathComponent("Level1") } + static var level2: String { level1.stringByAppendingPathComponent("Level2") } + static var level3: String { level2.stringByAppendingPathComponent("Level3") } + static var nested: String { level0.stringByAppendingPathComponent("NestedConfig/Test") } + static var nestedSub: String { nested.stringByAppendingPathComponent("Sub") } + static var childConfigTest1: String { level0.stringByAppendingPathComponent("ChildConfig/Test1/Main") } + static var childConfigTest2: String { level0.stringByAppendingPathComponent("ChildConfig/Test2") } + static var childConfigCycle1: String { level0.stringByAppendingPathComponent("ChildConfig/Cycle1") } + static var childConfigCycle2: String { level0.stringByAppendingPathComponent("ChildConfig/Cycle2") } + static var childConfigCycle3: String { level0.stringByAppendingPathComponent("ChildConfig/Cycle3/Main") } + static var childConfigCycle4: String { level0.stringByAppendingPathComponent("ChildConfig/Cycle4") } + static var parentConfigTest1: String { level0.stringByAppendingPathComponent("ParentConfig/Test1") } + static var parentConfigTest2: String { level0.stringByAppendingPathComponent("ParentConfig/Test2") } + static var parentConfigCycle1: String { level0.stringByAppendingPathComponent("ParentConfig/Cycle1") } + static var parentConfigCycle2: String { level0.stringByAppendingPathComponent("ParentConfig/Cycle2") } + static var parentConfigCycle3: String { level0.stringByAppendingPathComponent("ParentConfig/Cycle3") } + static var remoteConfigChild: String { level0.stringByAppendingPathComponent("RemoteConfig/Child") } + static var remoteConfigParent: String { level0.stringByAppendingPathComponent("RemoteConfig/Parent") } + static var remoteConfigLocalRef: String { level0.stringByAppendingPathComponent("RemoteConfig/LocalRef") } + static var remoteConfigCycle: String { level0.stringByAppendingPathComponent("RemoteConfig/Cycle") } + static var emptyFolder: String { level0.stringByAppendingPathComponent("EmptyFolder") } + } + + // swiftlint:disable identifier_name + + // MARK: YAML File Paths + enum Yml { + static var _0: String { Dir.level0.stringByAppendingPathComponent(Configuration.defaultFileName) } + static var _0Custom: String { Dir.level0.stringByAppendingPathComponent("custom.yml") } + static var _0CustomRules: String { Dir.level0.stringByAppendingPathComponent("custom_rules.yml") } + static var _0CustomRulesOnly: String { Dir.level0.stringByAppendingPathComponent("custom_rules_only.yml") } + static var _2: String { Dir.level2.stringByAppendingPathComponent(Configuration.defaultFileName) } + static var _2CustomRules: String { Dir.level2.stringByAppendingPathComponent("custom_rules.yml") } + static var _2CustomRulesOnly: String { Dir.level2.stringByAppendingPathComponent("custom_rules_only.yml") } + static var _2CustomRulesDisabled: String { + Dir.level2.stringByAppendingPathComponent("custom_rules_disabled.yml") + } + static var _2CustomRulesReconfig: String { + Dir.level2.stringByAppendingPathComponent("custom_rules_reconfig.yml") + } + static var _3: String { Dir.level3.stringByAppendingPathComponent(Configuration.defaultFileName) } + static var nested: String { Dir.nested.stringByAppendingPathComponent(Configuration.defaultFileName) } + } + + // MARK: Swift File Paths + enum Swift { + static var _0: String { Dir.level0.stringByAppendingPathComponent("Level0.swift") } + static var _1: String { Dir.level1.stringByAppendingPathComponent("Level1.swift") } + static var _2: String { Dir.level2.stringByAppendingPathComponent("Level2.swift") } + static var _3: String { Dir.level3.stringByAppendingPathComponent("Level3.swift") } + static var nestedSub: String { Dir.nestedSub.stringByAppendingPathComponent("Sub.swift") } + } + + // MARK: Configurations + enum Config { + static var _0: Configuration { Configuration(configurationFiles: []) } + static var _0Custom: Configuration { Configuration(configurationFiles: [Yml._0Custom]) } + static var _0CustomRules: Configuration { Configuration(configurationFiles: [Yml._0CustomRules]) } + static var _0CustomRulesOnly: Configuration { Configuration(configurationFiles: [Yml._0CustomRulesOnly]) } + static var _2: Configuration { Configuration(configurationFiles: [Yml._2]) } + static var _2CustomRules: Configuration { Configuration(configurationFiles: [Yml._2CustomRules]) } + static var _2CustomRulesOnly: Configuration { Configuration(configurationFiles: [Yml._2CustomRulesOnly]) } + static var _2CustomRulesDisabled: Configuration { + Configuration(configurationFiles: [Yml._2CustomRulesDisabled]) + } + static var _2CustomRulesReconfig: Configuration { + Configuration(configurationFiles: [Yml._2CustomRulesReconfig]) + } + static var _3: Configuration { Configuration(configurationFiles: [Yml._3]) } + static var nested: Configuration { Configuration(configurationFiles: [Yml.nested]) } + } + + // swiftlint:enable identifier_name +} diff --git a/Tests/FileSystemAccessTests/ConfigurationTests+Mock.swift b/Tests/FileSystemAccessTests/ConfigurationTests+Mock.swift deleted file mode 100644 index e4b6cfce41..0000000000 --- a/Tests/FileSystemAccessTests/ConfigurationTests+Mock.swift +++ /dev/null @@ -1,85 +0,0 @@ -import SwiftLintFramework -import TestHelpers - -// swiftlint:disable:next blanket_disable_command -// swiftlint:disable nesting identifier_name - -internal extension ConfigurationTests { - enum Mock { - // MARK: Test Resources Path - static let testResourcesPath: String = TestResources.path() - - // MARK: Directory Paths - enum Dir { - static var level0: String { testResourcesPath.stringByAppendingPathComponent("ProjectMock") } - static var level1: String { level0.stringByAppendingPathComponent("Level1") } - static var level2: String { level1.stringByAppendingPathComponent("Level2") } - static var level3: String { level2.stringByAppendingPathComponent("Level3") } - static var nested: String { level0.stringByAppendingPathComponent("NestedConfig/Test") } - static var nestedSub: String { nested.stringByAppendingPathComponent("Sub") } - static var childConfigTest1: String { level0.stringByAppendingPathComponent("ChildConfig/Test1/Main") } - static var childConfigTest2: String { level0.stringByAppendingPathComponent("ChildConfig/Test2") } - static var childConfigCycle1: String { level0.stringByAppendingPathComponent("ChildConfig/Cycle1") } - static var childConfigCycle2: String { level0.stringByAppendingPathComponent("ChildConfig/Cycle2") } - static var childConfigCycle3: String { level0.stringByAppendingPathComponent("ChildConfig/Cycle3/Main") } - static var childConfigCycle4: String { level0.stringByAppendingPathComponent("ChildConfig/Cycle4") } - static var parentConfigTest1: String { level0.stringByAppendingPathComponent("ParentConfig/Test1") } - static var parentConfigTest2: String { level0.stringByAppendingPathComponent("ParentConfig/Test2") } - static var parentConfigCycle1: String { level0.stringByAppendingPathComponent("ParentConfig/Cycle1") } - static var parentConfigCycle2: String { level0.stringByAppendingPathComponent("ParentConfig/Cycle2") } - static var parentConfigCycle3: String { level0.stringByAppendingPathComponent("ParentConfig/Cycle3") } - static var remoteConfigChild: String { level0.stringByAppendingPathComponent("RemoteConfig/Child") } - static var remoteConfigParent: String { level0.stringByAppendingPathComponent("RemoteConfig/Parent") } - static var remoteConfigLocalRef: String { level0.stringByAppendingPathComponent("RemoteConfig/LocalRef") } - static var remoteConfigCycle: String { level0.stringByAppendingPathComponent("RemoteConfig/Cycle") } - static var emptyFolder: String { level0.stringByAppendingPathComponent("EmptyFolder") } - } - - // MARK: YAML File Paths - enum Yml { - static var _0: String { Dir.level0.stringByAppendingPathComponent(Configuration.defaultFileName) } - static var _0Custom: String { Dir.level0.stringByAppendingPathComponent("custom.yml") } - static var _0CustomRules: String { Dir.level0.stringByAppendingPathComponent("custom_rules.yml") } - static var _0CustomRulesOnly: String { Dir.level0.stringByAppendingPathComponent("custom_rules_only.yml") } - static var _2: String { Dir.level2.stringByAppendingPathComponent(Configuration.defaultFileName) } - static var _2CustomRules: String { Dir.level2.stringByAppendingPathComponent("custom_rules.yml") } - static var _2CustomRulesOnly: String { Dir.level2.stringByAppendingPathComponent("custom_rules_only.yml") } - static var _2CustomRulesDisabled: String { - Dir.level2.stringByAppendingPathComponent("custom_rules_disabled.yml") - } - static var _2CustomRulesReconfig: String { - Dir.level2.stringByAppendingPathComponent("custom_rules_reconfig.yml") - } - static var _3: String { Dir.level3.stringByAppendingPathComponent(Configuration.defaultFileName) } - static var nested: String { Dir.nested.stringByAppendingPathComponent(Configuration.defaultFileName) } - } - - // MARK: Swift File Paths - enum Swift { - static var _0: String { Dir.level0.stringByAppendingPathComponent("Level0.swift") } - static var _1: String { Dir.level1.stringByAppendingPathComponent("Level1.swift") } - static var _2: String { Dir.level2.stringByAppendingPathComponent("Level2.swift") } - static var _3: String { Dir.level3.stringByAppendingPathComponent("Level3.swift") } - static var nestedSub: String { Dir.nestedSub.stringByAppendingPathComponent("Sub.swift") } - } - - // MARK: Configurations - enum Config { - static var _0: Configuration { Configuration(configurationFiles: []) } - static var _0Custom: Configuration { Configuration(configurationFiles: [Yml._0Custom]) } - static var _0CustomRules: Configuration { Configuration(configurationFiles: [Yml._0CustomRules]) } - static var _0CustomRulesOnly: Configuration { Configuration(configurationFiles: [Yml._0CustomRulesOnly]) } - static var _2: Configuration { Configuration(configurationFiles: [Yml._2]) } - static var _2CustomRules: Configuration { Configuration(configurationFiles: [Yml._2CustomRules]) } - static var _2CustomRulesOnly: Configuration { Configuration(configurationFiles: [Yml._2CustomRulesOnly]) } - static var _2CustomRulesDisabled: Configuration { - Configuration(configurationFiles: [Yml._2CustomRulesDisabled]) - } - static var _2CustomRulesReconfig: Configuration { - Configuration(configurationFiles: [Yml._2CustomRulesReconfig]) - } - static var _3: Configuration { Configuration(configurationFiles: [Yml._3]) } - static var nested: Configuration { Configuration(configurationFiles: [Yml.nested]) } - } - } -} diff --git a/Tests/FileSystemAccessTests/ConfigurationTests+MultipleConfigs.swift b/Tests/FileSystemAccessTests/ConfigurationTests+MultipleConfigs.swift index 937647187b..74253b6225 100644 --- a/Tests/FileSystemAccessTests/ConfigurationTests+MultipleConfigs.swift +++ b/Tests/FileSystemAccessTests/ConfigurationTests+MultipleConfigs.swift @@ -1,5 +1,6 @@ +import Foundation import TestHelpers -import XCTest +import Testing @testable import SwiftLintBuiltInRules @testable import SwiftLintFramework @@ -13,47 +14,46 @@ private extension Configuration { } // swiftlint:disable:next type_body_length -extension ConfigurationTests { +extension FileSystemAccessTestSuite.ConfigurationTests { // MARK: - Rules Merging - func testMerge() { - let config0Merge2 = Mock.Config._0.merged(withChild: Mock.Config._2) + @Test + @WorkingDirectory(path: Constants.Dir.level0) + func merge() { + let config0Merge2 = Constants.Config._0.merged(withChild: Constants.Config._2) - XCTAssertFalse(Mock.Config._0.contains(rule: ForceCastRule.self)) - XCTAssertTrue(Mock.Config._2.contains(rule: ForceCastRule.self)) - XCTAssertFalse(config0Merge2.contains(rule: ForceCastRule.self)) + #expect(!Constants.Config._0.contains(rule: ForceCastRule.self)) + #expect(Constants.Config._2.contains(rule: ForceCastRule.self)) + #expect(!config0Merge2.contains(rule: ForceCastRule.self)) - XCTAssertTrue(Mock.Config._0.contains(rule: TodoRule.self)) - XCTAssertTrue(Mock.Config._2.contains(rule: TodoRule.self)) - XCTAssertTrue(config0Merge2.contains(rule: TodoRule.self)) + #expect(Constants.Config._0.contains(rule: TodoRule.self)) + #expect(Constants.Config._2.contains(rule: TodoRule.self)) + #expect(config0Merge2.contains(rule: TodoRule.self)) - XCTAssertFalse(Mock.Config._3.contains(rule: TodoRule.self)) - XCTAssertFalse( - config0Merge2.merged(withChild: Mock.Config._3).contains(rule: TodoRule.self) - ) + #expect(!Constants.Config._3.contains(rule: TodoRule.self)) + #expect(!config0Merge2.merged(withChild: Constants.Config._3).contains(rule: TodoRule.self)) } // MARK: - Merging Aspects - func testWarningThresholdMerging() { + @Test + func warningThresholdMerging() { func configuration(forWarningThreshold warningThreshold: Int?) -> Configuration { Configuration( warningThreshold: warningThreshold, reporter: XcodeReporter.identifier ) } - XCTAssertEqual(configuration(forWarningThreshold: 3) - .merged(withChild: configuration(forWarningThreshold: 2)).warningThreshold, - 2) - XCTAssertEqual(configuration(forWarningThreshold: nil) - .merged(withChild: configuration(forWarningThreshold: 2)).warningThreshold, - 2) - XCTAssertEqual(configuration(forWarningThreshold: 3) - .merged(withChild: configuration(forWarningThreshold: nil)).warningThreshold, - 3) - XCTAssertNil(configuration(forWarningThreshold: nil) - .merged(withChild: configuration(forWarningThreshold: nil)).warningThreshold) - } - - func testOnlyRulesMerging() { + #expect(configuration(forWarningThreshold: 3) + .merged(withChild: configuration(forWarningThreshold: 2)).warningThreshold == 2) + #expect(configuration(forWarningThreshold: nil) + .merged(withChild: configuration(forWarningThreshold: 2)).warningThreshold == 2) + #expect(configuration(forWarningThreshold: 3) + .merged(withChild: configuration(forWarningThreshold: nil)).warningThreshold == 3) + #expect(configuration(forWarningThreshold: nil) + .merged(withChild: configuration(forWarningThreshold: nil)).warningThreshold == nil) + } + + @Test + func onlyRulesMerging() { let baseConfiguration = Configuration( rulesMode: .defaultConfiguration( disabled: [], @@ -64,260 +64,250 @@ extension ConfigurationTests { ) ) let onlyConfiguration = Configuration(rulesMode: .onlyConfiguration([TodoRule.identifier])) - XCTAssertTrue(baseConfiguration.contains(rule: TodoRule.self)) - XCTAssertEqual(onlyConfiguration.rules.count, 1) - XCTAssertTrue(onlyConfiguration.rules[0] is TodoRule) + #expect(baseConfiguration.contains(rule: TodoRule.self)) + #expect(onlyConfiguration.rules.count == 1) + #expect(onlyConfiguration.rules.first is TodoRule) let mergedConfiguration1 = baseConfiguration.merged(withChild: onlyConfiguration) - XCTAssertEqual(mergedConfiguration1.rules.count, 1) - XCTAssertTrue(mergedConfiguration1.rules[0] is TodoRule) + #expect(mergedConfiguration1.rules.count == 1) + #expect(mergedConfiguration1.rules.first is TodoRule) // Also test the other way around let mergedConfiguration2 = onlyConfiguration.merged(withChild: baseConfiguration) - XCTAssertEqual(mergedConfiguration2.rules.count, 3) // 2 opt-ins + 1 from the only rules - XCTAssertTrue(mergedConfiguration2.contains(rule: TodoRule.self)) - XCTAssertTrue(mergedConfiguration2.contains(rule: ForceCastRule.self)) - XCTAssertTrue(mergedConfiguration2.contains(rule: ForceTryRule.self)) + #expect(mergedConfiguration2.rules.count == 3) // 2 opt-ins + 1 from the only rules + #expect(mergedConfiguration2.contains(rule: TodoRule.self)) + #expect(mergedConfiguration2.contains(rule: ForceCastRule.self)) + #expect(mergedConfiguration2.contains(rule: ForceTryRule.self)) } - func testOnlyRuleMerging() { + @Test + func onlyRuleMerging() { let ruleIdentifier = TodoRule.identifier let onlyRuleConfiguration = Configuration.onlyRuleConfiguration(ruleIdentifier) let emptyDefaultConfiguration = Configuration.emptyDefaultConfiguration() let mergedConfiguration1 = onlyRuleConfiguration.merged(withChild: emptyDefaultConfiguration) - XCTAssertEqual(mergedConfiguration1.rules.count, 1) - XCTAssertTrue(mergedConfiguration1.rules[0] is TodoRule) + #expect(mergedConfiguration1.rules.count == 1) + #expect(mergedConfiguration1.rules.first is TodoRule) let disabledDefaultConfiguration = Configuration.disabledDefaultConfiguration(ruleIdentifier) let mergedConfiguration2 = onlyRuleConfiguration.merged(withChild: disabledDefaultConfiguration) - XCTAssertTrue(mergedConfiguration2.rules.isEmpty) + #expect(mergedConfiguration2.rules.isEmpty) let enabledOnlyConfiguration = Configuration.enabledOnlyConfiguration(ForceTryRule.identifier) let mergedConfiguration3 = onlyRuleConfiguration.merged(withChild: enabledOnlyConfiguration) - XCTAssertEqual(mergedConfiguration3.rules.count, 1) - XCTAssertTrue(mergedConfiguration3.rules[0] is TodoRule) + #expect(mergedConfiguration3.rules.count == 1) + #expect(mergedConfiguration3.rules.first is TodoRule) } - func testCustomRulesMerging() { - let mergedConfiguration = Mock.Config._0CustomRules.merged( - withChild: Mock.Config._2CustomRules, + @Test + func customRulesMerging() { + let mergedConfiguration = Constants.Config._0CustomRules.merged( + withChild: Constants.Config._2CustomRules, rootDirectory: "" ) guard let mergedCustomRules = mergedConfiguration.rules.customRules else { - XCTFail("Custom rules are expected to be present") + Issue.record("Custom rules are expected to be present") return } - XCTAssertTrue( + #expect( mergedCustomRules.configuration.customRuleConfigurations.contains { $0.identifier == "no_abc" } ) - XCTAssertTrue( + #expect( mergedCustomRules.configuration.customRuleConfigurations.contains { $0.identifier == "no_abcd" } ) } - func testMergingAllowsDisablingParentsCustomRules() { - let mergedConfiguration = Mock.Config._0CustomRules.merged( - withChild: Mock.Config._2CustomRulesDisabled, + @Test + func mergingAllowsDisablingParentsCustomRules() { + let mergedConfiguration = Constants.Config._0CustomRules.merged( + withChild: Constants.Config._2CustomRulesDisabled, rootDirectory: "" ) guard let mergedCustomRules = mergedConfiguration.rules.customRules else { - XCTFail("Custom rules are expected to be present") + Issue.record("Custom rules are expected to be present") return } - XCTAssertFalse( - mergedCustomRules.configuration.customRuleConfigurations.contains { $0.identifier == "no_abc" } - ) - XCTAssertTrue( - mergedCustomRules.configuration.customRuleConfigurations.contains { $0.identifier == "no_abcd" } - ) + #expect(!mergedCustomRules.configuration.customRuleConfigurations.contains { $0.identifier == "no_abc" }) + #expect(mergedCustomRules.configuration.customRuleConfigurations.contains { $0.identifier == "no_abcd" }) } - func testCustomRulesMergingWithOnlyRulesCase1() { + @Test + func customRulesMergingWithOnlyRulesCase1() { // The base configuration is in only rules mode // The child configuration is in the default rules mode // => all custom rules should be considered - let mergedConfiguration = Mock.Config._0CustomRulesOnly.merged( - withChild: Mock.Config._2CustomRules, + let mergedConfiguration = Constants.Config._0CustomRulesOnly.merged( + withChild: Constants.Config._2CustomRules, rootDirectory: "" ) guard let mergedCustomRules = mergedConfiguration.rules.customRules else { - XCTFail("Custom rules are expected to be present") + Issue.record("Custom rules are expected to be present") return } - XCTAssertTrue( + #expect( mergedCustomRules.configuration.customRuleConfigurations.contains { $0.identifier == "no_abc" } ) - XCTAssertTrue( + #expect( mergedCustomRules.configuration.customRuleConfigurations.contains { $0.identifier == "no_abcd" } ) } - func testCustomRulesMergingWithOnlyRulesCase2() { + @Test + func customRulesMergingWithOnlyRulesCase2() { // The base configuration is in only rules mode // The child configuration is in the only rules mode // => only the custom rules from the child configuration should be considered // (because custom rules from base configuration would require explicit mention as one of the `only_rules`) - let mergedConfiguration = Mock.Config._0CustomRulesOnly.merged( - withChild: Mock.Config._2CustomRulesOnly, + let mergedConfiguration = Constants.Config._0CustomRulesOnly.merged( + withChild: Constants.Config._2CustomRulesOnly, rootDirectory: "" ) guard let mergedCustomRules = mergedConfiguration.rules.customRules else { - XCTFail("Custom rules are expected to be present") + Issue.record("Custom rules are expected to be present") return } - XCTAssertFalse( - mergedCustomRules.configuration.customRuleConfigurations.contains { $0.identifier == "no_abc" } - ) - XCTAssertTrue( - mergedCustomRules.configuration.customRuleConfigurations.contains { $0.identifier == "no_abcd" } - ) + #expect(!mergedCustomRules.configuration.customRuleConfigurations.contains { $0.identifier == "no_abc" }) + #expect(mergedCustomRules.configuration.customRuleConfigurations.contains { $0.identifier == "no_abcd" }) } - func testCustomRulesReconfiguration() { + @Test + func customRulesReconfiguration() { // Custom Rule severity gets reconfigured to "error" - let mergedConfiguration = Mock.Config._0CustomRulesOnly.merged( - withChild: Mock.Config._2CustomRulesReconfig, + let mergedConfiguration = Constants.Config._0CustomRulesOnly.merged( + withChild: Constants.Config._2CustomRulesReconfig, rootDirectory: "" ) guard let mergedCustomRules = mergedConfiguration.rules.customRules else { - XCTFail("Custom rules are expected to be present") + Issue.record("Custom rules are expected to be present") return } - XCTAssertEqual( - mergedCustomRules.configuration.customRuleConfigurations.filter { $0.identifier == "no_abc" }.count, 1 + #expect( + mergedCustomRules.configuration.customRuleConfigurations.filter { $0.identifier == "no_abc" }.count == 1 ) guard let customRule = (mergedCustomRules.configuration.customRuleConfigurations.first { $0.identifier == "no_abc" }) else { - XCTFail("Custom rule is expected to be present") + Issue.record("Custom rule is expected to be present") return } - XCTAssertEqual(customRule.severityConfiguration.severity, .error) + #expect(customRule.severityConfiguration.severity == .error) } // MARK: - Nested Configurations - func testLevel0() { - XCTAssertEqual(Mock.Config._0.configuration(for: SwiftLintFile(path: Mock.Swift._0)!), - Mock.Config._0) + @Test + @WorkingDirectory(path: Constants.Dir.level0) + func level0() { + #expect(Constants.Config._0.configuration(for: SwiftLintFile(path: Constants.Swift._0)!) == Constants.Config._0) } - func testLevel1() { - XCTAssertEqual(Mock.Config._0.configuration(for: SwiftLintFile(path: Mock.Swift._1)!), - Mock.Config._0) + @Test + @WorkingDirectory(path: Constants.Dir.level0) + func level1() { + #expect(Constants.Config._0.configuration(for: SwiftLintFile(path: Constants.Swift._1)!) == Constants.Config._0) } - func testLevel2() { - let config = Mock.Config._0.configuration(for: SwiftLintFile(path: Mock.Swift._2)!) - var config2 = Mock.Config._2 - config2.fileGraph = Configuration.FileGraph(rootDirectory: Mock.Dir.level2) + @Test + func level2() { + let config = Constants.Config._0.configuration(for: SwiftLintFile(path: Constants.Swift._2)!) + var config2 = Constants.Config._2 + config2.fileGraph = Configuration.FileGraph(rootDirectory: Constants.Dir.level2) - XCTAssertEqual( - config, - Mock.Config._0.merged(withChild: config2, rootDirectory: config.rootDirectory) - ) + #expect(config == Constants.Config._0.merged(withChild: config2, rootDirectory: config.rootDirectory)) } - func testLevel3() { - let config = Mock.Config._0.configuration(for: SwiftLintFile(path: Mock.Swift._3)!) - var config3 = Mock.Config._3 - config3.fileGraph = Configuration.FileGraph(rootDirectory: Mock.Dir.level3) + @Test + func level3() { + let config = Constants.Config._0.configuration(for: SwiftLintFile(path: Constants.Swift._3)!) + var config3 = Constants.Config._3 + config3.fileGraph = Configuration.FileGraph(rootDirectory: Constants.Dir.level3) - XCTAssertEqual( - config, - Mock.Config._0.merged(withChild: config3, rootDirectory: config.rootDirectory) - ) + #expect(config == Constants.Config._0.merged(withChild: config3, rootDirectory: config.rootDirectory)) } - func testNestedConfigurationForOnePathPassedIn() { + @Test + func nestedConfigurationForOnePathPassedIn() { // If a path to one or more configuration files is specified, nested configurations should be ignored - let config = Configuration(configurationFiles: [Mock.Yml._0]) - XCTAssertEqual( - config.configuration(for: SwiftLintFile(path: Mock.Swift._3)!), - config - ) + let config = Configuration(configurationFiles: [Constants.Yml._0]) + #expect(config.configuration(for: SwiftLintFile(path: Constants.Swift._3)!) == config) } - func testParentConfigIsIgnoredAsNestedConfiguration() { + @Test + func parentConfigIsIgnoredAsNestedConfiguration() { // If a configuration has already been used to build the main config, // it should not again be regarded as a nested config - XCTAssertEqual( - Mock.Config.nested.configuration(for: SwiftLintFile(path: Mock.Swift.nestedSub)!), - Mock.Config.nested + #expect( + Constants.Config.nested.configuration(for: SwiftLintFile(path: Constants.Swift.nestedSub)!) + == Constants.Config.nested ) } // MARK: - Child & Parent Configs - func testValidChildConfig() { - guard !isRunningWithBazel else { - return - } - - for path in [Mock.Dir.childConfigTest1, Mock.Dir.childConfigTest2] { - XCTAssert(FileManager.default.changeCurrentDirectoryPath(path)) + @Test( + .disabled(if: isRunningWithBazel), + arguments: [Constants.Dir.childConfigTest1, Constants.Dir.childConfigTest2], + ) + @WorkingDirectory(path: Constants.Dir.emptyFolder) + func validChildConfig(_ path: String) { + #expect(FileManager.default.changeCurrentDirectoryPath(path)) - assertEqualExceptForFileGraph( - Configuration(configurationFiles: ["main.yml"]), - Configuration(configurationFiles: ["expected.yml"]) - ) - } + assertEqualExceptForFileGraph( + Configuration(configurationFiles: ["main.yml"]), + Configuration(configurationFiles: ["expected.yml"]) + ) } - func testValidParentConfig() { - for path in [Mock.Dir.parentConfigTest1, Mock.Dir.parentConfigTest2] { - XCTAssert(FileManager.default.changeCurrentDirectoryPath(path)) + @Test(arguments: [Constants.Dir.parentConfigTest1, Constants.Dir.parentConfigTest2]) + @WorkingDirectory(path: Constants.Dir.emptyFolder) + func validParentConfig(_ path: String) { + #expect(FileManager.default.changeCurrentDirectoryPath(path)) - assertEqualExceptForFileGraph( - Configuration(configurationFiles: ["main.yml"]), - Configuration(configurationFiles: ["expected.yml"]) - ) - } + assertEqualExceptForFileGraph( + Configuration(configurationFiles: ["main.yml"]), + Configuration(configurationFiles: ["expected.yml"]) + ) } - func testCommandLineChildConfigs() { - guard !isRunningWithBazel else { - return - } + @Test( + .disabled(if: isRunningWithBazel), + arguments: [Constants.Dir.childConfigTest1, Constants.Dir.childConfigTest2], + ) + @WorkingDirectory(path: Constants.Dir.emptyFolder) + func commandLineChildConfigs(_ path: String) { + #expect(FileManager.default.changeCurrentDirectoryPath(path)) - for path in [Mock.Dir.childConfigTest1, Mock.Dir.childConfigTest2] { - XCTAssert(FileManager.default.changeCurrentDirectoryPath(path)) - - assertEqualExceptForFileGraph( - Configuration( - configurationFiles: ["main.yml", "child1.yml", "child2.yml"] - ), - Configuration(configurationFiles: ["expected.yml"]) - ) - } + assertEqualExceptForFileGraph( + Configuration(configurationFiles: ["main.yml", "child1.yml", "child2.yml"]), + Configuration(configurationFiles: ["expected.yml"]) + ) } - func testConfigCycleDetection() { - for path in [ - Mock.Dir.childConfigCycle1, - Mock.Dir.childConfigCycle2, - Mock.Dir.childConfigCycle3, - Mock.Dir.parentConfigCycle1, - Mock.Dir.parentConfigCycle2, - Mock.Dir.parentConfigCycle3, - ] { - XCTAssert(FileManager.default.changeCurrentDirectoryPath(path)) - - // If the cycle is properly detected, the config should equal the default config. - XCTAssertEqual( - Configuration(configurationFiles: []), // not specifying a file means the .swiftlint.yml will be used - Configuration() - ) - } - } + @Test( + arguments: [ + Constants.Dir.childConfigCycle1, + Constants.Dir.childConfigCycle2, + Constants.Dir.childConfigCycle3, + Constants.Dir.parentConfigCycle1, + Constants.Dir.parentConfigCycle2, + Constants.Dir.parentConfigCycle3, + ], + ) + @WorkingDirectory(path: Constants.Dir.emptyFolder) + func configCycleDetection(_ path: String) { + #expect(FileManager.default.changeCurrentDirectoryPath(path)) - func testCommandLineConfigsCycleDetection() { - XCTAssert(FileManager.default.changeCurrentDirectoryPath(Mock.Dir.childConfigCycle4)) + // If the cycle is properly detected, the config should equal the default config. + #expect(Configuration(configurationFiles: []) == Configuration()) + } + @Test + @WorkingDirectory(path: Constants.Dir.childConfigCycle4) + func commandLineConfigsCycleDetection() { // If the cycle is properly detected, the config should equal the default config. assertEqualExceptForFileGraph( Configuration( @@ -328,7 +318,8 @@ extension ConfigurationTests { ) } - func testParentChildOptInAndDisable() { + @Test + func parentChildOptInAndDisable() { struct TestCase: Equatable { let optedInInParent: Bool let disabledInParent: Bool @@ -362,9 +353,9 @@ extension ConfigurationTests { TestCase(optedInInParent: true, disabledInParent: true, optedInInChild: true, disabledInChild: true, isEnabled: false), // swiftlint:enable line_length ] - XCTAssertEqual(testCases.unique.count, 4 * 4) + #expect(testCases.unique.count == 4 * 4) let ruleType = ImplicitReturnRule.self - XCTAssertTrue((ruleType as Any) is any OptInRule.Type) + #expect((ruleType as Any) is any OptInRule.Type) let ruleIdentifier = ruleType.identifier for testCase in testCases { let parentConfiguration = Configuration(rulesMode: .defaultConfiguration( @@ -377,11 +368,12 @@ extension ConfigurationTests { )) let mergedConfiguration = parentConfiguration.merged(withChild: childConfiguration) let isEnabled = mergedConfiguration.contains(rule: ruleType) - XCTAssertEqual(isEnabled, testCase.isEnabled, testCase.message) + #expect(isEnabled == testCase.isEnabled, Comment(rawValue: testCase.message)) } } - func testParentChildDisableForDefaultRule() { + @Test + func parentChildDisableForDefaultRule() { struct TestCase: Equatable { let disabledInParent: Bool let disabledInChild: Bool @@ -396,9 +388,9 @@ extension ConfigurationTests { TestCase(disabledInParent: false, disabledInChild: true, isEnabled: false), TestCase(disabledInParent: true, disabledInChild: true, isEnabled: false), ] - XCTAssertEqual(testCases.unique.count, 2 * 2) + #expect(testCases.unique.count == 2 * 2) let ruleType = BlanketDisableCommandRule.self - XCTAssertFalse(ruleType is any OptInRule.Type) + #expect(!(ruleType is any OptInRule.Type)) let ruleIdentifier = ruleType.identifier for testCase in testCases { let parentConfiguration = Configuration( @@ -409,11 +401,12 @@ extension ConfigurationTests { ) let mergedConfiguration = parentConfiguration.merged(withChild: childConfiguration) let isEnabled = mergedConfiguration.contains(rule: ruleType) - XCTAssertEqual(isEnabled, testCase.isEnabled, testCase.message) + #expect(isEnabled == testCase.isEnabled, Comment(rawValue: testCase.message)) } } - func testParentOnlyRulesAndChildOptInAndDisabled() { + @Test + func parentOnlyRulesAndChildOptInAndDisabled() { struct TestCase: Equatable { let optedInInChild: Bool let disabledInChild: Bool @@ -428,9 +421,9 @@ extension ConfigurationTests { TestCase(optedInInChild: false, disabledInChild: true, isEnabled: false), TestCase(optedInInChild: true, disabledInChild: true, isEnabled: false), ] - XCTAssertEqual(testCases.unique.count, 2 * 2) + #expect(testCases.unique.count == 2 * 2) let ruleType = ImplicitReturnRule.self - XCTAssertTrue((ruleType as Any) is any OptInRule.Type) + #expect((ruleType as Any) is any OptInRule.Type) let ruleIdentifier = ruleType.identifier let parentConfiguration = Configuration(rulesMode: .onlyConfiguration([ruleIdentifier])) for testCase in testCases { @@ -440,18 +433,19 @@ extension ConfigurationTests { )) let mergedConfiguration = parentConfiguration.merged(withChild: childConfiguration) let isEnabled = mergedConfiguration.contains(rule: ruleType) - XCTAssertEqual(isEnabled, testCase.isEnabled, testCase.message) + #expect(isEnabled == testCase.isEnabled, Comment(rawValue: testCase.message)) } } // MARK: Warnings about configurations for disabled rules - func testDefaultConfigurationDisabledRuleWarnings() { + @Test + func defaultConfigurationDisabledRuleWarnings() { let optInRuleType = ImplicitReturnRule.self - XCTAssertTrue((optInRuleType as Any) is any OptInRule.Type) + #expect((optInRuleType as Any) is any OptInRule.Type) testDefaultConfigurationDisabledRuleWarnings(for: optInRuleType) let defaultRuleType = BlockBasedKVORule.self - XCTAssertFalse((defaultRuleType as Any) is any OptInRule.Type) + #expect(!((defaultRuleType as Any) is any OptInRule.Type)) testDefaultConfigurationDisabledRuleWarnings(for: defaultRuleType) } @@ -489,7 +483,7 @@ extension ConfigurationTests { ruleType: any Rule.Type ) { guard case .defaultConfiguration(let disabledRules, let optInRules) = configuration.rulesMode else { - XCTFail("Configuration rulesMode was not the default") + Issue.record("Configuration rulesMode was not the default") return } @@ -501,54 +495,55 @@ extension ConfigurationTests { optInRules: optInRules, ruleType: ruleType ) - XCTAssertEqual(isEnabled, issue == nil) + #expect(isEnabled == (issue == nil)) guard let issue else { return } let ruleIdentifier = ruleType.identifier guard disabledRules.isEmpty, optInRules.isEmpty else { - XCTAssertEqual(issue, Issue.ruleDisabledInDisabledRules(ruleID: ruleIdentifier)) + #expect(issue == Issue.ruleDisabledInDisabledRules(ruleID: ruleIdentifier)) return } if parentConfiguration == nil || parentConfiguration == Configuration.emptyDefaultConfiguration() { - XCTAssertEqual(issue, Issue.ruleNotEnabledInOptInRules(ruleID: ruleIdentifier)) + #expect(issue == Issue.ruleNotEnabledInOptInRules(ruleID: ruleIdentifier)) } else if parentConfiguration == Configuration.emptyOnlyConfiguration() { if ruleType is any OptInRule.Type { - XCTAssertEqual(issue, Issue.ruleNotEnabledInOptInRules(ruleID: ruleIdentifier)) + #expect(issue == Issue.ruleNotEnabledInOptInRules(ruleID: ruleIdentifier)) } else { - XCTAssertEqual(issue, Issue.ruleNotEnabledInParentOnlyRules(ruleID: ruleIdentifier)) + #expect(issue == Issue.ruleNotEnabledInParentOnlyRules(ruleID: ruleIdentifier)) } } else if parentConfiguration == Configuration.optInDisabledDefaultConfiguration(ruleIdentifier) || parentConfiguration == Configuration.disabledDefaultConfiguration(ruleIdentifier) { - XCTAssertEqual(issue, Issue.ruleDisabledInParentConfiguration(ruleID: ruleIdentifier)) + #expect(issue == Issue.ruleDisabledInParentConfiguration(ruleID: ruleIdentifier)) } } - func testOnlyConfigurationDisabledRulesWarnings() { + @Test + func onlyConfigurationDisabledRulesWarnings() { let optInRuleType = ImplicitReturnRule.self - XCTAssertTrue((optInRuleType as Any) is any OptInRule.Type) + #expect((optInRuleType as Any) is any OptInRule.Type) testOnlyConfigurationDisabledRulesWarnings(ruleType: optInRuleType) let defaultRuleType = BlockBasedKVORule.self - XCTAssertFalse((defaultRuleType as Any) is any OptInRule.Type) + #expect(!((defaultRuleType as Any) is any OptInRule.Type)) testOnlyConfigurationDisabledRulesWarnings(ruleType: defaultRuleType) } private func testOnlyConfigurationDisabledRulesWarnings(ruleType: any Rule.Type) { let issue = Configuration.validateConfiguredRuleIsEnabled(onlyRules: [], ruleType: ruleType) - XCTAssertEqual(issue, Issue.ruleNotPresentInOnlyRules(ruleID: ruleType.identifier)) - XCTAssertNil( - Configuration.validateConfiguredRuleIsEnabled(onlyRules: [ruleType.identifier], ruleType: ruleType) + #expect(issue == Issue.ruleNotPresentInOnlyRules(ruleID: ruleType.identifier)) + #expect( + Configuration.validateConfiguredRuleIsEnabled(onlyRules: [ruleType.identifier], ruleType: ruleType) == nil ) } // MARK: - Remote Configs - func testValidRemoteChildConfig() { - XCTAssert(FileManager.default.changeCurrentDirectoryPath(Mock.Dir.remoteConfigChild)) - + @Test + @WorkingDirectory(path: Constants.Dir.remoteConfigChild) + func validRemoteChildConfig() { assertEqualExceptForFileGraph( Configuration( configurationFiles: ["main.yml"], @@ -565,9 +560,9 @@ extension ConfigurationTests { ) } - func testValidRemoteParentConfig() { - XCTAssert(FileManager.default.changeCurrentDirectoryPath(Mock.Dir.remoteConfigParent)) - + @Test + @WorkingDirectory(path: Constants.Dir.remoteConfigParent) + func validRemoteParentConfig() { assertEqualExceptForFileGraph( Configuration( configurationFiles: ["main.yml"], @@ -590,11 +585,11 @@ extension ConfigurationTests { ) } - func testsRemoteConfigNotAllowedToReferenceLocalConfig() { - XCTAssert(FileManager.default.changeCurrentDirectoryPath(Mock.Dir.remoteConfigLocalRef)) - + @Test + @WorkingDirectory(path: Constants.Dir.remoteConfigLocalRef) + func sRemoteConfigNotAllowedToReferenceLocalConfig() { // If the remote file is not allowed to reference a local file, the config should equal the default config. - XCTAssertEqual( + #expect( Configuration( configurationFiles: [], // not specifying a file means the .swiftlint.yml will be used mockedNetworkResults: [ @@ -605,16 +600,15 @@ extension ConfigurationTests { child_config: child2.yml """, ] - ), - Configuration() + ) == Configuration() ) } - func testRemoteConfigCycleDetection() { - XCTAssert(FileManager.default.changeCurrentDirectoryPath(Mock.Dir.remoteConfigCycle)) - + @Test + @WorkingDirectory(path: Constants.Dir.remoteConfigCycle) + func remoteConfigCycleDetection() { // If the cycle is properly detected, the config should equal the default config. - XCTAssertEqual( + #expect( Configuration( configurationFiles: [], // not specifying a file means the .swiftlint.yml will be used mockedNetworkResults: [ @@ -623,8 +617,7 @@ extension ConfigurationTests { child_config: https://www.mock.com """, ] - ), - Configuration() + ) == Configuration() ) } @@ -632,28 +625,21 @@ extension ConfigurationTests { /// This helper function checks whether two configurations are equal except for their file graph. /// This is needed to test a child/parent merged config against an expected config. func assertEqualExceptForFileGraph(_ configuration1: Configuration, _ configuration2: Configuration) { - XCTAssertEqual( - configuration1.rulesWrapper.disabledRuleIdentifiers, - configuration2.rulesWrapper.disabledRuleIdentifiers + #expect( + configuration1.rulesWrapper.disabledRuleIdentifiers == configuration2.rulesWrapper.disabledRuleIdentifiers ) - - XCTAssertEqual( - configuration1.rules.map { type(of: $0).identifier }, - configuration2.rules.map { type(of: $0).identifier } + #expect( + configuration1.rules.map { type(of: $0).identifier } == configuration2.rules.map { type(of: $0).identifier } ) - - XCTAssertEqual( + #expect( Set(configuration1.rulesWrapper.allRulesWrapped.map { $0.rule.createConfigurationDescription().oneLiner() - }), - Set(configuration2.rulesWrapper.allRulesWrapped.map { + }) == Set(configuration2.rulesWrapper.allRulesWrapped.map { $0.rule.createConfigurationDescription().oneLiner() }) ) - - XCTAssertEqual(Set(configuration1.includedPaths), Set(configuration2.includedPaths)) - - XCTAssertEqual(Set(configuration1.excludedPaths), Set(configuration2.excludedPaths)) + #expect(Set(configuration1.includedPaths) == Set(configuration2.includedPaths)) + #expect(Set(configuration1.excludedPaths) == Set(configuration2.excludedPaths)) } } diff --git a/Tests/FileSystemAccessTests/ConfigurationTests.swift b/Tests/FileSystemAccessTests/ConfigurationTests.swift index 7d13f14c4d..d63909889a 100644 --- a/Tests/FileSystemAccessTests/ConfigurationTests.swift +++ b/Tests/FileSystemAccessTests/ConfigurationTests.swift @@ -1,7 +1,7 @@ import Foundation import SourceKittenFramework import TestHelpers -import XCTest +import Testing @testable import SwiftLintFramework @@ -9,123 +9,107 @@ import XCTest private let optInRules = RuleRegistry.shared.list.list.filter({ $0.1.init() is any OptInRule }).map(\.0) -// swiftlint:disable:next type_body_length -final class ConfigurationTests: SwiftLintTestCase { - // MARK: Setup & Teardown - private var previousWorkingDir: String! // swiftlint:disable:this implicitly_unwrapped_optional - - override func setUp() { - super.setUp() - Configuration.resetCache() - previousWorkingDir = FileManager.default.currentDirectoryPath - XCTAssert(FileManager.default.changeCurrentDirectoryPath(Mock.Dir.level0)) - } - - override func tearDown() { - super.tearDown() - XCTAssert(FileManager.default.changeCurrentDirectoryPath(previousWorkingDir)) - } - - // MARK: Tests - func testInit() { - XCTAssertNotNil( - try? Configuration(dict: [:]), - "initializing Configuration with empty Dictionary should succeed" - ) - XCTAssertNotNil( - try? Configuration(dict: ["a": 1, "b": 2]), - "initializing Configuration with valid Dictionary should succeed" - ) +extension FileSystemAccessTestSuite.ConfigurationTests { // swiftlint:disable:this type_body_length + @Test + func basicInit() throws { + _ = try Configuration(dict: [:]) + _ = try Configuration(dict: ["a": 1, "b": 2]) } - func testNoConfiguration() { - // Change to a folder where there is no `.swiftlint.yml` - XCTAssert(FileManager.default.changeCurrentDirectoryPath(Mock.Dir.emptyFolder)) - - // Test whether the default configuration is used if there is no `.swiftlint.yml` or other config file - XCTAssertEqual(Configuration(configurationFiles: []), Configuration.default) + @Test + @WorkingDirectory(path: Constants.Dir.emptyFolder) + func useDefaultIfNoConfiguration() { + #expect(Configuration(configurationFiles: []) == Configuration.default) } - func testEmptyConfiguration() { + @Test + func emptyConfiguration() { guard let config = try? Configuration(dict: [:]) else { - XCTFail("empty YAML string should yield non-nil Configuration") + Issue.record("empty YAML string should yield non-nil Configuration") return } - XCTAssertEqual(config.rulesWrapper.disabledRuleIdentifiers, []) - XCTAssertEqual(config.includedPaths, []) - XCTAssertEqual(config.excludedPaths, []) - XCTAssertEqual(config.indentation, .spaces(count: 4)) - XCTAssertEqual(config.reporter, "xcode") - XCTAssertEqual(reporterFrom(identifier: config.reporter).identifier, "xcode") - XCTAssertFalse(config.allowZeroLintableFiles) - XCTAssertFalse(config.strict) - XCTAssertFalse(config.lenient) - XCTAssertNil(config.baseline) - XCTAssertNil(config.writeBaseline) - XCTAssertFalse(config.checkForUpdates) - } - - func testInitWithRelativePathAndRootPath() { - let expectedConfig = Mock.Config._0 + #expect(config.rulesWrapper.disabledRuleIdentifiers.isEmpty) + #expect(config.includedPaths.isEmpty) + #expect(config.excludedPaths.isEmpty) + #expect(config.indentation == .spaces(count: 4)) + #expect(config.reporter == "xcode") + #expect(reporterFrom(identifier: config.reporter).identifier == "xcode") + #expect(!config.allowZeroLintableFiles) + #expect(!config.strict) + #expect(!config.lenient) + #expect(config.baseline == nil) + #expect(config.writeBaseline == nil) + #expect(!config.checkForUpdates) + } + + @Test + @WorkingDirectory(path: Constants.Dir.level0) + func initWithRelativePathAndRootPath() { + let expectedConfig = Constants.Config._0 let config = Configuration(configurationFiles: [".swiftlint.yml"]) - XCTAssertEqual(config.rulesWrapper.disabledRuleIdentifiers, expectedConfig.rulesWrapper.disabledRuleIdentifiers) - XCTAssertEqual(config.includedPaths, expectedConfig.includedPaths) - XCTAssertEqual(config.excludedPaths, expectedConfig.excludedPaths) - XCTAssertEqual(config.indentation, expectedConfig.indentation) - XCTAssertEqual(config.reporter, expectedConfig.reporter) - XCTAssertTrue(config.allowZeroLintableFiles) - XCTAssertTrue(config.strict) - XCTAssertNotNil(config.baseline) - XCTAssertNotNil(config.writeBaseline) + #expect(config.rulesWrapper.disabledRuleIdentifiers == expectedConfig.rulesWrapper.disabledRuleIdentifiers) + #expect(config.includedPaths == expectedConfig.includedPaths) + #expect(config.excludedPaths == expectedConfig.excludedPaths) + #expect(config.indentation == expectedConfig.indentation) + #expect(config.reporter == expectedConfig.reporter) + #expect(config.allowZeroLintableFiles) + #expect(config.strict) + #expect(config.baseline != nil) + #expect(config.writeBaseline != nil) } - func testEnableAllRulesConfiguration() throws { + @Test + func enableAllRulesConfiguration() throws { let configuration = try Configuration( dict: [:], enableAllRules: true, cachePath: nil ) - XCTAssertEqual(configuration.rules.count, RuleRegistry.shared.list.list.count) + #expect(configuration.rules.count == RuleRegistry.shared.list.list.count) } - func testOnlyRule() throws { + @Test + func onlyRule() throws { let configuration = try Configuration( dict: [:], onlyRule: ["nesting"], cachePath: nil ) - XCTAssertEqual(configuration.rules.count, 1) + #expect(configuration.rules.count == 1) } - func testOnlyRuleMultiple() throws { + @Test + func onlyRuleMultiple() throws { let onlyRuleIdentifiers = ["nesting", "todo"].sorted() let configuration = try Configuration( dict: ["only_rules": "line_length"], onlyRule: onlyRuleIdentifiers, cachePath: nil ) - XCTAssertEqual(onlyRuleIdentifiers, configuration.enabledRuleIdentifiers) + #expect(onlyRuleIdentifiers == configuration.enabledRuleIdentifiers) let childConfiguration = try Configuration(dict: ["disabled_rules": onlyRuleIdentifiers.last ?? ""]) let mergedConfiguration = configuration.merged(withChild: childConfiguration) - XCTAssertEqual(onlyRuleIdentifiers.dropLast(), mergedConfiguration.enabledRuleIdentifiers) + #expect(onlyRuleIdentifiers.dropLast() == mergedConfiguration.enabledRuleIdentifiers) } - func testOnlyRules() throws { + @Test + func onlyRules() throws { let only = ["nesting", "todo"] let config = try Configuration(dict: ["only_rules": only]) let configuredIdentifiers = config.rules.map { type(of: $0).identifier }.sorted() - XCTAssertEqual(only, configuredIdentifiers) + #expect(only == configuredIdentifiers) } - func testOnlyRulesWithCustomRules() throws { + @Test + func onlyRulesWithCustomRules() throws { // All custom rules from a config file should be active if the `custom_rules` is included in the `only_rules` // As the behavior is different for custom rules from parent configs, this test is helpful let only = ["custom_rules"] @@ -134,17 +118,18 @@ final class ConfigurationTests: SwiftLintTestCase { let config = try Configuration(dict: ["only_rules": only, "custom_rules": customRules]) guard let resultingCustomRules = config.rules.customRules else { - XCTFail("Custom rules are expected to be present") + Issue.record("Custom rules are expected to be present") return } - XCTAssertTrue( + #expect( resultingCustomRules.configuration.customRuleConfigurations.contains { $0.identifier == customRuleIdentifier } ) } - func testOnlyRulesWithSpecificCustomRules() throws { + @Test + func onlyRulesWithSpecificCustomRules() throws { // Individual custom rules can be specified on the command line without specifying `custom_rules` as well. let customRuleIdentifier = "my_custom_rule" let customRuleIdentifier2 = "my_custom_rule2" @@ -162,26 +147,29 @@ final class ConfigurationTests: SwiftLintTestCase { onlyRule: [customRuleIdentifier] ) let resultingCustomRules = configuration.rules.customRules - XCTAssertNotNil(resultingCustomRules) + #expect(resultingCustomRules != nil) let enabledCustomRuleIdentifiers = resultingCustomRules?.configuration.customRuleConfigurations.map { rule in rule.identifier } - XCTAssertEqual(enabledCustomRuleIdentifiers, [customRuleIdentifier]) + #expect(enabledCustomRuleIdentifiers == [customRuleIdentifier]) } - func testWarningThreshold_value() throws { + @Test + func warningThreshold_value() throws { let config = try Configuration(dict: ["warning_threshold": 5]) - XCTAssertEqual(config.warningThreshold, 5) + #expect(config.warningThreshold == 5) } - func testWarningThreshold_nil() throws { + @Test + func warningThreshold_nil() throws { let config = try Configuration(dict: [:]) - XCTAssertNil(config.warningThreshold) + #expect(config.warningThreshold == nil) } - func testOtherRuleConfigurationsAlongsideOnlyRules() { + @Test + func otherRuleConfigurationsAlongsideOnlyRules() { let only = ["nesting", "todo"] let enabledRulesConfigDict = [ "opt_in_rules": ["line_length"], @@ -193,95 +181,93 @@ final class ConfigurationTests: SwiftLintTestCase { ] let combinedRulesConfigDict = enabledRulesConfigDict.reduce(into: disabledRulesConfigDict) { $0[$1.0] = $1.1 } var configuration = try? Configuration(dict: enabledRulesConfigDict) - XCTAssertNil(configuration) + #expect(configuration == nil) configuration = try? Configuration(dict: disabledRulesConfigDict) - XCTAssertNil(configuration) + #expect(configuration == nil) configuration = try? Configuration(dict: combinedRulesConfigDict) - XCTAssertNil(configuration) + #expect(configuration == nil) } - func testDisabledRules() throws { + @Test + func disabledRules() throws { let disabledConfig = try Configuration(dict: ["disabled_rules": ["nesting", "todo"]]) - XCTAssertEqual(disabledConfig.rulesWrapper.disabledRuleIdentifiers, - ["nesting", "todo"], + #expect(disabledConfig.rulesWrapper.disabledRuleIdentifiers == ["nesting", "todo"], "initializing Configuration with valid rules in Dictionary should succeed") let expectedIdentifiers = Set(RuleRegistry.shared.list.list.keys .filter({ !(["nesting", "todo"] + optInRules).contains($0) })) let configuredIdentifiers = Set(disabledConfig.rules.map { type(of: $0).identifier }) - XCTAssertEqual(expectedIdentifiers, configuredIdentifiers) + #expect(expectedIdentifiers == configuredIdentifiers) } - func testDisabledRulesWithUnknownRule() throws { + @Test + func disabledRulesWithUnknownRule() throws { let validRule = "nesting" let bogusRule = "no_sprites_with_elf_shoes" let configuration = try Configuration(dict: ["disabled_rules": [validRule, bogusRule]]) - XCTAssertEqual(configuration.rulesWrapper.disabledRuleIdentifiers, - [validRule], + #expect(configuration.rulesWrapper.disabledRuleIdentifiers == [validRule], "initializing Configuration with valid rules in YAML string should succeed") let expectedIdentifiers = Set(RuleRegistry.shared.list.list.keys .filter({ !([validRule] + optInRules).contains($0) })) - XCTAssertEqual(expectedIdentifiers, Set(configuration.enabledRuleIdentifiers)) + #expect(expectedIdentifiers == Set(configuration.enabledRuleIdentifiers)) } - func testDuplicatedRules() { + @Test + func duplicatedRules() { let duplicateConfig1 = try? Configuration(dict: ["only_rules": ["todo", "todo"]]) - XCTAssertEqual( - duplicateConfig1?.rules.count, 1, "duplicate rules should be removed when initializing Configuration" + #expect( + duplicateConfig1?.rules.count == 1, "duplicate rules should be removed when initializing Configuration" ) let duplicateConfig2 = try? Configuration(dict: ["opt_in_rules": [optInRules.first!, optInRules.first!]]) - XCTAssertEqual( - duplicateConfig2?.rules.filter { type(of: $0).identifier == optInRules.first! }.count, 1, + #expect( + duplicateConfig2?.rules.filter { type(of: $0).identifier == optInRules.first! }.count == 1, "duplicate rules should be removed when initializing Configuration" ) let duplicateConfig3 = try? Configuration(dict: ["disabled_rules": ["todo", "todo"]]) - XCTAssertEqual( - duplicateConfig3?.rulesWrapper.disabledRuleIdentifiers.count, 1, + #expect( + duplicateConfig3?.rulesWrapper.disabledRuleIdentifiers.count == 1, "duplicate rules should be removed when initializing Configuration" ) } - func testIncludedExcludedRelativeLocationLevel1() { - guard !isRunningWithBazel else { - return - } - - XCTAssert(FileManager.default.changeCurrentDirectoryPath(Mock.Dir.level1)) - + @Test(.disabled(if: isRunningWithBazel)) + @WorkingDirectory(path: Constants.Dir.level1) + func includedExcludedRelativeLocationLevel1() { // The included path "File.swift" should be put relative to the configuration file // (~> Resources/ProjectMock/File.swift) and not relative to the path where // SwiftLint is run from (~> Resources/ProjectMock/Level1/File.swift) let configuration = Configuration(configurationFiles: ["../custom_included_excluded.yml"]) let actualIncludedPath = configuration.includedPaths.first!.bridge() .absolutePathRepresentation(rootDirectory: configuration.rootDirectory) - let desiredIncludedPath = "File1.swift".absolutePathRepresentation(rootDirectory: Mock.Dir.level0) + let desiredIncludedPath = "File1.swift".absolutePathRepresentation(rootDirectory: Constants.Dir.level0) let actualExcludedPath = configuration.excludedPaths.first!.bridge() .absolutePathRepresentation(rootDirectory: configuration.rootDirectory) - let desiredExcludedPath = "File2.swift".absolutePathRepresentation(rootDirectory: Mock.Dir.level0) + let desiredExcludedPath = "File2.swift".absolutePathRepresentation(rootDirectory: Constants.Dir.level0) - XCTAssertEqual(actualIncludedPath, desiredIncludedPath) - XCTAssertEqual(actualExcludedPath, desiredExcludedPath) + #expect(actualIncludedPath == desiredIncludedPath) + #expect(actualExcludedPath == desiredExcludedPath) } - func testIncludedExcludedRelativeLocationLevel0() { + @Test + @WorkingDirectory(path: Constants.Dir.level0) + func includedExcludedRelativeLocationLevel0() { // Same as testIncludedPathRelatedToConfigurationFileLocationLevel1(), // but run from the directory the config file resides in - XCTAssert(FileManager.default.changeCurrentDirectoryPath(Mock.Dir.level0)) let configuration = Configuration(configurationFiles: ["custom_included_excluded.yml"]) let actualIncludedPath = configuration.includedPaths.first!.bridge() .absolutePathRepresentation(rootDirectory: configuration.rootDirectory) - let desiredIncludedPath = "File1.swift".absolutePathRepresentation(rootDirectory: Mock.Dir.level0) + let desiredIncludedPath = "File1.swift".absolutePathRepresentation(rootDirectory: Constants.Dir.level0) let actualExcludedPath = configuration.excludedPaths.first!.bridge() .absolutePathRepresentation(rootDirectory: configuration.rootDirectory) - let desiredExcludedPath = "File2.swift".absolutePathRepresentation(rootDirectory: Mock.Dir.level0) + let desiredExcludedPath = "File2.swift".absolutePathRepresentation(rootDirectory: Constants.Dir.level0) - XCTAssertEqual(actualIncludedPath, desiredIncludedPath) - XCTAssertEqual(actualExcludedPath, desiredExcludedPath) + #expect(actualIncludedPath == desiredIncludedPath) + #expect(actualExcludedPath == desiredExcludedPath) } private class TestFileManager: LintableFileManager { @@ -296,7 +282,7 @@ final class ConfigurationTests: SwiftLintTestCase { ] case "directory/excluded": filesToLint = ["directory/excluded/Excluded.swift"] case "directory/ExcludedFile.swift": filesToLint = ["directory/ExcludedFile.swift"] - default: XCTFail("Should not be called with path \(path)") + default: Issue.record("Should not be called with path \(path)") } return filesToLint.absolutePathsStandardized() } @@ -310,7 +296,8 @@ final class ConfigurationTests: SwiftLintTestCase { } } - func testExcludedPaths() { + @Test + func excludedPaths() { let fileManager = TestFileManager() let configuration = Configuration( includedPaths: ["directory"], @@ -322,10 +309,11 @@ final class ConfigurationTests: SwiftLintTestCase { forceExclude: false, excludeBy: .paths(excludedPaths: excludedPaths), fileManager: fileManager) - XCTAssertEqual(["directory/File1.swift", "directory/File2.swift"].absolutePathsStandardized(), paths) + #expect(["directory/File1.swift", "directory/File2.swift"].absolutePathsStandardized() == paths) } - func testForceExcludesFile() { + @Test + func forceExcludesFile() { let fileManager = TestFileManager() let configuration = Configuration(excludedPaths: ["directory/ExcludedFile.swift"]) let excludedPaths = configuration.excludedPaths(fileManager: fileManager) @@ -333,10 +321,11 @@ final class ConfigurationTests: SwiftLintTestCase { forceExclude: true, excludeBy: .paths(excludedPaths: excludedPaths), fileManager: fileManager) - XCTAssertEqual([], paths) + #expect([] == paths) } - func testForceExcludesFileNotPresentInExcluded() { + @Test + func forceExcludesFileNotPresentInExcluded() { let fileManager = TestFileManager() let configuration = Configuration(includedPaths: ["directory"], excludedPaths: ["directory/ExcludedFile.swift", "directory/excluded"]) @@ -345,10 +334,11 @@ final class ConfigurationTests: SwiftLintTestCase { forceExclude: true, excludeBy: .paths(excludedPaths: excludedPaths), fileManager: fileManager) - XCTAssertEqual(["directory/File1.swift", "directory/File2.swift"].absolutePathsStandardized(), paths) + #expect(["directory/File1.swift", "directory/File2.swift"].absolutePathsStandardized() == paths) } - func testForceExcludesDirectory() { + @Test + func forceExcludesDirectory() { let fileManager = TestFileManager() let configuration = Configuration(excludedPaths: ["directory/excluded", "directory/ExcludedFile.swift"]) let excludedPaths = configuration.excludedPaths(fileManager: fileManager) @@ -356,10 +346,11 @@ final class ConfigurationTests: SwiftLintTestCase { forceExclude: true, excludeBy: .paths(excludedPaths: excludedPaths), fileManager: fileManager) - XCTAssertEqual(["directory/File1.swift", "directory/File2.swift"].absolutePathsStandardized(), paths) + #expect(["directory/File1.swift", "directory/File2.swift"].absolutePathsStandardized() == paths) } - func testForceExcludesDirectoryThatIsNotInExcludedButHasChildrenThatAre() { + @Test + func forceExcludesDirectoryThatIsNotInExcludedButHasChildrenThatAre() { let fileManager = TestFileManager() let configuration = Configuration(excludedPaths: ["directory/excluded", "directory/ExcludedFile.swift"]) let excludedPaths = configuration.excludedPaths(fileManager: fileManager) @@ -367,12 +358,13 @@ final class ConfigurationTests: SwiftLintTestCase { forceExclude: true, excludeBy: .paths(excludedPaths: excludedPaths), fileManager: fileManager) - XCTAssertEqual(["directory/File1.swift", "directory/File2.swift"].absolutePathsStandardized(), paths) + #expect(["directory/File1.swift", "directory/File2.swift"].absolutePathsStandardized() == paths) } - func testLintablePaths() { + @Test + func lintablePaths() { let excluded = Configuration.default.excludedPaths(fileManager: TestFileManager()) - let paths = Configuration.default.lintablePaths(inPath: Mock.Dir.level0, + let paths = Configuration.default.lintablePaths(inPath: Constants.Dir.level0, forceExclude: false, excludeBy: .paths(excludedPaths: excluded)) let filenames = paths.map { $0.bridge().lastPathComponent }.sorted() @@ -382,234 +374,268 @@ final class ConfigurationTests: SwiftLintTestCase { "Main.swift", "Sub.swift", ] - XCTAssertEqual(Set(expectedFilenames), Set(filenames)) + #expect(Set(expectedFilenames) == Set(filenames)) } - func testGlobIncludePaths() { - XCTAssert(FileManager.default.changeCurrentDirectoryPath(Mock.Dir.level0)) + @Test + @WorkingDirectory(path: Constants.Dir.level0) + func globIncludePaths() { let configuration = Configuration(includedPaths: ["**/Level2"]) - let paths = configuration.lintablePaths(inPath: Mock.Dir.level0, + let paths = configuration.lintablePaths(inPath: Constants.Dir.level0, forceExclude: true, excludeBy: .paths(excludedPaths: configuration.excludedPaths)) let filenames = paths.map { $0.bridge().lastPathComponent }.sorted() let expectedFilenames = ["Level2.swift", "Level3.swift"] - XCTAssertEqual(Set(expectedFilenames), Set(filenames)) + #expect(Set(expectedFilenames) == Set(filenames)) } - func testGlobExcludePaths() { + @Test + func globExcludePaths() { let configuration = Configuration( - includedPaths: [Mock.Dir.level3], - excludedPaths: [Mock.Dir.level3.stringByAppendingPathComponent("*.swift")] + includedPaths: [Constants.Dir.level3], + excludedPaths: [Constants.Dir.level3.stringByAppendingPathComponent("*.swift")] ) let excludedPaths = configuration.excludedPaths() let lintablePaths = configuration.lintablePaths(inPath: "", forceExclude: false, excludeBy: .paths(excludedPaths: excludedPaths)) - XCTAssertEqual(lintablePaths, []) + #expect(lintablePaths.isEmpty) } // MARK: - Testing Configuration Equality - func testIsEqualTo() { - XCTAssertEqual(Mock.Config._0, Mock.Config._0) + @Test + func isEqualTo() { + #expect(Constants.Config._0 == Constants.Config._0) // swiftlint:disable:this identical_operands } - func testIsNotEqualTo() { - XCTAssertNotEqual(Mock.Config._0, Mock.Config._2) + @Test + func isNotEqualTo() { + #expect(Constants.Config._0 != Constants.Config._2) } // MARK: - Testing Custom Configuration File - func testCustomConfiguration() { - let file = SwiftLintFile(path: Mock.Swift._0)! - XCTAssertNotEqual(Mock.Config._0.configuration(for: file), - Mock.Config._0Custom.configuration(for: file)) + @Test + func customConfiguration() { + let file = SwiftLintFile(path: Constants.Swift._0)! + #expect(Constants.Config._0.configuration(for: file) != Constants.Config._0Custom.configuration(for: file)) } - func testConfigurationWithSwiftFileAsRoot() { - let configuration = Configuration(configurationFiles: [Mock.Yml._0]) + @Test + func configurationWithSwiftFileAsRoot() { + let configuration = Configuration(configurationFiles: [Constants.Yml._0]) - let file = SwiftLintFile(path: Mock.Swift._0)! - XCTAssertEqual(configuration.configuration(for: file), configuration) + let file = SwiftLintFile(path: Constants.Swift._0)! + #expect(configuration.configuration(for: file) == configuration) } - func testConfigurationWithSwiftFileAsRootAndCustomConfiguration() { - let configuration = Mock.Config._0Custom + @Test + func configurationWithSwiftFileAsRootAndCustomConfiguration() { + let configuration = Constants.Config._0Custom - let file = SwiftLintFile(path: Mock.Swift._0)! - XCTAssertEqual(configuration.configuration(for: file), configuration) + let file = SwiftLintFile(path: Constants.Swift._0)! + #expect(configuration.configuration(for: file) == configuration) } // MARK: - Testing custom indentation - func testIndentationTabs() throws { + @Test + func indentationTabs() throws { let configuration = try Configuration(dict: ["indentation": "tabs"]) - XCTAssertEqual(configuration.indentation, .tabs) + #expect(configuration.indentation == .tabs) } - func testIndentationSpaces() throws { + @Test + func indentationSpaces() throws { let configuration = try Configuration(dict: ["indentation": 2]) - XCTAssertEqual(configuration.indentation, .spaces(count: 2)) + #expect(configuration.indentation == .spaces(count: 2)) } - func testIndentationFallback() throws { + @Test + func indentationFallback() throws { let configuration = try Configuration(dict: ["indentation": "invalid"]) - XCTAssertEqual(configuration.indentation, .spaces(count: 4)) + #expect(configuration.indentation == .spaces(count: 4)) } // MARK: - Testing Rules from config dictionary - private let testRuleList = RuleList(rules: RuleWithLevelsMock.self) + private static nonisolated(unsafe) let testRuleList = RuleList(rules: RuleWithLevelsMock.self) - func testConfiguresCorrectlyFromDict() throws { + @Test + func configuresCorrectlyFromDict() throws { let ruleConfiguration = [1, 2] let config = [RuleWithLevelsMock.identifier: ruleConfiguration] - let rules = try testRuleList.allRulesWrapped(configurationDict: config).map(\.rule) - // swiftlint:disable:next xct_specific_matcher - XCTAssertTrue(rules == [try RuleWithLevelsMock(configuration: ruleConfiguration)]) + let rules = try Self.testRuleList.allRulesWrapped(configurationDict: config).map(\.rule) + #expect(rules == [try RuleWithLevelsMock(configuration: ruleConfiguration)]) } - func testConfigureFallsBackCorrectly() throws { + @Test + func configureFallsBackCorrectly() throws { let config = [RuleWithLevelsMock.identifier: ["a", "b"]] - let rules = try testRuleList.allRulesWrapped(configurationDict: config).map(\.rule) - // swiftlint:disable:next xct_specific_matcher - XCTAssertTrue(rules == [RuleWithLevelsMock()]) + let rules = try Self.testRuleList.allRulesWrapped(configurationDict: config).map(\.rule) + #expect(rules == [RuleWithLevelsMock()]) } - func testAllowZeroLintableFiles() throws { + @Test + func allowZeroLintableFiles() throws { let configuration = try Configuration(dict: ["allow_zero_lintable_files": true]) - XCTAssertTrue(configuration.allowZeroLintableFiles) + #expect(configuration.allowZeroLintableFiles) } - func testStrict() throws { + @Test + func strict() throws { let configuration = try Configuration(dict: ["strict": true]) - XCTAssertTrue(configuration.strict) + #expect(configuration.strict) } - func testLenient() throws { + @Test + func lenient() throws { let configuration = try Configuration(dict: ["lenient": true]) - XCTAssertTrue(configuration.lenient) + #expect(configuration.lenient) } - func testBaseline() throws { + @Test + func baseline() throws { let baselinePath = "Baseline.json" let configuration = try Configuration(dict: ["baseline": baselinePath]) - XCTAssertEqual(configuration.baseline, baselinePath) + #expect(configuration.baseline == baselinePath) } - func testWriteBaseline() throws { + @Test + func writeBaseline() throws { let baselinePath = "Baseline.json" let configuration = try Configuration(dict: ["write_baseline": baselinePath]) - XCTAssertEqual(configuration.writeBaseline, baselinePath) + #expect(configuration.writeBaseline == baselinePath) } - func testCheckForUpdates() throws { + @Test + func checkForUpdates() throws { let configuration = try Configuration(dict: ["check_for_updates": true]) - XCTAssertTrue(configuration.checkForUpdates) + #expect(configuration.checkForUpdates) } } // MARK: - ExcludeByPrefix option tests -extension ConfigurationTests { - func testExcludeByPrefixExcludedPaths() { - XCTAssert(FileManager.default.changeCurrentDirectoryPath(Mock.Dir.level0)) +extension FileSystemAccessTestSuite.ConfigurationTests { + @Test + @WorkingDirectory(path: Constants.Dir.level0) + func excludeByPrefixExcludedPaths() { let configuration = Configuration( includedPaths: ["Level1"], excludedPaths: ["Level1/Level1.swift", "Level1/Level2/Level3"] ) - let paths = configuration.lintablePaths(inPath: Mock.Dir.level0, - forceExclude: false, - excludeBy: .prefix) + let paths = configuration.lintablePaths( + inPath: Constants.Dir.level0, + forceExclude: false, + excludeBy: .prefix + ) let filenames = paths.map { $0.bridge().lastPathComponent } - XCTAssertEqual(filenames, ["Level2.swift"]) + #expect(filenames == ["Level2.swift"]) } - func testExcludeByPrefixForceExcludesFile() { - XCTAssert(FileManager.default.changeCurrentDirectoryPath(Mock.Dir.level0)) + @Test + func excludeByPrefixForceExcludesFile() { let configuration = Configuration(excludedPaths: ["Level1/Level2/Level3/Level3.swift"]) let paths = configuration.lintablePaths(inPath: "Level1/Level2/Level3/Level3.swift", forceExclude: true, excludeBy: .prefix) - XCTAssertEqual([], paths) + #expect(paths.isEmpty) } - func testExcludeByPrefixForceExcludesFileNotPresentInExcluded() { - XCTAssert(FileManager.default.changeCurrentDirectoryPath(Mock.Dir.level0)) - let configuration = Configuration(includedPaths: ["Level1"], - excludedPaths: ["Level1/Level1.swift"]) - let paths = configuration.lintablePaths(inPath: "Level1", - forceExclude: true, - excludeBy: .prefix) + @Test + @WorkingDirectory(path: Constants.Dir.level0) + func excludeByPrefixForceExcludesFileNotPresentInExcluded() { + let configuration = Configuration( + includedPaths: ["Level1"], + excludedPaths: ["Level1/Level1.swift"]) + let paths = configuration.lintablePaths( + inPath: "Level1", + forceExclude: true, + excludeBy: .prefix + ) let filenames = paths.map { $0.bridge().lastPathComponent }.sorted() - XCTAssertEqual(["Level2.swift", "Level3.swift"], filenames) + #expect(["Level2.swift", "Level3.swift"] == filenames) } - func testExcludeByPrefixForceExcludesDirectory() { - XCTAssert(FileManager.default.changeCurrentDirectoryPath(Mock.Dir.level0)) + @Test + @WorkingDirectory(path: Constants.Dir.level0) + func excludeByPrefixForceExcludesDirectory() { let configuration = Configuration( excludedPaths: [ "Level1/Level2", "Directory.swift", "ChildConfig", "ParentConfig", "NestedConfig" ] ) - let paths = configuration.lintablePaths(inPath: ".", - forceExclude: true, - excludeBy: .prefix) + let paths = configuration.lintablePaths( + inPath: ".", + forceExclude: true, + excludeBy: .prefix + ) let filenames = paths.map { $0.bridge().lastPathComponent }.sorted() - XCTAssertEqual(["Level0.swift", "Level1.swift"], filenames) + #expect(["Level0.swift", "Level1.swift"] == filenames) } - func testExcludeByPrefixForceExcludesDirectoryThatIsNotInExcludedButHasChildrenThatAre() { - XCTAssert(FileManager.default.changeCurrentDirectoryPath(Mock.Dir.level0)) + @Test + @WorkingDirectory(path: Constants.Dir.level0) + func excludeByPrefixForceExcludesDirectoryThatIsNotInExcludedButHasChildrenThatAre() { let configuration = Configuration( excludedPaths: [ "Level1", "Directory.swift/DirectoryLevel1.swift", "ChildConfig", "ParentConfig", "NestedConfig" ] ) - let paths = configuration.lintablePaths(inPath: ".", - forceExclude: true, - excludeBy: .prefix) + let paths = configuration.lintablePaths( + inPath: ".", + forceExclude: true, + excludeBy: .prefix + ) let filenames = paths.map { $0.bridge().lastPathComponent } - XCTAssertEqual(["Level0.swift"], filenames) + #expect(["Level0.swift"] == filenames) } - func testExcludeByPrefixGlobExcludePaths() { - XCTAssert(FileManager.default.changeCurrentDirectoryPath(Mock.Dir.level0)) + @Test + @WorkingDirectory(path: Constants.Dir.level0) + func excludeByPrefixGlobExcludePaths() { let configuration = Configuration( includedPaths: ["Level1"], excludedPaths: ["Level1/*/*.swift", "Level1/*/*/*.swift"]) - let paths = configuration.lintablePaths(inPath: "Level1", - forceExclude: false, - excludeBy: .prefix) + let paths = configuration.lintablePaths( + inPath: "Level1", + forceExclude: false, + excludeBy: .prefix + ) let filenames = paths.map { $0.bridge().lastPathComponent }.sorted() - XCTAssertEqual(filenames, ["Level1.swift"]) + #expect(filenames == ["Level1.swift"]) } - func testDictInitWithCachePath() throws { + @Test + func dictInitWithCachePath() throws { let configuration = try Configuration( dict: ["cache_path": "cache/path/1"] ) - XCTAssertEqual(configuration.cachePath, "cache/path/1") + #expect(configuration.cachePath == "cache/path/1") } - func testDictInitWithCachePathFromCommandLine() throws { + @Test + func dictInitWithCachePathFromCommandLine() throws { let configuration = try Configuration( dict: ["cache_path": "cache/path/1"], cachePath: "cache/path/2" ) - XCTAssertEqual(configuration.cachePath, "cache/path/2") + #expect(configuration.cachePath == "cache/path/2") } - func testMainInitWithCachePath() { + @Test + func mainInitWithCachePath() { let configuration = Configuration( configurationFiles: [], cachePath: "cache/path/1" ) - XCTAssertEqual(configuration.cachePath, "cache/path/1") + #expect(configuration.cachePath == "cache/path/1") } // This test demonstrates an existing bug: when the Configuration is obtained from the in-memory cache, the @@ -617,7 +643,8 @@ extension ConfigurationTests { // // This issue may not be reproducible under normal execution: the cache is in memory, so when a user changes // the cachePath from command line and re-runs swiftlint, cache is not reused leading to the correct behavior - func testMainInitWithCachePathAndCachedConfig() { + @Test + func mainInitWithCachePathAndCachedConfig() { let configuration1 = Configuration( configurationFiles: [], cachePath: "cache/path/1" @@ -628,8 +655,8 @@ extension ConfigurationTests { cachePath: "cache/path/2" ) - XCTAssertEqual(configuration1.cachePath, "cache/path/1") - XCTAssertEqual(configuration2.cachePath, "cache/path/1") + #expect(configuration1.cachePath == "cache/path/1") + #expect(configuration2.cachePath == "cache/path/1") } } @@ -641,8 +668,6 @@ private extension Sequence where Element == String { private extension Configuration { var enabledRuleIdentifiers: [String] { - rules.map { - type(of: $0).identifier - }.sorted() + rules.map { type(of: $0).identifier }.sorted() } } diff --git a/Tests/FileSystemAccessTests/FileSystemAccessTestSuite.swift b/Tests/FileSystemAccessTests/FileSystemAccessTestSuite.swift new file mode 100644 index 0000000000..d525eb9f70 --- /dev/null +++ b/Tests/FileSystemAccessTests/FileSystemAccessTestSuite.swift @@ -0,0 +1,16 @@ +import Testing + +@testable import SwiftLintFramework + +@Suite(.serialized, .rulesRegistered) +struct FileSystemAccessTestSuite { + struct BaselineTests {} + struct ConfigurationTests { + init() { + Configuration.resetCache() + } + } + struct GlobTests {} + struct ReporterTests {} + struct SourceKitCrashTests {} +} diff --git a/Tests/FileSystemAccessTests/GlobTests.swift b/Tests/FileSystemAccessTests/GlobTests.swift index 84771f554d..3439dbb3c6 100644 --- a/Tests/FileSystemAccessTests/GlobTests.swift +++ b/Tests/FileSystemAccessTests/GlobTests.swift @@ -1,73 +1,85 @@ import TestHelpers -import XCTest +import Testing @testable import SwiftLintFramework -final class GlobTests: SwiftLintTestCase { +extension FileSystemAccessTestSuite.GlobTests { private var mockPath: String { TestResources.path().stringByAppendingPathComponent("ProjectMock") } - func testNonExistingDirectory() { - XCTAssertTrue(Glob.resolveGlob("./bar/**").isEmpty) + @Test + func nonExistingDirectory() { + #expect(Glob.resolveGlob("./bar/**").isEmpty) } - func testOnlyGlobForWildcard() { + @Test + func onlyGlobForWildcard() { let files = Glob.resolveGlob("foo/bar.swift") - XCTAssertEqual(files, ["foo/bar.swift"]) + #expect(files == ["foo/bar.swift"]) } - func testNoMatchReturnsEmpty() { + @Test + func noMatchReturnsEmpty() { let files = Glob.resolveGlob(mockPath.stringByAppendingPathComponent("NoFile*.swift")) - XCTAssertTrue(files.isEmpty) + #expect(files.isEmpty) } - func testMatchesFiles() { + @Test + func matchesFiles() { let files = Glob.resolveGlob(mockPath.stringByAppendingPathComponent("Level*.swift")) - XCTAssertEqual(files, [mockPath.stringByAppendingPathComponent("Level0.swift")]) + #expect(files == [mockPath.stringByAppendingPathComponent("Level0.swift")]) } - func testMatchesSingleCharacter() { + @Test + func matchesSingleCharacter() { let files = Glob.resolveGlob(mockPath.stringByAppendingPathComponent("Level?.swift")) - XCTAssertEqual(files, [mockPath.stringByAppendingPathComponent("Level0.swift")]) + #expect(files == [mockPath.stringByAppendingPathComponent("Level0.swift")]) } - func testMatchesOneCharacterInBracket() { + @Test + func matchesOneCharacterInBracket() { let files = Glob.resolveGlob(mockPath.stringByAppendingPathComponent("Level[01].swift")) - XCTAssertEqual(files, [mockPath.stringByAppendingPathComponent("Level0.swift")]) + #expect(files == [mockPath.stringByAppendingPathComponent("Level0.swift")]) } - func testNoMatchOneCharacterInBracket() { + @Test + func noMatchOneCharacterInBracket() { let files = Glob.resolveGlob(mockPath.stringByAppendingPathComponent("Level[ab].swift")) - XCTAssertTrue(files.isEmpty) + #expect(files.isEmpty) } - func testMatchesCharacterInRange() { + @Test + func matchesCharacterInRange() { let files = Glob.resolveGlob(mockPath.stringByAppendingPathComponent("Level[0-9].swift")) - XCTAssertEqual(files, [mockPath.stringByAppendingPathComponent("Level0.swift")]) + #expect(files == [mockPath.stringByAppendingPathComponent("Level0.swift")]) } - func testNoMatchCharactersInRange() { + @Test + func noMatchCharactersInRange() { let files = Glob.resolveGlob(mockPath.stringByAppendingPathComponent("Level[a-z].swift")) - XCTAssertTrue(files.isEmpty) + #expect(files.isEmpty) } - func testMatchesMultipleFiles() { + @Test + func matchesMultipleFiles() { let expectedFiles: Set = [ mockPath.stringByAppendingPathComponent("Level0.swift"), mockPath.stringByAppendingPathComponent("Directory.swift"), ] let files = Glob.resolveGlob(mockPath.stringByAppendingPathComponent("*.swift")) - XCTAssertEqual(files.sorted(), expectedFiles.sorted()) + #expect(files.sorted() == expectedFiles.sorted()) } - func testMatchesNestedDirectory() { + @Test + func matchesNestedDirectory() { let files = Glob.resolveGlob(mockPath.stringByAppendingPathComponent("Level1/*.swift")) - XCTAssertEqual(files, [mockPath.stringByAppendingPathComponent("Level1/Level1.swift")]) + #expect(files == [mockPath.stringByAppendingPathComponent("Level1/Level1.swift")]) } - func testGlobstarSupport() { + @Test + func globstarSupport() { let expectedFiles = Set( [ "Directory.swift", @@ -82,6 +94,6 @@ final class GlobTests: SwiftLintTestCase { ) let files = Glob.resolveGlob(mockPath.stringByAppendingPathComponent("**/*.swift")) - XCTAssertEqual(files.sorted(), expectedFiles.sorted()) + #expect(files.sorted() == expectedFiles.sorted()) } } diff --git a/Tests/FileSystemAccessTests/ReporterTests.swift b/Tests/FileSystemAccessTests/ReporterTests.swift index d519f2848f..fda91bf247 100644 --- a/Tests/FileSystemAccessTests/ReporterTests.swift +++ b/Tests/FileSystemAccessTests/ReporterTests.swift @@ -1,73 +1,76 @@ import Foundation import SourceKittenFramework import TestHelpers -import XCTest +import Testing @testable import SwiftLintBuiltInRules @testable import SwiftLintFramework -final class ReporterTests: SwiftLintTestCase { - private let violations = [ - StyleViolation( - ruleDescription: LineLengthRule.description, - location: Location(file: "filename", line: 1, character: 1), - reason: "Violation Reason 1" - ), - StyleViolation( - ruleDescription: LineLengthRule.description, - severity: .error, - location: Location(file: "filename", line: 1), - reason: "Violation Reason 2" - ), - StyleViolation( - ruleDescription: SyntacticSugarRule.description, - severity: .error, - location: Location( - file: FileManager.default.currentDirectoryPath + "/path/file.swift", - line: 1, - character: 2 +extension FileSystemAccessTestSuite.ReporterTests { + private static var violations: [StyleViolation] { + [ + StyleViolation( + ruleDescription: LineLengthRule.description, + location: Location(file: "filename", line: 1, character: 1), + reason: "Violation Reason 1" ), - reason: "Shorthand syntactic sugar should be used, i.e. [Int] instead of Array"), - StyleViolation( - ruleDescription: ColonRule.description, - severity: .error, - location: Location(file: nil), - reason: nil - ), - ] - - func testReporterFromString() { - for reporter in reportersList { - XCTAssertEqual(reporter.identifier, reporterFrom(identifier: reporter.identifier).identifier) - } + StyleViolation( + ruleDescription: LineLengthRule.description, + severity: .error, + location: Location(file: "filename", line: 1), + reason: "Violation Reason 2" + ), + StyleViolation( + ruleDescription: SyntacticSugarRule.description, + severity: .error, + location: Location( + file: FileManager.default.currentDirectoryPath + "/path/file.swift", + line: 1, + character: 2 + ), + reason: "Shorthand syntactic sugar should be used, i.e. [Int] instead of Array"), + StyleViolation( + ruleDescription: ColonRule.description, + severity: .error, + location: Location(file: nil), + reason: nil + ), + ] } - private func stringFromFile(_ filename: String) -> String { - SwiftLintFile(path: "\(TestResources.path())/\(filename)")!.contents + @Test + func reporterFromString() { + for reporter in reportersList { + #expect(reporter.identifier == reporterFrom(identifier: reporter.identifier).identifier) + } } - func testXcodeReporter() throws { + @Test + func xcodeReporter() throws { try assertEqualContent( referenceFile: "CannedXcodeReporterOutput.txt", reporterType: XcodeReporter.self ) } - func testEmojiReporter() throws { + @Test + func emojiReporter() throws { try assertEqualContent( referenceFile: "CannedEmojiReporterOutput.txt", reporterType: EmojiReporter.self ) } - func testGitHubActionsLoggingReporter() throws { + @Test + func gitHubActionsLoggingReporter() throws { try assertEqualContent( referenceFile: "CannedGitHubActionsLoggingReporterOutput.txt", reporterType: GitHubActionsLoggingReporter.self ) } - func testGitLabJUnitReporter() throws { + @Test + func gitLabJUnitReporter() throws { try assertEqualContent( referenceFile: "CannedGitLabJUnitReporterOutput.xml", reporterType: GitLabJUnitReporter.self @@ -86,7 +89,8 @@ final class ReporterTests: SwiftLintTestCase { queuedFatalError("Unexpected value in JSON: \(result)") } - func testJSONReporter() throws { + @Test + func jsonReporter() throws { try assertEqualContent( referenceFile: "CannedJSONReporterOutput.json", reporterType: JSONReporter.self, @@ -94,49 +98,56 @@ final class ReporterTests: SwiftLintTestCase { ) } - func testCSVReporter() throws { + @Test + func cSVReporter() throws { try assertEqualContent( referenceFile: "CannedCSVReporterOutput.csv", reporterType: CSVReporter.self ) } - func testCheckstyleReporter() throws { + @Test + func checkstyleReporter() throws { try assertEqualContent( referenceFile: "CannedCheckstyleReporterOutput.xml", reporterType: CheckstyleReporter.self ) } - func testCodeClimateReporter() throws { + @Test + func codeClimateReporter() throws { try assertEqualContent( referenceFile: "CannedCodeClimateReporterOutput.json", reporterType: CodeClimateReporter.self ) } - func testSARIFReporter() throws { + @Test + func sarifReporter() throws { try assertEqualContent( referenceFile: "CannedSARIFReporterOutput.json", reporterType: SARIFReporter.self ) } - func testJunitReporter() throws { + @Test + func junitReporter() throws { try assertEqualContent( referenceFile: "CannedJunitReporterOutput.xml", reporterType: JUnitReporter.self ) } - func testHTMLReporter() throws { + @Test + func htmlReporter() throws { try assertEqualContent( referenceFile: "CannedHTMLReporterOutput.html", reporterType: HTMLReporter.self ) } - func testSonarQubeReporter() throws { + @Test + func sonarQubeReporter() throws { try assertEqualContent( referenceFile: "CannedSonarQubeReporterOutput.json", reporterType: SonarQubeReporter.self, @@ -144,59 +155,67 @@ final class ReporterTests: SwiftLintTestCase { ) } - func testMarkdownReporter() throws { + @Test + func markdownReporter() throws { try assertEqualContent( referenceFile: "CannedMarkdownReporterOutput.md", reporterType: MarkdownReporter.self ) } - func testRelativePathReporter() throws { + @Test + func relativePathReporter() throws { try assertEqualContent( referenceFile: "CannedRelativePathReporterOutput.txt", reporterType: RelativePathReporter.self ) } - func testRelativePathReporterPaths() { + @Test + func relativePathReporterPaths() { let relativePath = "filename" let absolutePath = FileManager.default.currentDirectoryPath + "/" + relativePath let location = Location(file: absolutePath, line: 1, character: 2) - let violation = StyleViolation(ruleDescription: LineLengthRule.description, - location: location, - reason: "Violation Reason") + let violation = StyleViolation( + ruleDescription: LineLengthRule.description, + location: location, + reason: "Violation Reason") let result = RelativePathReporter.generateReport([violation]) - XCTAssertFalse(result.contains(absolutePath)) - XCTAssertTrue(result.contains(relativePath)) + #expect(!result.contains(absolutePath)) + #expect(result.contains(relativePath)) } - func testSummaryReporter() { - let expectedOutput = stringFromFile("CannedSummaryReporterOutput.txt") + @Test + func summaryReporter() throws { + let expectedOutput = try stringFromFile("CannedSummaryReporterOutput.txt") .trimmingTrailingCharacters(in: .whitespacesAndNewlines) let correctableViolation = StyleViolation( ruleDescription: VerticalWhitespaceOpeningBracesRule.description, location: Location(file: "filename", line: 1, character: 2), reason: "Violation Reason" ) - let result = SummaryReporter.generateReport(violations + [correctableViolation]) - XCTAssertEqual(result, expectedOutput) + let result = SummaryReporter.generateReport(Self.violations + [correctableViolation]) + #expect(result == expectedOutput) } - func testSummaryReporterWithNoViolations() { - let expectedOutput = stringFromFile("CannedSummaryReporterNoViolationsOutput.txt") + @Test + func summaryReporterWithNoViolations() throws { + let expectedOutput = try stringFromFile("CannedSummaryReporterNoViolationsOutput.txt") .trimmingTrailingCharacters(in: .whitespacesAndNewlines) let result = SummaryReporter.generateReport([]) - XCTAssertEqual(result, expectedOutput) + #expect(result == expectedOutput) } - private func assertEqualContent(referenceFile: String, - reporterType: any Reporter.Type, - stringConverter: (String) throws -> some Equatable = { $0 }, - file: StaticString = #filePath, - line: UInt = #line) throws { + private func assertEqualContent( + referenceFile: String, + reporterType: any Reporter.Type, + stringConverter: (String) throws -> some Equatable = { $0 }, + file: StaticString = #filePath, + line: UInt = #line + ) throws { let dateFormatter = DateFormatter() dateFormatter.dateStyle = .short - let reference = stringFromFile(referenceFile).replacingOccurrences( + let reference = try stringFromFile(referenceFile).replacingOccurrences( of: "${CURRENT_WORKING_DIRECTORY}", with: FileManager.default.currentDirectoryPath ).replacingOccurrences( @@ -206,7 +225,7 @@ final class ReporterTests: SwiftLintTestCase { of: "${TODAYS_DATE}", with: dateFormatter.string(from: Date()) ) - let reporterOutput = reporterType.generateReport(violations) + let reporterOutput = reporterType.generateReport(Self.violations) let convertedReference = try stringConverter(reference) let convertedReporterOutput = try stringConverter(reporterOutput) if convertedReference != convertedReporterOutput { @@ -223,6 +242,12 @@ final class ReporterTests: SwiftLintTestCase { ) .write(to: referenceURL, atomically: true, encoding: .utf8) } - XCTAssertEqual(convertedReference, convertedReporterOutput, file: file, line: line) + #expect( + convertedReference == convertedReporterOutput, + sourceLocation: SourceLocation(fileID: #fileID, filePath: file.description, line: Int(line), column: 1)) + } + + private func stringFromFile(_ filename: String) throws -> String { + try #require(SwiftLintFile(path: TestResources.path() + "/" + filename)).contents } } diff --git a/Tests/FileSystemAccessTests/SourceKitCrashTests.swift b/Tests/FileSystemAccessTests/SourceKitCrashTests.swift index 34c00d65cb..6c691cfd7f 100644 --- a/Tests/FileSystemAccessTests/SourceKitCrashTests.swift +++ b/Tests/FileSystemAccessTests/SourceKitCrashTests.swift @@ -1,16 +1,13 @@ +import Foundation import TestHelpers -import XCTest +import Testing @testable import SwiftLintFramework -final class SourceKitCrashTests: SwiftLintTestCase { - override func invokeTest() { - CurrentRule.$allowSourceKitRequestWithoutRule.withValue(true) { - super.invokeTest() - } - } - - func testAssertHandlerIsNotCalledOnNormalFile() { +extension FileSystemAccessTestSuite.SourceKitCrashTests { + @Test(.sourceKitRequestsWithoutRule) + @TemporaryDirectory + func assertHandlerIsNotCalledOnNormalFile() { let file = SwiftLintFile(contents: "A file didn't crash SourceKitService") file.sourcekitdFailed = false @@ -18,11 +15,12 @@ final class SourceKitCrashTests: SwiftLintTestCase { file.assertHandler = { assertHandlerCalled = true } _ = file.syntaxMap - XCTAssertFalse(assertHandlerCalled, - "Expects assert handler was not called on accessing SwiftLintFile.syntaxMap") + #expect(!assertHandlerCalled, "Expects assert handler was not called on accessing SwiftLintFile.syntaxMap") } - func testAssertHandlerIsCalledOnFileThatCrashedSourceKitService() { + @Test(.sourceKitRequestsWithoutRule) + @TemporaryDirectory + func assertHandlerIsCalledOnFileThatCrashedSourceKitService() { let file = SwiftLintFile(contents: "A file crashed SourceKitService") file.sourcekitdFailed = true @@ -30,15 +28,16 @@ final class SourceKitCrashTests: SwiftLintTestCase { file.assertHandler = { assertHandlerCalled = true } _ = file.syntaxMap - XCTAssertTrue(assertHandlerCalled, - "Expects assert handler was called on accessing SwiftLintFile.syntaxMap") + #expect(assertHandlerCalled, "Expects assert handler was called on accessing SwiftLintFile.syntaxMap") } - func testRulesWithFileThatCrashedSourceKitService() throws { - let file = try XCTUnwrap(SwiftLintFile(path: "\(TestResources.path())/ProjectMock/Level0.swift")) + @Test(.sourceKitRequestsWithoutRule) + @WorkingDirectory(path: Constants.Dir.level0) + func rulesWithFileThatCrashedSourceKitService() throws { + let file = try #require(SwiftLintFile(path: "Level0.swift")) file.sourcekitdFailed = true file.assertHandler = { - XCTFail("If this called, rule's SourceKitFreeRule is not properly configured") + Issue.record("If this called, rule's SourceKitFreeRule is not properly configured") } let configuration = Configuration(rulesMode: .onlyConfiguration(allRuleIdentifiers)) let storage = RuleStorage() diff --git a/Tests/FrameworkTests/CollectingRuleTests.swift b/Tests/FrameworkTests/CollectingRuleTests.swift index 7e87dc3440..8e832b38d2 100644 --- a/Tests/FrameworkTests/CollectingRuleTests.swift +++ b/Tests/FrameworkTests/CollectingRuleTests.swift @@ -1,17 +1,21 @@ -@testable import SwiftLintFramework import TestHelpers -import XCTest +import Testing + +@testable import SwiftLintFramework -final class CollectingRuleTests: SwiftLintTestCase { - func testCollectsIntoStorage() { +@Suite +struct CollectingRuleTests { + @Test + func collectsIntoStorage() { struct Spec: MockCollectingRule { var configuration = SeverityConfiguration(.warning) func collectInfo(for _: SwiftLintFile) -> Int { 42 } + func validate(file: SwiftLintFile, collectedInfo: [SwiftLintFile: Int]) -> [StyleViolation] { - XCTAssertEqual(collectedInfo[file], 42) + #expect(collectedInfo[file] == 42) return [ StyleViolation( ruleDescription: Self.description, @@ -21,21 +25,23 @@ final class CollectingRuleTests: SwiftLintTestCase { } } - XCTAssertFalse(violations(Example("_ = 0"), config: Spec.configuration!).isEmpty) + #expect(!violations(Example("_ = 0"), config: Spec.configuration!).isEmpty) } - func testCollectsAllFiles() { + @Test + func collectsAllFiles() { struct Spec: MockCollectingRule { var configuration = SeverityConfiguration(.warning) func collectInfo(for file: SwiftLintFile) -> String { file.contents } + func validate(file: SwiftLintFile, collectedInfo: [SwiftLintFile: String]) -> [StyleViolation] { let values = collectedInfo.values - XCTAssertTrue(values.contains("foo")) - XCTAssertTrue(values.contains("bar")) - XCTAssertTrue(values.contains("baz")) + #expect(values.contains("foo")) + #expect(values.contains("bar")) + #expect(values.contains("baz")) return [ StyleViolation( ruleDescription: Self.description, @@ -46,32 +52,38 @@ final class CollectingRuleTests: SwiftLintTestCase { } let inputs = ["foo", "bar", "baz"] - XCTAssertEqual(inputs.violations(config: Spec.configuration!).count, inputs.count) + #expect(inputs.violations(config: Spec.configuration!).count == inputs.count) } - func testCollectsAnalyzerFiles() { + @Test + func collectsAnalyzerFiles() { struct Spec: MockCollectingRule, AnalyzerRule { var configuration = SeverityConfiguration(.warning) func collectInfo(for _: SwiftLintFile, compilerArguments: [String]) -> [String] { compilerArguments } - func validate(file: SwiftLintFile, collectedInfo: [SwiftLintFile: [String]], compilerArguments: [String]) - -> [StyleViolation] { - XCTAssertEqual(collectedInfo[file], compilerArguments) - return [ - StyleViolation( - ruleDescription: Self.description, - location: Location(file: file, byteOffset: 0) - ), - ] + + func validate( + file: SwiftLintFile, + collectedInfo: [SwiftLintFile: [String]], + compilerArguments: [String] + ) -> [StyleViolation] { + #expect(collectedInfo[file] == compilerArguments) + return [ + StyleViolation( + ruleDescription: Self.description, + location: Location(file: file, byteOffset: 0) + ), + ] } } - XCTAssertFalse(violations(Example("_ = 0"), config: Spec.configuration!, requiresFileOnDisk: true).isEmpty) + #expect(violations(Example("_ = 0"), config: Spec.configuration!, requiresFileOnDisk: true).isNotEmpty) } - func testCorrects() { + @Test + func corrects() { struct Spec: MockCollectingRule, CorrectableRule { var configuration = SeverityConfiguration(.warning) @@ -107,16 +119,26 @@ final class CollectingRuleTests: SwiftLintTestCase { file.contents } - func validate(file: SwiftLintFile, collectedInfo: [SwiftLintFile: String], compilerArguments _: [String]) - -> [StyleViolation] { - collectedInfo[file] == "baz" - ? [.init(ruleDescription: Spec.description, location: Location(file: file, byteOffset: 2))] - : [] + func validate( + file: SwiftLintFile, + collectedInfo: [SwiftLintFile: String], + compilerArguments _: [String] + ) -> [StyleViolation] { + collectedInfo[file] == "baz" + ? [ + .init( + ruleDescription: Spec.description, + location: Location(file: file, byteOffset: 2) + ), + ] + : [] } - func correct(file: SwiftLintFile, - collectedInfo: [SwiftLintFile: String], - compilerArguments _: [String]) -> Int { + func correct( + file: SwiftLintFile, + collectedInfo: [SwiftLintFile: String], + compilerArguments _: [String] + ) -> Int { collectedInfo[file] == "baz" ? 1 : 0 } @@ -126,8 +148,8 @@ final class CollectingRuleTests: SwiftLintTestCase { } let inputs = ["foo", "baz"] - XCTAssertEqual(inputs.corrections(config: Spec.configuration!).count, 1) - XCTAssertEqual(inputs.corrections(config: AnalyzerSpec.configuration!, requiresFileOnDisk: true).count, 1) + #expect(inputs.corrections(config: Spec.configuration!).count == 1) + #expect(inputs.corrections(config: AnalyzerSpec.configuration!, requiresFileOnDisk: true).count == 1) } } diff --git a/Tests/FrameworkTests/CommandTests.swift b/Tests/FrameworkTests/CommandTests.swift index 9e7fc7ae4d..e4d1989f09 100644 --- a/Tests/FrameworkTests/CommandTests.swift +++ b/Tests/FrameworkTests/CommandTests.swift @@ -1,10 +1,11 @@ // swiftlint:disable file_length import Foundation import SourceKittenFramework -@testable import SwiftLintBuiltInRules -@testable import SwiftLintFramework +import SwiftLintFramework import TestHelpers -import XCTest +import Testing + +@testable import SwiftLintBuiltInRules private extension Command { init?(string: String) { @@ -15,477 +16,576 @@ private extension Command { } } -// swiftlint:disable:next type_body_length -final class CommandTests: SwiftLintTestCase { +@Suite(.rulesRegistered) +struct CommandTests { // swiftlint:disable:this type_body_length + // MARK: Command Creation - func testNoCommandsInEmptyFile() { + @Test + func noCommandsInEmptyFile() { let file = SwiftLintFile(contents: "") - XCTAssertEqual(file.commands(), []) + #expect(file.commands().isEmpty) } - func testEmptyString() { - XCTAssertNil(Command(string: "")) + @Test + func emptyString() { + #expect(Command(string: "") == nil) } - func testDisable() { + @Test + func disable() { let input = "// swiftlint:disable rule_id\n" let file = SwiftLintFile(contents: input) let expected = Command(action: .disable, ruleIdentifiers: ["rule_id"], line: 1, range: 4..<29) - XCTAssertEqual(file.commands(), [expected]) - XCTAssertEqual(Command(string: input), expected) + #expect(file.commands() == [expected]) + #expect(Command(string: input) == expected) } - func testDisablePrevious() { + @Test + func disablePrevious() { let input = "// swiftlint:disable:previous rule_id\n" let file = SwiftLintFile(contents: input) - let expected = Command(action: .disable, ruleIdentifiers: ["rule_id"], line: 1, range: 4..<38, - modifier: .previous) - XCTAssertEqual(file.commands(), expected.expand()) - XCTAssertEqual(Command(string: input), expected) + let expected = Command( + action: .disable, ruleIdentifiers: ["rule_id"], line: 1, range: 4..<38, + modifier: .previous) + #expect(file.commands() == expected.expand()) + #expect(Command(string: input) == expected) } - func testDisableThis() { + @Test + func disableThis() { let input = "// swiftlint:disable:this rule_id\n" let file = SwiftLintFile(contents: input) - let expected = Command(action: .disable, ruleIdentifiers: ["rule_id"], line: 1, range: 4..<34, - modifier: .this) - XCTAssertEqual(file.commands(), expected.expand()) - XCTAssertEqual(Command(string: input), expected) + let expected = Command( + action: .disable, + ruleIdentifiers: ["rule_id"], + line: 1, + range: 4..<34, + modifier: .this + ) + #expect(file.commands() == expected.expand()) + #expect(Command(string: input) == expected) } - func testDisableNext() { + @Test + func disableNext() { let input = "// swiftlint:disable:next rule_id\n" let file = SwiftLintFile(contents: input) - let expected = Command(action: .disable, ruleIdentifiers: ["rule_id"], line: 1, range: 4..<34, - modifier: .next) - XCTAssertEqual(file.commands(), expected.expand()) - XCTAssertEqual(Command(string: input), expected) + let expected = Command( + action: .disable, + ruleIdentifiers: ["rule_id"], + line: 1, + range: 4..<34, + modifier: .next + ) + #expect(file.commands() == expected.expand()) + #expect(Command(string: input) == expected) } - func testEnable() { + @Test + func enable() { let input = "// swiftlint:enable rule_id\n" let file = SwiftLintFile(contents: input) - let expected = Command(action: .enable, ruleIdentifiers: ["rule_id"], line: 1, range: 4..<28) - XCTAssertEqual(file.commands(), [expected]) - XCTAssertEqual(Command(string: input), expected) + let expected = Command( + action: .enable, + ruleIdentifiers: ["rule_id"], + line: 1, + range: 4..<28 + ) + #expect(file.commands() == [expected]) + #expect(Command(string: input) == expected) } - func testEnablePrevious() { + @Test + func enablePrevious() { let input = "// swiftlint:enable:previous rule_id\n" let file = SwiftLintFile(contents: input) - let expected = Command(action: .enable, ruleIdentifiers: ["rule_id"], line: 1, range: 4..<37, - modifier: .previous) - XCTAssertEqual(file.commands(), expected.expand()) - XCTAssertEqual(Command(string: input), expected) + let expected = Command( + action: .enable, + ruleIdentifiers: ["rule_id"], + line: 1, + range: 4..<37, + modifier: .previous + ) + #expect(file.commands() == expected.expand()) + #expect(Command(string: input) == expected) } - func testEnableThis() { + @Test + func enableThis() { let input = "// swiftlint:enable:this rule_id\n" let file = SwiftLintFile(contents: input) - let expected = Command(action: .enable, ruleIdentifiers: ["rule_id"], line: 1, range: 4..<33, modifier: .this) - XCTAssertEqual(file.commands(), expected.expand()) - XCTAssertEqual(Command(string: input), expected) + let expected = Command( + action: .enable, + ruleIdentifiers: ["rule_id"], + line: 1, + range: 4..<33, + modifier: .this + ) + #expect(file.commands() == expected.expand()) + #expect(Command(string: input) == expected) } - func testEnableNext() { + @Test + func enableNext() { let input = "// swiftlint:enable:next rule_id\n" let file = SwiftLintFile(contents: input) - let expected = Command(action: .enable, ruleIdentifiers: ["rule_id"], line: 1, range: 4..<33, modifier: .next) - XCTAssertEqual(file.commands(), expected.expand()) - XCTAssertEqual(Command(string: input), expected) + let expected = Command( + action: .enable, + ruleIdentifiers: ["rule_id"], + line: 1, + range: 4..<33, + modifier: .next + ) + #expect(file.commands() == expected.expand()) + #expect(Command(string: input) == expected) } - func testTrailingComment() { + @Test + func trailingComment() { let input = "// swiftlint:enable:next rule_id - Comment\n" let file = SwiftLintFile(contents: input) - let expected = Command(action: .enable, ruleIdentifiers: ["rule_id"], line: 1, range: 4..<43, - modifier: .next, - trailingComment: "Comment") - XCTAssertEqual(file.commands(), expected.expand()) - XCTAssertEqual(Command(string: input), expected) + let expected = Command( + action: .enable, + ruleIdentifiers: ["rule_id"], + line: 1, + range: 4..<43, + modifier: .next, + trailingComment: "Comment" + ) + #expect(file.commands() == expected.expand()) + #expect(Command(string: input) == expected) } - func testTrailingCommentWithUrl() { - let input = "// swiftlint:enable:next rule_id - Comment with URL https://github.com/realm/SwiftLint\n" + @Test + func trailingCommentWithUrl() { + let input = + "// swiftlint:enable:next rule_id - Comment with URL https://github.com/realm/SwiftLint\n" let file = SwiftLintFile(contents: input) - let expected = Command(action: .enable, ruleIdentifiers: ["rule_id"], line: 1, range: 4..<87, - modifier: .next, - trailingComment: "Comment with URL https://github.com/realm/SwiftLint") - XCTAssertEqual(file.commands(), expected.expand()) - XCTAssertEqual(Command(string: input), expected) + let expected = Command( + action: .enable, + ruleIdentifiers: ["rule_id"], + line: 1, + range: 4..<87, + modifier: .next, + trailingComment: "Comment with URL https://github.com/realm/SwiftLint" + ) + #expect(file.commands() == expected.expand()) + #expect(Command(string: input) == expected) } - func testTrailingCommentUrlOnly() { + @Test + func trailingCommentUrlOnly() { let input = "// swiftlint:enable:next rule_id - https://github.com/realm/SwiftLint\n" let file = SwiftLintFile(contents: input) - let expected = Command(action: .enable, ruleIdentifiers: ["rule_id"], line: 1, range: 4..<70, - modifier: .next, - trailingComment: "https://github.com/realm/SwiftLint") - XCTAssertEqual(file.commands(), expected.expand()) - XCTAssertEqual(Command(string: input), expected) + let expected = Command( + action: .enable, + ruleIdentifiers: ["rule_id"], + line: 1, + range: 4..<70, + modifier: .next, + trailingComment: "https://github.com/realm/SwiftLint" + ) + #expect(file.commands() == expected.expand()) + #expect(Command(string: input) == expected) } // MARK: Action - func testActionInverse() { - XCTAssertEqual(Command.Action.enable.inverse(), .disable) - XCTAssertEqual(Command.Action.disable.inverse(), .enable) + @Test + func actionInverse() { + #expect(Command.Action.enable.inverse() == .disable) + #expect(Command.Action.disable.inverse() == .enable) } // MARK: Command Expansion private let completeLine = 0.. Int { - 1 - } - // swiftlint:disable:next unused_declaration - func bar() { - foo() + Example( + """ + public class Foo { + // swiftlint:disable:next unused_declaration + func foo() -> Int { + 1 + } + // swiftlint:disable:next unused_declaration + func bar() { + foo() + } } - } - """), + """), config: configuration, requiresFileOnDisk: true ) - XCTAssertEqual(violations.count, 1) - XCTAssertEqual(violations.first?.ruleIdentifier, "superfluous_disable_command") - XCTAssertEqual(violations.first?.location.line, 3) + #expect(violations.count == 1) + #expect(violations.first?.ruleIdentifier == "superfluous_disable_command") + #expect(violations.first?.location.line == 3) } } diff --git a/Tests/FrameworkTests/ConfigurationAliasesTests.swift b/Tests/FrameworkTests/ConfigurationAliasesTests.swift index 083b5f647d..1615920d50 100644 --- a/Tests/FrameworkTests/ConfigurationAliasesTests.swift +++ b/Tests/FrameworkTests/ConfigurationAliasesTests.swift @@ -1,42 +1,47 @@ -@testable import SwiftLintFramework +import SwiftLintFramework import TestHelpers -import XCTest +import Testing -final class ConfigurationAliasesTests: SwiftLintTestCase { +@Suite +struct ConfigurationAliasesTests { private let testRuleList = RuleList(rules: RuleWithLevelsMock.self) - func testConfiguresCorrectlyFromDeprecatedAlias() throws { + @Test + func configuresCorrectlyFromDeprecatedAlias() throws { let ruleConfiguration = [1, 2] let config = ["mock": ruleConfiguration] let rules = try testRuleList.allRulesWrapped(configurationDict: config).map(\.rule) - // swiftlint:disable:next xct_specific_matcher - XCTAssertTrue(rules == [try RuleWithLevelsMock(configuration: ruleConfiguration)]) + #expect(rules == [try RuleWithLevelsMock(configuration: ruleConfiguration)]) } - func testReturnsNilWithDuplicatedConfiguration() { + @Test + func returnsNilWithDuplicatedConfiguration() { let dict = ["mock": [1, 2], "severity_level_mock": [1, 3]] let configuration = try? Configuration(dict: dict, ruleList: testRuleList) - XCTAssertNil(configuration) + #expect(configuration == nil) } - func testInitsFromDeprecatedAlias() { + @Test + func initsFromDeprecatedAlias() { let ruleConfiguration = [1, 2] let configuration = try? Configuration(dict: ["mock": ruleConfiguration], ruleList: testRuleList) - XCTAssertNotNil(configuration) + #expect(configuration != nil) } - func testOnlyRulesFromDeprecatedAlias() { + @Test + func onlyRulesFromDeprecatedAlias() { // swiftlint:disable:next force_try let configuration = try! Configuration(dict: ["only_rules": ["mock"]], ruleList: testRuleList) let configuredIdentifiers = configuration.rules.map { type(of: $0).identifier } - XCTAssertEqual(configuredIdentifiers, ["severity_level_mock"]) + #expect(configuredIdentifiers == ["severity_level_mock"]) } - func testDisabledRulesFromDeprecatedAlias() { + @Test + func disabledRulesFromDeprecatedAlias() { // swiftlint:disable:next force_try let configuration = try! Configuration(dict: ["disabled_rules": ["mock"]], ruleList: testRuleList) - XCTAssert(configuration.rules.isEmpty) + #expect(configuration.rules.isEmpty) } } diff --git a/Tests/FrameworkTests/CustomRulesTests.swift b/Tests/FrameworkTests/CustomRulesTests.swift index 7042a517f3..d87e90ee36 100644 --- a/Tests/FrameworkTests/CustomRulesTests.swift +++ b/Tests/FrameworkTests/CustomRulesTests.swift @@ -2,22 +2,18 @@ import SourceKittenFramework @testable import SwiftLintCore @testable import SwiftLintFramework import TestHelpers -import XCTest +import Testing // swiftlint:disable file_length -// swiftlint:disable:next type_body_length -final class CustomRulesTests: SwiftLintTestCase { + +@Suite(.serialized, .rulesRegistered, .sourceKitRequestsWithoutRule) +struct CustomRulesTests { // swiftlint:disable:this type_body_length private typealias Configuration = RegexConfiguration private var testFile: SwiftLintFile { SwiftLintFile(path: "\(TestResources.path())/test.txt")! } - override func invokeTest() { - CurrentRule.$allowSourceKitRequestWithoutRule.withValue(true) { - super.invokeTest() - } - } - - func testCustomRuleConfigurationSetsCorrectlyWithMatchKinds() { + @Test + func customRuleConfigurationSetsCorrectlyWithMatchKinds() { let configDict = [ "my_custom_rule": [ "name": "MyCustomRule", @@ -39,13 +35,14 @@ final class CustomRulesTests: SwiftLintTestCase { do { var configuration = CustomRulesConfiguration() try configuration.apply(configuration: configDict) - XCTAssertEqual(configuration, compRules) + #expect(configuration == compRules) } catch { - XCTFail("Did not configure correctly") + Issue.record("Did not configure correctly") } } - func testCustomRuleConfigurationSetsCorrectlyWithExcludedMatchKinds() { + @Test + func customRuleConfigurationSetsCorrectlyWithExcludedMatchKinds() { let configDict = [ "my_custom_rule": [ "name": "MyCustomRule", @@ -67,21 +64,23 @@ final class CustomRulesTests: SwiftLintTestCase { do { var configuration = CustomRulesConfiguration() try configuration.apply(configuration: configDict) - XCTAssertEqual(configuration, compRules) + #expect(configuration == compRules) } catch { - XCTFail("Did not configure correctly") + Issue.record("Did not configure correctly") } } - func testCustomRuleConfigurationThrows() { + @Test + func customRuleConfigurationThrows() { let config = 17 var customRulesConfig = CustomRulesConfiguration() - checkError(Issue.invalidConfiguration(ruleID: CustomRules.identifier)) { + #expect(throws: Issue.invalidConfiguration(ruleID: CustomRules.identifier)) { try customRulesConfig.apply(configuration: config) } } - func testCustomRuleConfigurationMatchKindAmbiguity() { + @Test + func customRuleConfigurationMatchKindAmbiguity() { let configDict = [ "name": "MyCustomRule", "message": "Message", @@ -95,12 +94,13 @@ final class CustomRulesTests: SwiftLintTestCase { let expectedError = Issue.genericWarning( "The configuration keys 'match_kinds' and 'excluded_match_kinds' cannot appear at the same time." ) - checkError(expectedError) { + #expect(throws: expectedError) { try configuration.apply(configuration: configDict) } } - func testCustomRuleConfigurationIgnoreInvalidRules() throws { + @Test + func customRuleConfigurationIgnoreInvalidRules() throws { let configDict = [ "my_custom_rule": [ "name": "MyCustomRule", @@ -114,19 +114,19 @@ final class CustomRulesTests: SwiftLintTestCase { var customRulesConfig = CustomRulesConfiguration() try customRulesConfig.apply(configuration: configDict) - XCTAssertEqual(customRulesConfig.customRuleConfigurations.count, 1) + #expect(customRulesConfig.customRuleConfigurations.count == 1) let identifier = customRulesConfig.customRuleConfigurations.first?.identifier - XCTAssertEqual(identifier, "my_custom_rule") + #expect(identifier == "my_custom_rule") } - func testCustomRules() { + @Test + func customRules() { let (regexConfig, customRules) = getCustomRules() let file = SwiftLintFile(contents: "// My file with\n// a pattern") - XCTAssertEqual( - customRules.validate(file: file), - [ + #expect( + customRules.validate(file: file) == [ StyleViolation( ruleDescription: regexConfig.description, severity: .warning, @@ -137,7 +137,8 @@ final class CustomRulesTests: SwiftLintTestCase { ) } - func testLocalDisableCustomRule() throws { + @Test + func localDisableCustomRule() throws { let customRules: [String: Any] = [ "custom": [ "regex": "pattern", @@ -146,15 +147,15 @@ final class CustomRulesTests: SwiftLintTestCase { ] let example = Example("//swiftlint:disable custom \n// file with a pattern") let violations = try violations(forExample: example, customRules: customRules) - XCTAssertTrue(violations.isEmpty) + #expect(violations.isEmpty) } - func testLocalDisableCustomRuleWithMultipleRules() { + @Test + func localDisableCustomRuleWithMultipleRules() { let (configs, customRules) = getCustomRulesWithTwoRules() let file = SwiftLintFile(contents: "//swiftlint:disable \(configs.1.identifier) \n// file with a pattern") - XCTAssertEqual( - customRules.validate(file: file), - [ + #expect( + customRules.validate(file: file) == [ StyleViolation( ruleDescription: configs.0.description, severity: .warning, @@ -165,14 +166,16 @@ final class CustomRulesTests: SwiftLintTestCase { ) } - func testCustomRulesIncludedDefault() { + @Test + func customRulesIncludedDefault() { // Violation detected when included is omitted. let (_, customRules) = getCustomRules() let violations = customRules.validate(file: testFile) - XCTAssertEqual(violations.count, 1) + #expect(violations.count == 1) } - func testCustomRulesIncludedExcludesFile() { + @Test + func customRulesIncludedExcludesFile() { var (regexConfig, customRules) = getCustomRules(["included": "\\.yml$"]) var customRuleConfiguration = CustomRulesConfiguration() @@ -180,10 +183,11 @@ final class CustomRulesTests: SwiftLintTestCase { customRules.configuration = customRuleConfiguration let violations = customRules.validate(file: testFile) - XCTAssertTrue(violations.isEmpty) + #expect(violations.isEmpty) } - func testCustomRulesExcludedExcludesFile() { + @Test + func customRulesExcludedExcludesFile() { var (regexConfig, customRules) = getCustomRules(["excluded": "\\.txt$"]) var customRuleConfiguration = CustomRulesConfiguration() @@ -191,10 +195,11 @@ final class CustomRulesTests: SwiftLintTestCase { customRules.configuration = customRuleConfiguration let violations = customRules.validate(file: testFile) - XCTAssertTrue(violations.isEmpty) + #expect(violations.isEmpty) } - func testCustomRulesExcludedArrayExcludesFile() { + @Test + func customRulesExcludedArrayExcludesFile() { var (regexConfig, customRules) = getCustomRules(["excluded": ["\\.pdf$", "\\.txt$"]]) var customRuleConfiguration = CustomRulesConfiguration() @@ -202,23 +207,25 @@ final class CustomRulesTests: SwiftLintTestCase { customRules.configuration = customRuleConfiguration let violations = customRules.validate(file: testFile) - XCTAssertTrue(violations.isEmpty) + #expect(violations.isEmpty) } - func testCustomRulesCaptureGroup() { + @Test + func customRulesCaptureGroup() { let (_, customRules) = getCustomRules([ "regex": #"\ba\s+(\w+)"#, "capture_group": 1, ]) let violations = customRules.validate(file: testFile) - XCTAssertEqual(violations.count, 1) - XCTAssertEqual(violations[0].location.line, 2) - XCTAssertEqual(violations[0].location.character, 6) + #expect(violations.count == 1) + #expect(violations[0].location.line == 2) + #expect(violations[0].location.character == 6) } // MARK: - superfluous_disable_command support - func testCustomRulesTriggersSuperfluousDisableCommand() throws { + @Test + func customRulesTriggersSuperfluousDisableCommand() throws { let customRuleIdentifier = "forbidden" let customRules: [String: Any] = [ customRuleIdentifier: [ @@ -231,11 +238,12 @@ final class CustomRulesTests: SwiftLintTestCase { """) let violations = try violations(forExample: example, customRules: customRules) - XCTAssertEqual(violations.count, 1) - XCTAssertTrue(violations[0].isSuperfluousDisableCommandViolation(for: "custom_rules")) + #expect(violations.count == 1) + #expect(violations[0].isSuperfluousDisableCommandViolation(for: "custom_rules")) } - func testSpecificCustomRuleTriggersSuperfluousDisableCommand() throws { + @Test + func specificCustomRuleTriggersSuperfluousDisableCommand() throws { let customRuleIdentifier = "forbidden" let customRules: [String: Any] = [ customRuleIdentifier: [ @@ -249,11 +257,12 @@ final class CustomRulesTests: SwiftLintTestCase { """) let violations = try violations(forExample: example, customRules: customRules) - XCTAssertEqual(violations.count, 1) - XCTAssertTrue(violations[0].isSuperfluousDisableCommandViolation(for: customRuleIdentifier)) + #expect(violations.count == 1) + #expect(violations[0].isSuperfluousDisableCommandViolation(for: customRuleIdentifier)) } - func testSpecificAndCustomRulesTriggersSuperfluousDisableCommand() throws { + @Test + func specificAndCustomRulesTriggersSuperfluousDisableCommand() throws { let customRuleIdentifier = "forbidden" let customRules: [String: Any] = [ customRuleIdentifier: [ @@ -268,12 +277,13 @@ final class CustomRulesTests: SwiftLintTestCase { let violations = try violations(forExample: example, customRules: customRules) - XCTAssertEqual(violations.count, 2) - XCTAssertTrue(violations[0].isSuperfluousDisableCommandViolation(for: "custom_rules")) - XCTAssertTrue(violations[1].isSuperfluousDisableCommandViolation(for: "\(customRuleIdentifier)")) + #expect(violations.count == 2) + #expect(violations[0].isSuperfluousDisableCommandViolation(for: "custom_rules")) + #expect(violations[1].isSuperfluousDisableCommandViolation(for: "\(customRuleIdentifier)")) } - func testCustomRulesViolationAndViolationOfSuperfluousDisableCommand() throws { + @Test + func customRulesViolationAndViolationOfSuperfluousDisableCommand() throws { let customRuleIdentifier = "forbidden" let customRules: [String: Any] = [ customRuleIdentifier: [ @@ -289,12 +299,13 @@ final class CustomRulesTests: SwiftLintTestCase { let violations = try violations(forExample: example, customRules: customRules) - XCTAssertEqual(violations.count, 2) - XCTAssertEqual(violations[0].ruleIdentifier, customRuleIdentifier) - XCTAssertTrue(violations[1].isSuperfluousDisableCommandViolation(for: customRuleIdentifier)) + #expect(violations.count == 2) + #expect(violations[0].ruleIdentifier == customRuleIdentifier) + #expect(violations[1].isSuperfluousDisableCommandViolation(for: customRuleIdentifier)) } - func testDisablingCustomRulesDoesNotTriggerSuperfluousDisableCommand() throws { + @Test + func disablingCustomRulesDoesNotTriggerSuperfluousDisableCommand() throws { let customRules: [String: Any] = [ "forbidden": [ "regex": "FORBIDDEN", @@ -306,10 +317,11 @@ final class CustomRulesTests: SwiftLintTestCase { let FORBIDDEN = 1 """) - XCTAssertTrue(try violations(forExample: example, customRules: customRules).isEmpty) + #expect(try violations(forExample: example, customRules: customRules).isEmpty) } - func testMultipleSpecificCustomRulesTriggersSuperfluousDisableCommand() throws { + @Test + func multipleSpecificCustomRulesTriggersSuperfluousDisableCommand() throws { let customRules = [ "forbidden": [ "regex": "FORBIDDEN", @@ -324,12 +336,13 @@ final class CustomRulesTests: SwiftLintTestCase { """) let violations = try self.violations(forExample: example, customRules: customRules) - XCTAssertEqual(violations.count, 2) - XCTAssertTrue(violations[0].isSuperfluousDisableCommandViolation(for: "forbidden")) - XCTAssertTrue(violations[1].isSuperfluousDisableCommandViolation(for: "forbidden2")) + #expect(violations.count == 2) + #expect(violations[0].isSuperfluousDisableCommandViolation(for: "forbidden")) + #expect(violations[1].isSuperfluousDisableCommandViolation(for: "forbidden2")) } - func testUnviolatedSpecificCustomRulesTriggersSuperfluousDisableCommand() throws { + @Test + func unviolatedSpecificCustomRulesTriggersSuperfluousDisableCommand() throws { let customRules = [ "forbidden": [ "regex": "FORBIDDEN", @@ -344,11 +357,12 @@ final class CustomRulesTests: SwiftLintTestCase { """) let violations = try self.violations(forExample: example, customRules: customRules) - XCTAssertEqual(violations.count, 1) - XCTAssertTrue(violations[0].isSuperfluousDisableCommandViolation(for: "forbidden2")) + #expect(violations.count == 1) + #expect(violations[0].isSuperfluousDisableCommandViolation(for: "forbidden2")) } - func testViolatedSpecificAndGeneralCustomRulesTriggersSuperfluousDisableCommand() throws { + @Test + func violatedSpecificAndGeneralCustomRulesTriggersSuperfluousDisableCommand() throws { let customRules = [ "forbidden": [ "regex": "FORBIDDEN", @@ -363,11 +377,12 @@ final class CustomRulesTests: SwiftLintTestCase { """) let violations = try self.violations(forExample: example, customRules: customRules) - XCTAssertEqual(violations.count, 1) - XCTAssertTrue(violations[0].isSuperfluousDisableCommandViolation(for: "forbidden2")) + #expect(violations.count == 1) + #expect(violations[0].isSuperfluousDisableCommandViolation(for: "forbidden2")) } - func testSuperfluousDisableCommandWithMultipleCustomRules() throws { + @Test + func superfluousDisableCommandWithMultipleCustomRules() throws { let customRules: [String: Any] = [ "custom1": [ "regex": "pattern", @@ -392,52 +407,59 @@ final class CustomRulesTests: SwiftLintTestCase { let violations = try violations(forExample: example, customRules: customRules) - XCTAssertEqual(violations.count, 3) - XCTAssertEqual(violations[0].ruleIdentifier, "custom2") - XCTAssertTrue(violations[1].isSuperfluousDisableCommandViolation(for: "custom1")) - XCTAssertTrue(violations[2].isSuperfluousDisableCommandViolation(for: "custom3")) + #expect(violations.count == 3) + #expect(violations[0].ruleIdentifier == "custom2") + #expect(violations[1].isSuperfluousDisableCommandViolation(for: "custom1")) + #expect(violations[2].isSuperfluousDisableCommandViolation(for: "custom3")) } - func testViolatedCustomRuleDoesNotTriggerSuperfluousDisableCommand() throws { + @Test + func violatedCustomRuleDoesNotTriggerSuperfluousDisableCommand() throws { let customRules: [String: Any] = [ "dont_print": [ "regex": "print\\(" ], ] - let example = Example(""" - // swiftlint:disable:next dont_print - print("Hello, world") - """) - XCTAssertTrue(try violations(forExample: example, customRules: customRules).isEmpty) + let example = Example( + """ + // swiftlint:disable:next dont_print + print("Hello, world") + """) + #expect(try violations(forExample: example, customRules: customRules).isEmpty) } - func testDisableAllDoesNotTriggerSuperfluousDisableCommand() throws { + @Test + func disableAllDoesNotTriggerSuperfluousDisableCommand() throws { let customRules: [String: Any] = [ "dont_print": [ "regex": "print\\(" ], ] - let example = Example(""" - // swiftlint:disable:next all - print("Hello, world") - """) - XCTAssertTrue(try violations(forExample: example, customRules: customRules).isEmpty) + let example = Example( + """ + // swiftlint:disable:next all + print("Hello, world") + """) + #expect(try violations(forExample: example, customRules: customRules).isEmpty) } - func testDisableAllAndDisableSpecificCustomRuleDoesNotTriggerSuperfluousDisableCommand() throws { + @Test + func disableAllAndDisableSpecificCustomRuleDoesNotTriggerSuperfluousDisableCommand() throws { let customRules: [String: Any] = [ "dont_print": [ "regex": "print\\(" ], ] - let example = Example(""" - // swiftlint:disable:next all dont_print - print("Hello, world") - """) - XCTAssertTrue(try violations(forExample: example, customRules: customRules).isEmpty) + let example = Example( + """ + // swiftlint:disable:next all dont_print + print("Hello, world") + """) + #expect(try violations(forExample: example, customRules: customRules).isEmpty) } - func testNestedCustomRuleDisablesDoNotTriggerSuperfluousDisableCommand() throws { + @Test + func nestedCustomRuleDisablesDoNotTriggerSuperfluousDisableCommand() throws { let customRules: [String: Any] = [ "rule1": [ "regex": "pattern1" @@ -446,18 +468,20 @@ final class CustomRulesTests: SwiftLintTestCase { "regex": "pattern2" ], ] - let example = Example(""" - // swiftlint:disable rule1 - // swiftlint:disable rule2 - let pattern2 = "" - // swiftlint:enable rule2 - let pattern1 = "" - // swiftlint:enable rule1 - """) - XCTAssertTrue(try violations(forExample: example, customRules: customRules).isEmpty) + let example = Example( + """ + // swiftlint:disable rule1 + // swiftlint:disable rule2 + let pattern2 = "" + // swiftlint:enable rule2 + let pattern1 = "" + // swiftlint:enable rule1 + """) + #expect(try violations(forExample: example, customRules: customRules).isEmpty) } - func testNestedAndOverlappingCustomRuleDisables() throws { + @Test + func nestedAndOverlappingCustomRuleDisables() throws { let customRules: [String: Any] = [ "rule1": [ "regex": "pattern1" @@ -481,11 +505,12 @@ final class CustomRulesTests: SwiftLintTestCase { """) let violations = try violations(forExample: example, customRules: customRules) - XCTAssertEqual(violations.count, 1) - XCTAssertTrue(violations[0].isSuperfluousDisableCommandViolation(for: "rule3")) + #expect(violations.count == 1) + #expect(violations[0].isSuperfluousDisableCommandViolation(for: "rule3")) } - func testSuperfluousDisableRuleOrder() throws { + @Test + func superfluousDisableRuleOrder() throws { let customRules: [String: Any] = [ "rule1": [ "regex": "pattern1" @@ -507,16 +532,17 @@ final class CustomRulesTests: SwiftLintTestCase { """) let violations = try violations(forExample: example, customRules: customRules) - XCTAssertEqual(violations.count, 4) - XCTAssertTrue(violations[0].isSuperfluousDisableCommandViolation(for: "rule1")) - XCTAssertTrue(violations[1].isSuperfluousDisableCommandViolation(for: "rule2")) - XCTAssertTrue(violations[2].isSuperfluousDisableCommandViolation(for: "rule3")) - XCTAssertTrue(violations[3].isSuperfluousDisableCommandViolation(for: "rule2")) + #expect(violations.count == 4) + #expect(violations[0].isSuperfluousDisableCommandViolation(for: "rule1")) + #expect(violations[1].isSuperfluousDisableCommandViolation(for: "rule2")) + #expect(violations[2].isSuperfluousDisableCommandViolation(for: "rule3")) + #expect(violations[3].isSuperfluousDisableCommandViolation(for: "rule2")) } // MARK: - ExecutionMode Tests (Phase 1) - func testRegexConfigurationParsesExecutionMode() throws { + @Test + func regexConfigurationParsesExecutionMode() throws { let configDict = [ "regex": "pattern", "execution_mode": "swiftsyntax", @@ -524,10 +550,11 @@ final class CustomRulesTests: SwiftLintTestCase { var regexConfig = Configuration(identifier: "test_rule") try regexConfig.apply(configuration: configDict) - XCTAssertEqual(regexConfig.executionMode, .swiftsyntax) + #expect(regexConfig.executionMode == .swiftsyntax) } - func testRegexConfigurationParsesSourceKitMode() throws { + @Test + func regexConfigurationParsesSourceKitMode() throws { let configDict = [ "regex": "pattern", "execution_mode": "sourcekit", @@ -535,32 +562,35 @@ final class CustomRulesTests: SwiftLintTestCase { var regexConfig = Configuration(identifier: "test_rule") try regexConfig.apply(configuration: configDict) - XCTAssertEqual(regexConfig.executionMode, .sourcekit) + #expect(regexConfig.executionMode == .sourcekit) } - func testRegexConfigurationWithoutModeIsDefault() throws { + @Test + func regexConfigurationWithoutModeIsDefault() throws { let configDict = [ "regex": "pattern", ] var regexConfig = Configuration(identifier: "test_rule") try regexConfig.apply(configuration: configDict) - XCTAssertEqual(regexConfig.executionMode, .default) + #expect(regexConfig.executionMode == .default) } - func testRegexConfigurationRejectsInvalidMode() { + @Test + func regexConfigurationRejectsInvalidMode() { let configDict = [ "regex": "pattern", "execution_mode": "invalid_mode", ] var regexConfig = Configuration(identifier: "test_rule") - checkError(Issue.invalidConfiguration(ruleID: CustomRules.identifier)) { + #expect(throws: Issue.invalidConfiguration(ruleID: CustomRules.identifier)) { try regexConfig.apply(configuration: configDict) } } - func testCustomRulesConfigurationParsesDefaultExecutionMode() throws { + @Test + func customRulesConfigurationParsesDefaultExecutionMode() throws { let configDict: [String: Any] = [ "default_execution_mode": "swiftsyntax", "my_rule": [ @@ -570,12 +600,13 @@ final class CustomRulesTests: SwiftLintTestCase { var customRulesConfig = CustomRulesConfiguration() try customRulesConfig.apply(configuration: configDict) - XCTAssertEqual(customRulesConfig.defaultExecutionMode, .swiftsyntax) - XCTAssertEqual(customRulesConfig.customRuleConfigurations.count, 1) - XCTAssertEqual(customRulesConfig.customRuleConfigurations[0].executionMode, .default) + #expect(customRulesConfig.defaultExecutionMode == .swiftsyntax) + #expect(customRulesConfig.customRuleConfigurations.count == 1) + #expect(customRulesConfig.customRuleConfigurations[0].executionMode == .default) } - func testCustomRulesAppliesDefaultModeToRulesWithoutExplicitMode() throws { + @Test + func customRulesAppliesDefaultModeToRulesWithoutExplicitMode() throws { let configDict: [String: Any] = [ "default_execution_mode": "sourcekit", "rule1": [ @@ -589,19 +620,20 @@ final class CustomRulesTests: SwiftLintTestCase { var customRulesConfig = CustomRulesConfiguration() try customRulesConfig.apply(configuration: configDict) - XCTAssertEqual(customRulesConfig.defaultExecutionMode, .sourcekit) - XCTAssertEqual(customRulesConfig.customRuleConfigurations.count, 2) + #expect(customRulesConfig.defaultExecutionMode == .sourcekit) + #expect(customRulesConfig.customRuleConfigurations.count == 2) // rule1 should have default mode let rule1 = customRulesConfig.customRuleConfigurations.first { $0.identifier == "rule1" } - XCTAssertEqual(rule1?.executionMode, .default) + #expect(rule1?.executionMode == .default) // rule2 should keep its explicit mode let rule2 = customRulesConfig.customRuleConfigurations.first { $0.identifier == "rule2" } - XCTAssertEqual(rule2?.executionMode, .swiftsyntax) + #expect(rule2?.executionMode == .swiftsyntax) } - func testCustomRulesConfigurationRejectsInvalidDefaultMode() { + @Test + func customRulesConfigurationRejectsInvalidDefaultMode() { let configDict: [String: Any] = [ "default_execution_mode": "invalid", "my_rule": [ @@ -610,20 +642,22 @@ final class CustomRulesTests: SwiftLintTestCase { ] var customRulesConfig = CustomRulesConfiguration() - checkError(Issue.invalidConfiguration(ruleID: CustomRules.identifier)) { + #expect(throws: Issue.invalidConfiguration(ruleID: CustomRules.identifier)) { try customRulesConfig.apply(configuration: configDict) } } - func testExecutionModeIncludedInCacheDescription() { + @Test + func executionModeIncludedInCacheDescription() { var regexConfig = Configuration(identifier: "test_rule") regexConfig.regex = "pattern" regexConfig.executionMode = .swiftsyntax - XCTAssertTrue(regexConfig.cacheDescription.contains("swiftsyntax")) + #expect(regexConfig.cacheDescription.contains("swiftsyntax")) } - func testExecutionModeAffectsHash() { + @Test + func executionModeAffectsHash() { var config1 = Configuration(identifier: "test_rule") config1.regex = "pattern" config1.executionMode = .swiftsyntax @@ -637,14 +671,15 @@ final class CustomRulesTests: SwiftLintTestCase { config3.executionMode = .default // Different execution modes should produce different hashes - XCTAssertNotEqual(config1.hashValue, config2.hashValue) - XCTAssertNotEqual(config1.hashValue, config3.hashValue) - XCTAssertNotEqual(config2.hashValue, config3.hashValue) + #expect(config1.hashValue != config2.hashValue) + #expect(config1.hashValue != config3.hashValue) + #expect(config2.hashValue != config3.hashValue) } // MARK: - Phase 2 Tests: SwiftSyntax Mode Execution - func testCustomRuleUsesSwiftSyntaxModeWhenConfigured() throws { + @Test + func customRuleUsesSwiftSyntaxModeWhenConfigured() throws { // Test that a rule configured with swiftsyntax mode works correctly let customRules: [String: Any] = [ "no_foo": [ @@ -657,14 +692,15 @@ final class CustomRulesTests: SwiftLintTestCase { let example = Example("let foo = 42") let violations = try violations(forExample: example, customRules: customRules) - XCTAssertEqual(violations.count, 1) - XCTAssertEqual(violations[0].ruleIdentifier, "no_foo") - XCTAssertEqual(violations[0].reason, "Don't use foo") - XCTAssertEqual(violations[0].location.line, 1) - XCTAssertEqual(violations[0].location.character, 5) + #expect(violations.count == 1) + #expect(violations[0].ruleIdentifier == "no_foo") + #expect(violations[0].reason == "Don't use foo") + #expect(violations[0].location.line == 1) + #expect(violations[0].location.character == 5) } - func testCustomRuleWithoutMatchKindsUsesSwiftSyntaxByDefault() throws { + @Test + func customRuleWithoutMatchKindsUsesSwiftSyntaxByDefault() throws { // When default_execution_mode is swiftsyntax, rules without match_kinds should use it let customRules: [String: Any] = [ "default_execution_mode": "swiftsyntax", @@ -678,14 +714,15 @@ final class CustomRulesTests: SwiftLintTestCase { let violations = try violations(forExample: example, customRules: customRules) // Should find both occurrences of 'bar' since no match_kinds filtering - XCTAssertEqual(violations.count, 2) - XCTAssertEqual(violations[0].location.line, 1) - XCTAssertEqual(violations[0].location.character, 5) - XCTAssertEqual(violations[1].location.line, 1) - XCTAssertEqual(violations[1].location.character, 18) + #expect(violations.count == 2) + #expect(violations[0].location.line == 1) + #expect(violations[0].location.character == 5) + #expect(violations[1].location.line == 1) + #expect(violations[1].location.character == 18) } - func testCustomRuleDefaultsToSourceKitWhenNoModeSpecified() throws { + @Test + func customRuleDefaultsToSourceKitWhenNoModeSpecified() throws { // When NO execution mode is specified (neither default nor per-rule), it should default to swiftsyntax let customRules: [String: Any] = [ "no_foo": [ @@ -698,9 +735,9 @@ final class CustomRulesTests: SwiftLintTestCase { let violations = try violations(forExample: example, customRules: customRules) // Should work correctly with implicit swiftsyntax mode - XCTAssertEqual(violations.count, 1) - XCTAssertEqual(violations[0].ruleIdentifier, "no_foo") - XCTAssertEqual(violations[0].reason, "Don't use foo") + #expect(violations.count == 1) + #expect(violations[0].ruleIdentifier == "no_foo") + #expect(violations[0].reason == "Don't use foo") // Verify the rule is effectively SourceKit-free let configuration = try SwiftLintFramework.Configuration(dict: [ @@ -709,15 +746,17 @@ final class CustomRulesTests: SwiftLintTestCase { ]) guard let customRule = configuration.rules.customRules else { - XCTFail("Expected CustomRules in configuration") + Issue.record("Expected CustomRules in configuration") return } - XCTAssertFalse(customRule.isEffectivelySourceKitFree, - "Rule depends on SourceKit") + #expect( + !customRule.isEffectivelySourceKitFree, + "Rule depends on SourceKit") } - func testCustomRuleWithMatchKindsUsesSwiftSyntaxWhenConfigured() throws { + @Test + func customRuleWithMatchKindsUsesSwiftSyntaxWhenConfigured() throws { // Phase 4: Rules with match_kinds in swiftsyntax mode should use SwiftSyntax bridging let customRules: [String: Any] = [ "comment_foo": [ @@ -735,12 +774,13 @@ final class CustomRulesTests: SwiftLintTestCase { let violations = try violations(forExample: example, customRules: customRules) // Should only match 'foo' in comment, not in code - XCTAssertEqual(violations.count, 1) - XCTAssertEqual(violations[0].location.line, 1) - XCTAssertEqual(violations[0].location.character, 23) // Position of 'foo' in comment + #expect(violations.count == 1) + #expect(violations[0].location.line == 1) + #expect(violations[0].location.character == 23) // Position of 'foo' in comment // Position of 'foo' in comment } - func testCustomRuleWithKindFilteringDefaultsToSourceKit() throws { + @Test + func customRuleWithKindFilteringDefaultsToSourceKit() throws { // When using kind filtering without specifying mode, it should default to sourcekit let customRules: [String: Any] = [ "no_keywords": [ @@ -754,9 +794,9 @@ final class CustomRulesTests: SwiftLintTestCase { let violations = try violations(forExample: example, customRules: customRules) // Should match 'foo' and '42' but not 'let' (keyword) - XCTAssertEqual(violations.count, 2) - XCTAssertEqual(violations[0].location.character, 5) // 'foo' - XCTAssertEqual(violations[1].location.character, 11) // '42' + #expect(violations.count == 2) + #expect(violations[0].location.character == 5) // 'foo' // 'foo' + #expect(violations[1].location.character == 11) // '42' // '42' // Verify the rule is effectively SourceKit-free let configuration = try SwiftLintFramework.Configuration(dict: [ @@ -765,15 +805,17 @@ final class CustomRulesTests: SwiftLintTestCase { ]) guard let customRule = configuration.rules.customRules else { - XCTFail("Expected CustomRules in configuration") + Issue.record("Expected CustomRules in configuration") return } - XCTAssertFalse(customRule.isEffectivelySourceKitFree, - "Rule with kind filtering should default to sourcekit mode") + #expect( + !customRule.isEffectivelySourceKitFree, + "Rule with kind filtering should default to sourcekit mode") } - func testCustomRuleWithExcludedMatchKindsUsesSwiftSyntaxWithDefaultMode() throws { + @Test + func customRuleWithExcludedMatchKindsUsesSwiftSyntaxWithDefaultMode() throws { // Phase 4: Rules with excluded_match_kinds should use SwiftSyntax when default mode is swiftsyntax let customRules: [String: Any] = [ "default_execution_mode": "swiftsyntax", @@ -791,14 +833,15 @@ final class CustomRulesTests: SwiftLintTestCase { let violations = try violations(forExample: example, customRules: customRules) // Should match 'foo' in code but not in comment - XCTAssertEqual(violations.count, 2) - XCTAssertEqual(violations[0].location.line, 1) - XCTAssertEqual(violations[0].location.character, 5) // 'foo' in variable name - XCTAssertEqual(violations[1].location.line, 2) - XCTAssertEqual(violations[1].location.character, 5) // 'foo' in foobar + #expect(violations.count == 2) + #expect(violations[0].location.line == 1) + #expect(violations[0].location.character == 5) // 'foo' in variable name // 'foo' in variable name + #expect(violations[1].location.line == 2) + #expect(violations[1].location.character == 5) // 'foo' in foobar // 'foo' in foobar } - func testSwiftSyntaxModeProducesSameResultsAsSourceKitForSimpleRules() throws { + @Test + func swiftSyntaxModeProducesSameResultsAsSourceKitForSimpleRules() throws { // Test that both modes produce identical results for rules without kind filtering let pattern = "\\bTODO\\b" let message = "TODOs should be resolved" @@ -831,18 +874,19 @@ final class CustomRulesTests: SwiftLintTestCase { let sourceKitViolations = try violations(forExample: example, customRules: sourceKitRules) // Both modes should produce identical results - XCTAssertEqual(swiftSyntaxViolations.count, sourceKitViolations.count) - XCTAssertEqual(swiftSyntaxViolations.count, 3) // Two in comments, one in string + #expect(swiftSyntaxViolations.count == sourceKitViolations.count) + #expect(swiftSyntaxViolations.count == 3) // Two in comments, one in string // Two in comments, one in string // Verify locations match for (ssViolation, skViolation) in zip(swiftSyntaxViolations, sourceKitViolations) { - XCTAssertEqual(ssViolation.location.line, skViolation.location.line) - XCTAssertEqual(ssViolation.location.character, skViolation.location.character) - XCTAssertEqual(ssViolation.reason, skViolation.reason) + #expect(ssViolation.location.line == skViolation.location.line) + #expect(ssViolation.location.character == skViolation.location.character) + #expect(ssViolation.reason == skViolation.reason) } } - func testSwiftSyntaxModeWithCaptureGroups() throws { + @Test + func swiftSyntaxModeWithCaptureGroups() throws { // Test that capture groups work correctly in SwiftSyntax mode let customRules: [String: Any] = [ "number_suffix": [ @@ -856,13 +900,14 @@ final class CustomRulesTests: SwiftLintTestCase { let example = Example("let value = 42_suffix + 100_suffix") let violations = try violations(forExample: example, customRules: customRules) - XCTAssertEqual(violations.count, 2) + #expect(violations.count == 2) // First capture group should highlight just the number part - XCTAssertEqual(violations[0].location.character, 13) // Position of "42" - XCTAssertEqual(violations[1].location.character, 25) // Position of "100" + #expect(violations[0].location.character == 13) // Position of "42" // Position of "42" + #expect(violations[1].location.character == 25) // Position of "100" // Position of "100" } - func testSwiftSyntaxModeRespectsIncludedExcludedPaths() throws { + @Test + func swiftSyntaxModeRespectsIncludedExcludedPaths() throws { // Verify that included/excluded path filtering works in SwiftSyntax mode var regexConfig = Configuration(identifier: "test_rule") regexConfig.regex = "pattern" @@ -870,30 +915,31 @@ final class CustomRulesTests: SwiftLintTestCase { regexConfig.included = [try RegularExpression(pattern: "\\.swift$")] regexConfig.excluded = [try RegularExpression(pattern: "Tests")] - XCTAssertTrue(regexConfig.shouldValidate(filePath: "/path/to/file.swift")) - XCTAssertFalse(regexConfig.shouldValidate(filePath: "/path/to/file.m")) - XCTAssertFalse(regexConfig.shouldValidate(filePath: "/path/to/Tests/file.swift")) + #expect(regexConfig.shouldValidate(filePath: "/path/to/file.swift")) + #expect(!regexConfig.shouldValidate(filePath: "/path/to/file.m")) + #expect(!regexConfig.shouldValidate(filePath: "/path/to/Tests/file.swift")) } // MARK: - only_rules support - func testOnlyRulesWithCustomRules() throws { + @Test + func onlyRulesWithCustomRules() throws { let ruleIdentifierToEnable = "aaa" let violations = try testOnlyRulesWithCustomRules([ruleIdentifierToEnable]) - XCTAssertEqual(violations.count, 1) - XCTAssertEqual(violations[0].ruleIdentifier, ruleIdentifierToEnable) + #expect(violations.count == 1) + #expect(violations[0].ruleIdentifier == ruleIdentifierToEnable) } - func testOnlyRulesWithIndividualIdentifiers() throws { + @Test + func onlyRulesWithIndividualIdentifiers() throws { let customRuleIdentifiers = ["aaa", "bbb"] let violationsWithIndividualRuleIdentifiers = try testOnlyRulesWithCustomRules(customRuleIdentifiers) - XCTAssertEqual(violationsWithIndividualRuleIdentifiers.count, 2) - XCTAssertEqual( - violationsWithIndividualRuleIdentifiers.map { $0.ruleIdentifier }, - customRuleIdentifiers + #expect(violationsWithIndividualRuleIdentifiers.count == 2) + #expect( + violationsWithIndividualRuleIdentifiers.map { $0.ruleIdentifier } == customRuleIdentifiers ) let violationsWithCustomRulesIdentifier = try testOnlyRulesWithCustomRules(["custom_rules"]) - XCTAssertEqual(violationsWithIndividualRuleIdentifiers, violationsWithCustomRulesIdentifier) + #expect(violationsWithIndividualRuleIdentifiers == violationsWithCustomRulesIdentifier) } // MARK: - Private @@ -946,7 +992,7 @@ final class CustomRulesTests: SwiftLintTestCase { do { try regexConfig.apply(configuration: configurationDict) } catch { - XCTFail("Failed regex config") + Issue.record("Failed regex config") } return regexConfig } @@ -961,7 +1007,8 @@ final class CustomRulesTests: SwiftLintTestCase { // MARK: - Phase 4 Tests: SwiftSyntax Mode WITH Kind Filtering - func testSwiftSyntaxModeWithMatchKindsProducesCorrectResults() throws { + @Test + func swiftSyntaxModeWithMatchKindsProducesCorrectResults() throws { // Test various syntax kinds with SwiftSyntax bridging let customRules: [String: Any] = [ "keyword_test": [ @@ -981,7 +1028,7 @@ final class CustomRulesTests: SwiftLintTestCase { let violations = try violations(forExample: example, customRules: customRules) // Should match 'let', 'func', and 'return' keywords - XCTAssertEqual(violations.count, 3) + #expect(violations.count == 3) // Verify the locations correspond to keywords let expectedLocations = [ @@ -991,12 +1038,13 @@ final class CustomRulesTests: SwiftLintTestCase { ] for (index, expected) in expectedLocations.enumerated() { - XCTAssertEqual(violations[index].location.line, expected.line) - XCTAssertEqual(violations[index].location.character, expected.character) + #expect(violations[index].location.line == expected.line) + #expect(violations[index].location.character == expected.character) } } - func testSwiftSyntaxModeWithExcludedKindsFiltersCorrectly() throws { + @Test + func swiftSyntaxModeWithExcludedKindsFiltersCorrectly() throws { // Test that excluded kinds are properly filtered out let customRules: [String: Any] = [ "no_identifier": [ @@ -1013,10 +1061,11 @@ final class CustomRulesTests: SwiftLintTestCase { let violations = try violations(forExample: example, customRules: customRules) // Should match 'let' (keyword) and '42' (number), but not 'value' or 'Int' - XCTAssertEqual(violations.count, 2) + #expect(violations.count == 2) } - func testSwiftSyntaxModeHandlesComplexKindMatching() throws { + @Test + func swiftSyntaxModeHandlesComplexKindMatching() throws { // Test matching multiple specific kinds let customRules: [String: Any] = [ "special_tokens": [ @@ -1035,10 +1084,11 @@ final class CustomRulesTests: SwiftLintTestCase { // Should match "Alice" (string), 25 (number), and "// User name" (comment) // The regex \S+ will match non-whitespace sequences - XCTAssertGreaterThanOrEqual(violations.count, 3) + #expect(violations.count >= 3) } - func testSwiftSyntaxModeWorksWithCaptureGroups() throws { + @Test + func swiftSyntaxModeWorksWithCaptureGroups() throws { // Test that capture groups work correctly with SwiftSyntax mode let customRules: [String: Any] = [ "string_content": [ @@ -1053,11 +1103,12 @@ final class CustomRulesTests: SwiftLintTestCase { let example = Example(#"let greeting = "Hello, World!""#) let violations = try violations(forExample: example, customRules: customRules) - XCTAssertEqual(violations.count, 1) - XCTAssertEqual(violations[0].location.character, 17) // Start of "Hello, World!" content + #expect(violations.count == 1) + #expect(violations[0].location.character == 17) // Start of "Hello, World!" content } - func testSwiftSyntaxModeRespectsSourceKitModeOverride() throws { + @Test + func swiftSyntaxModeRespectsSourceKitModeOverride() throws { // Test that explicit sourcekit mode overrides default swiftsyntax mode let customRules: [String: Any] = [ "default_execution_mode": "swiftsyntax", @@ -1073,11 +1124,12 @@ final class CustomRulesTests: SwiftLintTestCase { let violations = try violations(forExample: example, customRules: customRules) // Should still work correctly with explicit sourcekit mode - XCTAssertEqual(violations.count, 1) - XCTAssertEqual(violations[0].location.character, 5) + #expect(violations.count == 1) + #expect(violations[0].location.character == 5) } - func testSwiftSyntaxModeHandlesEmptyBridging() throws { + @Test + func swiftSyntaxModeHandlesEmptyBridging() throws { // Test graceful handling when no tokens match the specified kinds let customRules: [String: Any] = [ "attribute_only": [ @@ -1092,7 +1144,7 @@ final class CustomRulesTests: SwiftLintTestCase { let violations = try violations(forExample: example, customRules: customRules) // Should produce no violations since there are no built-in attributes - XCTAssertEqual(violations.count, 0) + #expect(violations.isEmpty) } private func testOnlyRulesWithCustomRules(_ onlyRulesIdentifiers: [String]) throws -> [StyleViolation] { diff --git a/Tests/FrameworkTests/EmptyFileTests.swift b/Tests/FrameworkTests/EmptyFileTests.swift index b83502fba7..e73d3b5b49 100644 --- a/Tests/FrameworkTests/EmptyFileTests.swift +++ b/Tests/FrameworkTests/EmptyFileTests.swift @@ -1,13 +1,12 @@ import SwiftLintFramework -import TestHelpers -import XCTest +import Testing -// swiftlint:disable:next balanced_xctest_lifecycle -final class EmptyFileTests: SwiftLintTestCase { - var collectedLinter: CollectedLinter! // swiftlint:disable:this implicitly_unwrapped_optional - var ruleStorage: RuleStorage! // swiftlint:disable:this implicitly_unwrapped_optional +@Suite +struct EmptyFileTests { + var collectedLinter: CollectedLinter! // swiftlint:disable:this implicitly_unwrapped_optional + var ruleStorage: RuleStorage! // swiftlint:disable:this implicitly_unwrapped_optional - override func setUpWithError() throws { + init() throws { let ruleList = RuleList(rules: RuleMock.self, RuleMock.self) let configuration = try Configuration(dict: [:], ruleList: ruleList) let file = SwiftLintFile(contents: "") @@ -16,15 +15,17 @@ final class EmptyFileTests: SwiftLintTestCase { collectedLinter = linter.collect(into: ruleStorage) } - func testShouldLintEmptyFileRespectedDuringLint() throws { + @Test + func shouldLintEmptyFileRespectedDuringLint() throws { let styleViolations = collectedLinter.styleViolations(using: ruleStorage) - XCTAssertEqual(styleViolations.count, 1) - XCTAssertEqual(styleViolations.first?.ruleIdentifier, "rule_mock") + #expect(styleViolations.count == 1) + #expect(styleViolations.first?.ruleIdentifier == "rule_mock") } - func testShouldLintEmptyFileRespectedDuringCorrect() throws { + @Test + func shouldLintEmptyFileRespectedDuringCorrect() throws { let corrections = collectedLinter.correct(using: ruleStorage) - XCTAssertEqual(corrections, ["rule_mock": 1]) + #expect(corrections == ["rule_mock": 1]) } } @@ -44,11 +45,12 @@ private struct RuleMock: Cor var configuration = SeverityConfiguration(.warning) static var description: RuleDescription { - RuleDescription(identifier: "rule_mock<\(ShouldLintEmptyFiles.self)>", - name: "", - description: "", - kind: .style, - deprecatedAliases: ["mock"]) + RuleDescription( + identifier: "rule_mock<\(ShouldLintEmptyFiles.self)>", + name: "", + description: "", + kind: .style, + deprecatedAliases: ["mock"]) } var shouldLintEmptyFiles: Bool { diff --git a/Tests/FrameworkTests/LintOrAnalyzeOptionsTests.swift b/Tests/FrameworkTests/LintOrAnalyzeOptionsTests.swift index 07ec490791..09f20e68cc 100644 --- a/Tests/FrameworkTests/LintOrAnalyzeOptionsTests.swift +++ b/Tests/FrameworkTests/LintOrAnalyzeOptionsTests.swift @@ -1,10 +1,12 @@ @testable import SwiftLintFramework -import XCTest +import Testing -final class LintOrAnalyzeOptionsTests: XCTestCase { +@Suite +struct LintOrAnalyzeOptionsTests { private typealias Leniency = LintOrAnalyzeOptions.Leniency - func testLeniency() { + @Test + func leniency() { let parameters = [ Leniency(strict: false, lenient: false), Leniency(strict: true, lenient: true), @@ -18,20 +20,20 @@ final class LintOrAnalyzeOptionsTests: XCTestCase { let leniency = options.leniency(strict: configuration.strict, lenient: configuration.lenient) if commandLine.strict { // Command line takes precedence. - XCTAssertTrue(leniency.strict) + #expect(leniency.strict) if !commandLine.lenient { // `--strict` should disable configuration lenience. - XCTAssertFalse(leniency.lenient) + #expect(!leniency.lenient) } } else if commandLine.lenient { // Command line takes precedence, and should override // `strict` in the configuration. - XCTAssertTrue(leniency.lenient) - XCTAssertFalse(leniency.strict) + #expect(leniency.lenient) + #expect(!leniency.strict) } else if configuration.strict { - XCTAssertTrue(leniency.strict) + #expect(leniency.strict) } else if configuration.lenient { - XCTAssertTrue(leniency.lenient) + #expect(leniency.lenient) } } } diff --git a/Tests/FrameworkTests/LinterCacheTests.swift b/Tests/FrameworkTests/LinterCacheTests.swift index 66c2cb6bda..1d25c21bda 100644 --- a/Tests/FrameworkTests/LinterCacheTests.swift +++ b/Tests/FrameworkTests/LinterCacheTests.swift @@ -1,7 +1,7 @@ import Foundation @testable import SwiftLintFramework import TestHelpers -import XCTest +import Testing private struct CacheTestHelper { fileprivate let configuration: Configuration @@ -69,7 +69,8 @@ private class TestFileManager: LintableFileManager { } } -final class LinterCacheTests: SwiftLintTestCase { +@Suite(.rulesRegistered) +final class LinterCacheTests { // MARK: Test Helpers private var cache = LinterCache(fileManager: TestFileManager()) @@ -81,16 +82,18 @@ final class LinterCacheTests: SwiftLintTestCase { private func cacheAndValidate(violations: [StyleViolation], forFile: String, configuration: Configuration, - file: StaticString = #filePath, + file: String = #filePath, line: UInt = #line) { cache.cache(violations: violations, forFile: forFile, configuration: configuration) cache = cache.flushed() - XCTAssertEqual(cache.violations(forFile: forFile, configuration: configuration)!, - violations, file: (file), line: line) + #expect( + cache.violations(forFile: forFile, configuration: configuration)! == violations, + sourceLocation: SourceLocation(fileID: #fileID, filePath: file, line: Int(line), column: 1) + ) } private func cacheAndValidateNoViolationsTwoFiles(configuration: Configuration, - file: StaticString = #filePath, + file: String = #filePath, line: UInt = #line) { let (file1, file2) = ("file1.swift", "file2.swift") // swiftlint:disable:next force_cast @@ -103,22 +106,36 @@ final class LinterCacheTests: SwiftLintTestCase { private func validateNewConfigDoesntHitCache(dict: [String: Any], initialConfig: Configuration, - file: StaticString = #filePath, + file: String = #filePath, line: UInt = #line) throws { let newConfig = try Configuration(dict: dict) let (file1, file2) = ("file1.swift", "file2.swift") + let location = SourceLocation(fileID: #fileID, filePath: file, line: Int(line), column: 1) - XCTAssertNil(cache.violations(forFile: file1, configuration: newConfig), file: (file), line: line) - XCTAssertNil(cache.violations(forFile: file2, configuration: newConfig), file: (file), line: line) + #expect( + cache.violations(forFile: file1, configuration: newConfig) == nil, + sourceLocation: location + ) + #expect( + cache.violations(forFile: file2, configuration: newConfig) == nil, + sourceLocation: location + ) - XCTAssertEqual(cache.violations(forFile: file1, configuration: initialConfig)!, [], file: (file), line: line) - XCTAssertEqual(cache.violations(forFile: file2, configuration: initialConfig)!, [], file: (file), line: line) + #expect( + cache.violations(forFile: file1, configuration: initialConfig)!.isEmpty, + sourceLocation: location + ) + #expect( + cache.violations(forFile: file2, configuration: initialConfig)!.isEmpty, + sourceLocation: location + ) } // MARK: Cache Reuse // Two subsequent lints with no changes reuses cache - func testUnchangedFilesReusesCache() { + @Test + func unchangedFilesReusesCache() { let helper = makeCacheTestHelper(dict: ["only_rules": ["mock"]]) let file = "foo.swift" let violations = helper.makeViolations(file: file) @@ -126,50 +143,54 @@ final class LinterCacheTests: SwiftLintTestCase { cacheAndValidate(violations: violations, forFile: file, configuration: helper.configuration) helper.touch(file: file) - XCTAssertNil(cache.violations(forFile: file, configuration: helper.configuration)) + #expect(cache.violations(forFile: file, configuration: helper.configuration) == nil) } - func testConfigFileReorderedReusesCache() { + @Test + func configFileReorderedReusesCache() { let helper = makeCacheTestHelper(dict: ["only_rules": ["mock"], "disabled_rules": [Any]()]) let file = "foo.swift" let violations = helper.makeViolations(file: file) cacheAndValidate(violations: violations, forFile: file, configuration: helper.configuration) let configuration2 = helper.makeConfig(dict: ["disabled_rules": [Any](), "only_rules": ["mock"]]) - XCTAssertEqual(cache.violations(forFile: file, configuration: configuration2)!, violations) + #expect(cache.violations(forFile: file, configuration: configuration2)! == violations) } - func testConfigFileWhitespaceAndCommentsChangedOrAddedOrRemovedReusesCache() throws { + @Test + func configFileWhitespaceAndCommentsChangedOrAddedOrRemovedReusesCache() throws { let helper = makeCacheTestHelper(dict: try YamlParser.parse("only_rules:\n - mock")) let file = "foo.swift" let violations = helper.makeViolations(file: file) cacheAndValidate(violations: violations, forFile: file, configuration: helper.configuration) let configuration2 = helper.makeConfig(dict: ["disabled_rules": [Any](), "only_rules": ["mock"]]) - XCTAssertEqual(cache.violations(forFile: file, configuration: configuration2)!, violations) + #expect(cache.violations(forFile: file, configuration: configuration2)! == violations) let configYamlWithComment = try YamlParser.parse("# comment1\nonly_rules:\n - mock # comment2") let configuration3 = helper.makeConfig(dict: configYamlWithComment) - XCTAssertEqual(cache.violations(forFile: file, configuration: configuration3)!, violations) - XCTAssertEqual(cache.violations(forFile: file, configuration: helper.configuration)!, violations) + #expect(cache.violations(forFile: file, configuration: configuration3)! == violations) + #expect(cache.violations(forFile: file, configuration: helper.configuration)! == violations) } - func testConfigFileUnrelatedKeysChangedOrAddedOrRemovedReusesCache() { + @Test + func configFileUnrelatedKeysChangedOrAddedOrRemovedReusesCache() { let helper = makeCacheTestHelper(dict: ["only_rules": ["mock"], "reporter": "json"]) let file = "foo.swift" let violations = helper.makeViolations(file: file) cacheAndValidate(violations: violations, forFile: file, configuration: helper.configuration) let configuration2 = helper.makeConfig(dict: ["only_rules": ["mock"], "reporter": "xcode"]) - XCTAssertEqual(cache.violations(forFile: file, configuration: configuration2)!, violations) + #expect(cache.violations(forFile: file, configuration: configuration2)! == violations) let configuration3 = helper.makeConfig(dict: ["only_rules": ["mock"]]) - XCTAssertEqual(cache.violations(forFile: file, configuration: configuration3)!, violations) + #expect(cache.violations(forFile: file, configuration: configuration3)! == violations) } // MARK: Sing-File Cache Invalidation // Two subsequent lints with a file touch in between causes just that one // file to be re-linted, with the cache used for all other files - func testChangedFileCausesJustThatFileToBeLintWithCacheUsedForAllOthers() { + @Test + func changedFileCausesJustThatFileToBeLintWithCacheUsedForAllOthers() { let helper = makeCacheTestHelper(dict: ["only_rules": ["mock"], "reporter": "json"]) let (file1, file2) = ("file1.swift", "file2.swift") let violations1 = helper.makeViolations(file: file1) @@ -178,11 +199,12 @@ final class LinterCacheTests: SwiftLintTestCase { cacheAndValidate(violations: violations1, forFile: file1, configuration: helper.configuration) cacheAndValidate(violations: violations2, forFile: file2, configuration: helper.configuration) helper.touch(file: file2) - XCTAssertEqual(cache.violations(forFile: file1, configuration: helper.configuration)!, violations1) - XCTAssertNil(cache.violations(forFile: file2, configuration: helper.configuration)) + #expect(cache.violations(forFile: file1, configuration: helper.configuration)! == violations1) + #expect(cache.violations(forFile: file2, configuration: helper.configuration) == nil) } - func testFileRemovedPreservesThatFileInTheCacheAndDoesntCauseAnyOtherFilesToBeLinted() { + @Test + func fileRemovedPreservesThatFileInTheCacheAndDoesntCauseAnyOtherFilesToBeLinted() { let helper = makeCacheTestHelper(dict: ["only_rules": ["mock"], "reporter": "json"]) let (file1, file2) = ("file1.swift", "file2.swift") let violations1 = helper.makeViolations(file: file1) @@ -190,15 +212,16 @@ final class LinterCacheTests: SwiftLintTestCase { cacheAndValidate(violations: violations1, forFile: file1, configuration: helper.configuration) cacheAndValidate(violations: violations2, forFile: file2, configuration: helper.configuration) - XCTAssertEqual(helper.fileCount(), 2) + #expect(helper.fileCount() == 2) helper.remove(file: file2) - XCTAssertEqual(cache.violations(forFile: file1, configuration: helper.configuration)!, violations1) - XCTAssertEqual(helper.fileCount(), 1) + #expect(cache.violations(forFile: file1, configuration: helper.configuration)! == violations1) + #expect(helper.fileCount() == 1) } // MARK: All-File Cache Invalidation - func testCustomRulesChangedOrAddedOrRemovedCausesAllFilesToBeReLinted() throws { + @Test + func customRulesChangedOrAddedOrRemovedCausesAllFilesToBeReLinted() throws { let initialConfig = try Configuration( dict: [ "only_rules": ["custom_rules", "rule1"], @@ -230,7 +253,8 @@ final class LinterCacheTests: SwiftLintTestCase { try validateNewConfigDoesntHitCache(dict: ["only_rules": ["custom_rules"]], initialConfig: initialConfig) } - func testDisabledRulesChangedOrAddedOrRemovedCausesAllFilesToBeReLinted() throws { + @Test + func disabledRulesChangedOrAddedOrRemovedCausesAllFilesToBeReLinted() throws { let initialConfig = try Configuration(dict: ["disabled_rules": ["nesting"]]) cacheAndValidateNoViolationsTwoFiles(configuration: initialConfig) @@ -242,7 +266,8 @@ final class LinterCacheTests: SwiftLintTestCase { try validateNewConfigDoesntHitCache(dict: ["disabled_rules": [Any]()], initialConfig: initialConfig) } - func testOptInRulesChangedOrAddedOrRemovedCausesAllFilesToBeReLinted() throws { + @Test + func optInRulesChangedOrAddedOrRemovedCausesAllFilesToBeReLinted() throws { let initialConfig = try Configuration(dict: ["opt_in_rules": ["attributes"]]) cacheAndValidateNoViolationsTwoFiles(configuration: initialConfig) @@ -255,7 +280,8 @@ final class LinterCacheTests: SwiftLintTestCase { try validateNewConfigDoesntHitCache(dict: ["opt_in_rules": [Any]()], initialConfig: initialConfig) } - func testEnabledRulesChangedOrAddedOrRemovedCausesAllFilesToBeReLinted() throws { + @Test + func enabledRulesChangedOrAddedOrRemovedCausesAllFilesToBeReLinted() throws { let initialConfig = try Configuration(dict: ["enabled_rules": ["attributes"]]) cacheAndValidateNoViolationsTwoFiles(configuration: initialConfig) @@ -268,7 +294,8 @@ final class LinterCacheTests: SwiftLintTestCase { try validateNewConfigDoesntHitCache(dict: ["enabled_rules": [Any]()], initialConfig: initialConfig) } - func testOnlyRulesChangedOrAddedOrRemovedCausesAllFilesToBeReLinted() throws { + @Test + func onlyRulesChangedOrAddedOrRemovedCausesAllFilesToBeReLinted() throws { let initialConfig = try Configuration(dict: ["only_rules": ["nesting"]]) cacheAndValidateNoViolationsTwoFiles(configuration: initialConfig) @@ -280,7 +307,8 @@ final class LinterCacheTests: SwiftLintTestCase { try validateNewConfigDoesntHitCache(dict: ["only_rules": [Any]()], initialConfig: initialConfig) } - func testRuleConfigurationChangedOrAddedOrRemovedCausesAllFilesToBeReLinted() throws { + @Test + func ruleConfigurationChangedOrAddedOrRemovedCausesAllFilesToBeReLinted() throws { let initialConfig = try Configuration(dict: ["line_length": 120]) cacheAndValidateNoViolationsTwoFiles(configuration: initialConfig) @@ -293,7 +321,8 @@ final class LinterCacheTests: SwiftLintTestCase { try validateNewConfigDoesntHitCache(dict: [:], initialConfig: initialConfig) } - func testSwiftVersionChangedRemovedCausesAllFilesToBeReLinted() { + @Test + func swiftVersionChangedRemovedCausesAllFilesToBeReLinted() { let fileManager = TestFileManager() cache = LinterCache(fileManager: fileManager) let helper = makeCacheTestHelper(dict: [:]) @@ -306,7 +335,7 @@ final class LinterCacheTests: SwiftLintTestCase { let differentSwiftVersion: SwiftVersion = .five cache = LinterCache(fileManager: fileManager, swiftVersion: differentSwiftVersion) - XCTAssertNotNil(thisSwiftVersionCache.violations(forFile: file, configuration: helper.configuration)) - XCTAssertNil(cache.violations(forFile: file, configuration: helper.configuration)) + #expect(thisSwiftVersionCache.violations(forFile: file, configuration: helper.configuration) != nil) + #expect(cache.violations(forFile: file, configuration: helper.configuration) == nil) } } diff --git a/Tests/FrameworkTests/ParserDiagnosticsTests.swift b/Tests/FrameworkTests/ParserDiagnosticsTests.swift index fad92d20d9..ce68e2be17 100644 --- a/Tests/FrameworkTests/ParserDiagnosticsTests.swift +++ b/Tests/FrameworkTests/ParserDiagnosticsTests.swift @@ -1,54 +1,55 @@ +import TestHelpers +import Testing + @testable import SwiftLintBuiltInRules @testable import SwiftLintCore -import TestHelpers -import XCTest -final class ParserDiagnosticsTests: SwiftLintTestCase { - func testFileWithParserErrorDiagnostics() { - $parserDiagnosticsDisabledForTests.withValue(false) { - XCTAssertNotNil(SwiftLintFile(contents: "importz Foundation").parserDiagnostics) - } +@Suite(.parserDiagnosticsEnabled(true)) +struct ParserDiagnosticsTests { + @Test + func fileWithParserErrorDiagnostics() { + #expect(SwiftLintFile(contents: "importz Foundation").parserDiagnostics.isNotEmpty) } - func testFileWithParserErrorDiagnosticsDoesntAutocorrect() throws { - let contents = """ - print(CGPointZero)) - """ - XCTAssertEqual(SwiftLintFile(contents: contents).parserDiagnostics, ["extraneous code \')\' at top level"]) + @Test + func fileWithParserErrorDiagnosticsDoesntAutocorrect() throws { + let contents = "print(CGPointZero))" + #expect(SwiftLintFile(contents: contents).parserDiagnostics == ["extraneous code \')\' at top level"]) let ruleDescription = LegacyConstantRule.description .with(corrections: [Example(contents): Example(contents)]) - let config = try XCTUnwrap(makeConfig(nil, ruleDescription.identifier, skipDisableCommandTests: true)) - verifyCorrections(ruleDescription, config: config, disableCommands: [], - testMultiByteOffsets: false, parserDiagnosticsDisabledForTests: false) + verifyCorrections( + ruleDescription, + config: try #require(makeConfig(nil, ruleDescription.identifier, skipDisableCommandTests: true)), + disableCommands: [], + testMultiByteOffsets: false, + parserDiagnosticsDisabledForTests: false + ) } - func testFileWithParserWarningDiagnostics() throws { + @Test + func fileWithParserWarningDiagnostics() throws { // extraneous duplicate parameter name; 'bar' already has an argument label - let original = """ - func foo(bar bar: String) -> Int { 0 } - """ - - let corrected = """ - func foo(bar bar: String) -> Int { 0 } - """ + let original = "func foo(bar bar: String) -> Int { 0 }" + let corrected = "func foo(bar bar: String) -> Int { 0 }" - $parserDiagnosticsDisabledForTests.withValue(false) { - XCTAssertEqual(SwiftLintFile(contents: original).parserDiagnostics, []) - } + #expect(SwiftLintFile(contents: original).parserDiagnostics.isEmpty) let ruleDescription = ReturnArrowWhitespaceRule.description .with(corrections: [Example(original): Example(corrected)]) - let config = try XCTUnwrap(makeConfig(nil, ruleDescription.identifier, skipDisableCommandTests: true)) - verifyCorrections(ruleDescription, config: config, disableCommands: [], - testMultiByteOffsets: false, parserDiagnosticsDisabledForTests: false) + verifyCorrections( + ruleDescription, + config: try #require(makeConfig(nil, ruleDescription.identifier, skipDisableCommandTests: true)), + disableCommands: [], + testMultiByteOffsets: false, + parserDiagnosticsDisabledForTests: false + ) } - func testFileWithoutParserDiagnostics() { - $parserDiagnosticsDisabledForTests.withValue(false) { - XCTAssertEqual(SwiftLintFile(contents: "import Foundation").parserDiagnostics, []) - } + @Test + func fileWithoutParserDiagnostics() throws { + #expect(SwiftLintFile(contents: "import Foundation").parserDiagnostics.isEmpty) } } diff --git a/Tests/FrameworkTests/RuleConfigurationTests.swift b/Tests/FrameworkTests/RuleConfigurationTests.swift index 4ac11de6c8..0594e0be8a 100644 --- a/Tests/FrameworkTests/RuleConfigurationTests.swift +++ b/Tests/FrameworkTests/RuleConfigurationTests.swift @@ -1,287 +1,324 @@ import SourceKittenFramework +import TestHelpers +import Testing + @testable import SwiftLintBuiltInRules @testable import SwiftLintCore -import TestHelpers -import XCTest -final class RuleConfigurationTests: SwiftLintTestCase { +@Suite +struct RuleConfigurationTests { private let defaultNestingConfiguration = NestingConfiguration( typeLevel: SeverityLevelsConfiguration(warning: 0), functionLevel: SeverityLevelsConfiguration(warning: 0) ) - func testNestingConfigurationSetsCorrectly() { - let config = [ - "type_level": [ - "warning": 7, "error": 17 - ], - "function_level": [ - "warning": 8, "error": 18 - ], - "check_nesting_in_closures_and_statements": false, - "always_allow_one_type_in_functions": true, - ] as [String: any Sendable] + @Test + func nestingConfigurationSetsCorrectly() { + let config = + [ + "type_level": [ + "warning": 7, "error": 17, + ], + "function_level": [ + "warning": 8, "error": 18, + ], + "check_nesting_in_closures_and_statements": false, + "always_allow_one_type_in_functions": true, + ] as [String: any Sendable] var nestingConfig = defaultNestingConfiguration do { try nestingConfig.apply(configuration: config) - XCTAssertEqual(nestingConfig.typeLevel.warning, 7) - XCTAssertEqual(nestingConfig.functionLevel.warning, 8) - XCTAssertEqual(nestingConfig.typeLevel.error, 17) - XCTAssertEqual(nestingConfig.functionLevel.error, 18) - XCTAssert(nestingConfig.alwaysAllowOneTypeInFunctions) - XCTAssert(!nestingConfig.checkNestingInClosuresAndStatements) + #expect(nestingConfig.typeLevel.warning == 7) + #expect(nestingConfig.functionLevel.warning == 8) + #expect(nestingConfig.typeLevel.error == 17) + #expect(nestingConfig.functionLevel.error == 18) + #expect(nestingConfig.alwaysAllowOneTypeInFunctions) + #expect(!nestingConfig.checkNestingInClosuresAndStatements) } catch { - XCTFail("Failed to configure nested configurations") + Issue.record("Failed to configure nested configurations") } } - func testNestingConfigurationThrowsOnBadConfig() { + @Test + func nestingConfigurationThrowsOnBadConfig() { let config = 17 var nestingConfig = defaultNestingConfiguration - checkError(Issue.invalidConfiguration(ruleID: NestingRule.identifier)) { + #expect(throws: Issue.invalidConfiguration(ruleID: NestingRule.identifier)) { try nestingConfig.apply(configuration: config) } } - func testSeverityWorksAsOnlyParameter() throws { + @Test + func severityWorksAsOnlyParameter() throws { var config = AttributesConfiguration() - XCTAssertEqual(config.severity, .warning) + #expect(config.severity == .warning) try config.apply(configuration: "error") - XCTAssertEqual(config.severity, .error) + #expect(config.severity == .error) } - func testSeverityConfigurationFromString() { + @Test + func severityConfigurationFromString() { let config = "Warning" let comp = SeverityConfiguration(.warning) var severityConfig = SeverityConfiguration(.error) - do { + #expect(throws: Never.self) { try severityConfig.apply(configuration: config) - XCTAssertEqual(severityConfig, comp) - } catch { - XCTFail("Failed to configure severity from string") } + #expect(severityConfig == comp) } - func testSeverityConfigurationFromDictionary() { + @Test + func severityConfigurationFromDictionary() { let config = ["severity": "warning"] let comp = SeverityConfiguration(.warning) var severityConfig = SeverityConfiguration(.error) do { try severityConfig.apply(configuration: config) - XCTAssertEqual(severityConfig, comp) + #expect(severityConfig == comp) } catch { - XCTFail("Failed to configure severity from dictionary") + Issue.record("Failed to configure severity from dictionary") } } - func testSeverityConfigurationThrowsNothingApplied() throws { + @Test + func severityConfigurationThrowsNothingApplied() throws { let config = 17 var severityConfig = SeverityConfiguration(.error) - checkError(Issue.nothingApplied(ruleID: RuleMock.identifier)) { + #expect(throws: Issue.nothingApplied(ruleID: RuleMock.identifier)) { try severityConfig.apply(configuration: config) } } - func testSeverityConfigurationThrowsInvalidConfiguration() { + @Test + func severityConfigurationThrowsInvalidConfiguration() { let config = "foo" var severityConfig = SeverityConfiguration(.warning) - checkError(Issue.invalidConfiguration(ruleID: RuleMock.identifier)) { + #expect(throws: Issue.invalidConfiguration(ruleID: RuleMock.identifier)) { try severityConfig.apply(configuration: config) } } - func testSeverityLevelConfigParams() { + @Test + func severityLevelConfigParams() { let severityConfig = SeverityLevelsConfiguration(warning: 17, error: 7) - XCTAssertEqual( - severityConfig.params, - [RuleParameter(severity: .error, value: 7), RuleParameter(severity: .warning, value: 17)] + #expect( + severityConfig.params == [ + RuleParameter(severity: .error, value: 7), + RuleParameter(severity: .warning, value: 17), + ] ) } - func testSeverityLevelConfigPartialParams() { + @Test + func severityLevelConfigPartialParams() { let severityConfig = SeverityLevelsConfiguration(warning: 17, error: nil) - XCTAssertEqual(severityConfig.params, [RuleParameter(severity: .warning, value: 17)]) + #expect(severityConfig.params == [RuleParameter(severity: .warning, value: 17)]) } - func testSeverityLevelConfigApplyNilErrorValue() throws { + @Test + func severityLevelConfigApplyNilErrorValue() throws { var severityConfig = SeverityLevelsConfiguration(warning: 17, error: 20) try severityConfig.apply(configuration: ["error": nil, "warning": 18]) - XCTAssertEqual(severityConfig.params, [RuleParameter(severity: .warning, value: 18)]) + #expect(severityConfig.params == [RuleParameter(severity: .warning, value: 18)]) } - func testSeverityLevelConfigApplyMissingErrorValue() throws { + @Test + func severityLevelConfigApplyMissingErrorValue() throws { var severityConfig = SeverityLevelsConfiguration(warning: 17, error: 20) try severityConfig.apply(configuration: ["warning": 18]) - XCTAssertEqual(severityConfig.params, [RuleParameter(severity: .warning, value: 18)]) + #expect(severityConfig.params == [RuleParameter(severity: .warning, value: 18)]) } - func testRegexConfigurationThrows() { + @Test + func regexConfigurationThrows() { let config = 17 var regexConfig = RegexConfiguration(identifier: "") - checkError(Issue.invalidConfiguration(ruleID: RuleMock.identifier)) { + #expect(throws: Issue.invalidConfiguration(ruleID: RuleMock.identifier)) { try regexConfig.apply(configuration: config) } } - func testRegexRuleDescription() { + @Test + func regexRuleDescription() { var regexConfig = RegexConfiguration(identifier: "regex") - XCTAssertEqual(regexConfig.description, RuleDescription(identifier: "regex", - name: "regex", - description: "", kind: .style)) + #expect( + regexConfig.description + == RuleDescription( + identifier: "regex", + name: "regex", + description: "", kind: .style)) regexConfig.name = "name" - XCTAssertEqual(regexConfig.description, RuleDescription(identifier: "regex", - name: "name", - description: "", kind: .style)) + #expect( + regexConfig.description + == RuleDescription( + identifier: "regex", + name: "name", + description: "", kind: .style)) } - func testTrailingWhitespaceConfigurationThrowsOnBadConfig() { + @Test + func trailingWhitespaceConfigurationThrowsOnBadConfig() { let config = "unknown" - var configuration = TrailingWhitespaceConfiguration(ignoresEmptyLines: false, - ignoresComments: true) - checkError(Issue.invalidConfiguration(ruleID: TrailingWhitespaceRule.identifier)) { + var configuration = TrailingWhitespaceConfiguration( + ignoresEmptyLines: false, + ignoresComments: true) + #expect(throws: Issue.invalidConfiguration(ruleID: TrailingWhitespaceRule.identifier)) { try configuration.apply(configuration: config) } } - func testTrailingWhitespaceConfigurationInitializerSetsIgnoresEmptyLines() { - let configuration1 = TrailingWhitespaceConfiguration(ignoresEmptyLines: false, - ignoresComments: true) - XCTAssertFalse(configuration1.ignoresEmptyLines) + @Test + func trailingWhitespaceConfigurationInitializerSetsIgnoresEmptyLines() { + let configuration1 = TrailingWhitespaceConfiguration( + ignoresEmptyLines: false, + ignoresComments: true) + #expect(!configuration1.ignoresEmptyLines) - let configuration2 = TrailingWhitespaceConfiguration(ignoresEmptyLines: true, - ignoresComments: true) - XCTAssertTrue(configuration2.ignoresEmptyLines) + let configuration2 = TrailingWhitespaceConfiguration( + ignoresEmptyLines: true, + ignoresComments: true) + #expect(configuration2.ignoresEmptyLines) } - func testTrailingWhitespaceConfigurationInitializerSetsIgnoresComments() { - let configuration1 = TrailingWhitespaceConfiguration(ignoresEmptyLines: false, - ignoresComments: true) - XCTAssertTrue(configuration1.ignoresComments) + @Test + func trailingWhitespaceConfigurationInitializerSetsIgnoresComments() { + let configuration1 = TrailingWhitespaceConfiguration( + ignoresEmptyLines: false, + ignoresComments: true) + #expect(configuration1.ignoresComments) - let configuration2 = TrailingWhitespaceConfiguration(ignoresEmptyLines: false, - ignoresComments: false) - XCTAssertFalse(configuration2.ignoresComments) + let configuration2 = TrailingWhitespaceConfiguration( + ignoresEmptyLines: false, + ignoresComments: false) + #expect(!configuration2.ignoresComments) } - func testTrailingWhitespaceConfigurationApplyConfigurationSetsIgnoresEmptyLines() { - var configuration = TrailingWhitespaceConfiguration(ignoresEmptyLines: false, - ignoresComments: true) - do { - let config1 = ["ignores_empty_lines": true] + @Test + func trailingWhitespaceConfigurationApplyConfigurationSetsIgnoresEmptyLines() { + var configuration = TrailingWhitespaceConfiguration( + ignoresEmptyLines: false, + ignoresComments: true + ) + let config1 = ["ignores_empty_lines": true] + #expect(throws: Never.self) { try configuration.apply(configuration: config1) - XCTAssertTrue(configuration.ignoresEmptyLines) + } + #expect(configuration.ignoresEmptyLines) - let config2 = ["ignores_empty_lines": false] + let config2 = ["ignores_empty_lines": false] + #expect(throws: Never.self) { try configuration.apply(configuration: config2) - XCTAssertFalse(configuration.ignoresEmptyLines) - } catch { - XCTFail("Failed to apply ignores_empty_lines") } + #expect(!configuration.ignoresEmptyLines) } - func testTrailingWhitespaceConfigurationApplyConfigurationSetsIgnoresComments() { - var configuration = TrailingWhitespaceConfiguration(ignoresEmptyLines: false, - ignoresComments: true) - do { - let config1 = ["ignores_comments": true] + @Test + func trailingWhitespaceConfigurationApplyConfigurationSetsIgnoresComments() { + var configuration = TrailingWhitespaceConfiguration( + ignoresEmptyLines: false, + ignoresComments: true + ) + let config1 = ["ignores_comments": true] + #expect(throws: Never.self) { try configuration.apply(configuration: config1) - XCTAssertTrue(configuration.ignoresComments) + } + #expect(configuration.ignoresComments) - let config2 = ["ignores_comments": false] + let config2 = ["ignores_comments": false] + #expect(throws: Never.self) { try configuration.apply(configuration: config2) - XCTAssertFalse(configuration.ignoresComments) - } catch { - XCTFail("Failed to apply ignores_comments") } + #expect(!configuration.ignoresComments) } - func testTrailingWhitespaceConfigurationCompares() { - let configuration1 = TrailingWhitespaceConfiguration(ignoresEmptyLines: false, - ignoresComments: true) - let configuration2 = TrailingWhitespaceConfiguration(ignoresEmptyLines: true, - ignoresComments: true) - XCTAssertNotEqual(configuration1, configuration2) - - let configuration3 = TrailingWhitespaceConfiguration(ignoresEmptyLines: true, - ignoresComments: true) - XCTAssertEqual(configuration2, configuration3) - - let configuration4 = TrailingWhitespaceConfiguration(ignoresEmptyLines: false, - ignoresComments: false) + @Test + func trailingWhitespaceConfigurationCompares() { + let configuration1 = TrailingWhitespaceConfiguration( + ignoresEmptyLines: false, + ignoresComments: true) + let configuration2 = TrailingWhitespaceConfiguration( + ignoresEmptyLines: true, + ignoresComments: true) + #expect(configuration1 != configuration2) + + let configuration3 = TrailingWhitespaceConfiguration( + ignoresEmptyLines: true, + ignoresComments: true) + #expect(configuration2 == configuration3) + + let configuration4 = TrailingWhitespaceConfiguration( + ignoresEmptyLines: false, + ignoresComments: false) - XCTAssertNotEqual(configuration1, configuration4) + #expect(configuration1 != configuration4) - let configuration5 = TrailingWhitespaceConfiguration(ignoresEmptyLines: true, - ignoresComments: false) + let configuration5 = TrailingWhitespaceConfiguration( + ignoresEmptyLines: true, + ignoresComments: false) - XCTAssertNotEqual(configuration1, configuration5) + #expect(configuration1 != configuration5) } - func testTrailingWhitespaceConfigurationApplyConfigurationUpdatesSeverityConfiguration() { + @Test + func trailingWhitespaceConfigurationApplyConfigurationUpdatesSeverityConfiguration() { var configuration = TrailingWhitespaceConfiguration( severityConfiguration: .warning, ignoresEmptyLines: false, ignoresComments: true ) - do { + #expect(throws: Never.self) { try configuration.apply(configuration: ["severity": "error"]) - XCTAssertEqual(configuration.severityConfiguration.severity, .error) - } catch { - XCTFail("Failed to apply severity") } + #expect(configuration.severityConfiguration.severity == .error) } - func testOverriddenSuperCallConfigurationFromDictionary() { + @Test + func overriddenSuperCallConfigurationFromDictionary() { var configuration = OverriddenSuperCallConfiguration() - XCTAssertTrue(configuration.resolvedMethodNames.contains("viewWillAppear(_:)")) + #expect(configuration.resolvedMethodNames.contains("viewWillAppear(_:)")) let conf1 = ["severity": "error", "excluded": "viewWillAppear(_:)"] - do { + #expect(throws: Never.self) { try configuration.apply(configuration: conf1) - XCTAssertEqual(configuration.severityConfiguration.severity, .error) - XCTAssertFalse(configuration.resolvedMethodNames.contains("*")) - XCTAssertFalse(configuration.resolvedMethodNames.contains("viewWillAppear(_:)")) - XCTAssertTrue(configuration.resolvedMethodNames.contains("viewWillDisappear(_:)")) - } catch { - XCTFail("Failed to apply configuration for \(conf1)") } + #expect(configuration.severityConfiguration.severity == .error) + #expect(!configuration.resolvedMethodNames.contains("*")) + #expect(!configuration.resolvedMethodNames.contains("viewWillAppear(_:)")) + #expect(configuration.resolvedMethodNames.contains("viewWillDisappear(_:)")) let conf2 = [ "severity": "error", "excluded": "viewWillAppear(_:)", "included": ["*", "testMethod1()", "testMethod2(_:)"], ] as [String: any Sendable] - do { + #expect(throws: Never.self) { try configuration.apply(configuration: conf2) - XCTAssertEqual(configuration.severityConfiguration.severity, .error) - XCTAssertFalse(configuration.resolvedMethodNames.contains("*")) - XCTAssertFalse(configuration.resolvedMethodNames.contains("viewWillAppear(_:)")) - XCTAssertTrue(configuration.resolvedMethodNames.contains("viewWillDisappear(_:)")) - XCTAssertTrue(configuration.resolvedMethodNames.contains("testMethod1()")) - XCTAssertTrue(configuration.resolvedMethodNames.contains("testMethod2(_:)")) - } catch { - XCTFail("Failed to apply configuration for \(conf2)") } + #expect(configuration.severityConfiguration.severity == .error) + #expect(!configuration.resolvedMethodNames.contains("*")) + #expect(!configuration.resolvedMethodNames.contains("viewWillAppear(_:)")) + #expect(configuration.resolvedMethodNames.contains("viewWillDisappear(_:)")) + #expect(configuration.resolvedMethodNames.contains("testMethod1()")) + #expect(configuration.resolvedMethodNames.contains("testMethod2(_:)")) let conf3 = [ "severity": "warning", "excluded": "*", "included": ["testMethod1()", "testMethod2(_:)"], ] as [String: any Sendable] - do { + #expect(throws: Never.self) { try configuration.apply(configuration: conf3) - XCTAssertEqual(configuration.severityConfiguration.severity, .warning) - XCTAssertEqual(configuration.resolvedMethodNames.count, 2) - XCTAssertFalse(configuration.resolvedMethodNames.contains("*")) - XCTAssertTrue(configuration.resolvedMethodNames.contains("testMethod1()")) - XCTAssertTrue(configuration.resolvedMethodNames.contains("testMethod2(_:)")) - } catch { - XCTFail("Failed to apply configuration for \(conf3)") } + #expect(configuration.severityConfiguration.severity == .warning) + #expect(configuration.resolvedMethodNames.count == 2) + #expect(!configuration.resolvedMethodNames.contains("*")) + #expect(configuration.resolvedMethodNames.contains("testMethod1()")) + #expect(configuration.resolvedMethodNames.contains("testMethod2(_:)")) } - func testModifierOrderConfigurationFromDictionary() throws { + @Test + func modifierOrderConfigurationFromDictionary() throws { var configuration = ModifierOrderConfiguration() let config: [String: Any] = [ "severity": "warning", @@ -314,37 +351,42 @@ final class RuleConfigurationTests: SwiftLintTestCase { .lazy, .dynamic, ] - XCTAssertEqual(configuration.severityConfiguration.severity, .warning) - XCTAssertEqual(configuration.preferredModifierOrder, expected) + #expect(configuration.severityConfiguration.severity == .warning) + #expect(configuration.preferredModifierOrder == expected) } - func testModifierOrderConfigurationThrowsOnUnrecognizedModifierGroup() { + @Test + func modifierOrderConfigurationThrowsOnUnrecognizedModifierGroup() { var configuration = ModifierOrderConfiguration() - let config = ["severity": "warning", "preferred_modifier_order": ["specialize"]] as [String: any Sendable] + let config = + ["severity": "warning", "preferred_modifier_order": ["specialize"]] + as [String: any Sendable] - checkError(Issue.invalidConfiguration(ruleID: ModifierOrderRule.identifier)) { + #expect(throws: Issue.invalidConfiguration(ruleID: ModifierOrderRule.identifier)) { try configuration.apply(configuration: config) } } - func testModifierOrderConfigurationThrowsOnNonModifiableGroup() { + @Test + func modifierOrderConfigurationThrowsOnNonModifiableGroup() { var configuration = ModifierOrderConfiguration() - let config = ["severity": "warning", "preferred_modifier_order": ["atPrefixed"]] as [String: any Sendable] - checkError(Issue.invalidConfiguration(ruleID: ModifierOrderRule.identifier)) { + let config = ["severity": "warning", "preferred_modifier_order": ["atPrefixed"]] as [String: any Sendable] + #expect(throws: Issue.invalidConfiguration(ruleID: ModifierOrderRule.identifier)) { try configuration.apply(configuration: config) } } - func testComputedAccessorsOrderRuleConfiguration() throws { + @Test + func computedAccessorsOrderRuleConfiguration() throws { var configuration = ComputedAccessorsOrderConfiguration() let config = ["severity": "error", "order": "set_get"] try configuration.apply(configuration: config) - XCTAssertEqual(configuration.severityConfiguration.severity, .error) - XCTAssertEqual(configuration.order, .setGet) + #expect(configuration.severityConfiguration.severity == .error) + #expect(configuration.order == .setGet) - XCTAssertEqual( - RuleConfigurationDescription.from(configuration: configuration).oneLiner(), - "severity: error; order: set_get") + #expect( + RuleConfigurationDescription.from(configuration: configuration).oneLiner() + == "severity: error; order: set_get") } } diff --git a/Tests/FrameworkTests/RulesFilterTests.swift b/Tests/FrameworkTests/RulesFilterTests.swift index d495206433..baffe85a65 100644 --- a/Tests/FrameworkTests/RulesFilterTests.swift +++ b/Tests/FrameworkTests/RulesFilterTests.swift @@ -1,8 +1,10 @@ import SwiftLintFramework -import XCTest +import Testing -final class RulesFilterTests: XCTestCase { - func testRulesFilterExcludesEnabledRules() { +@Suite +struct RulesFilterTests { + @Test + func rulesFilterExcludesEnabledRules() { let allRules = RuleList( rules: [ RuleMock1.self, @@ -21,13 +23,11 @@ final class RulesFilterTests: XCTestCase { let filteredRules = rulesFilter.getRules(excluding: [.enabled]) - XCTAssertEqual( - Set(filteredRules.list.keys), - Set([RuleMock2.identifier]) - ) + #expect(Set(filteredRules.list.keys) == Set([RuleMock2.identifier])) } - func testRulesFilterExcludesDisabledRules() { + @Test + func rulesFilterExcludesDisabledRules() { let allRules = RuleList( rules: [ RuleMock1.self, @@ -46,13 +46,11 @@ final class RulesFilterTests: XCTestCase { let filteredRules = rulesFilter.getRules(excluding: [.disabled]) - XCTAssertEqual( - Set(filteredRules.list.keys), - Set([RuleMock1.identifier, CorrectableRuleMock.identifier]) - ) + #expect(Set(filteredRules.list.keys) == Set([RuleMock1.identifier, CorrectableRuleMock.identifier])) } - func testRulesFilterExcludesUncorrectableRules() { + @Test + func rulesFilterExcludesUncorrectableRules() { let allRules = RuleList( rules: [ RuleMock1.self, @@ -71,13 +69,11 @@ final class RulesFilterTests: XCTestCase { let filteredRules = rulesFilter.getRules(excluding: [.uncorrectable]) - XCTAssertEqual( - Set(filteredRules.list.keys), - Set([CorrectableRuleMock.identifier]) - ) + #expect(Set(filteredRules.list.keys) == Set([CorrectableRuleMock.identifier])) } - func testRulesFilterExcludesUncorrectableDisabledRules() { + @Test + func rulesFilterExcludesUncorrectableDisabledRules() { let allRules = RuleList( rules: [ RuleMock1.self, @@ -96,13 +92,11 @@ final class RulesFilterTests: XCTestCase { let filteredRules = rulesFilter.getRules(excluding: [.disabled, .uncorrectable]) - XCTAssertEqual( - Set(filteredRules.list.keys), - Set([CorrectableRuleMock.identifier]) - ) + #expect(Set(filteredRules.list.keys) == Set([CorrectableRuleMock.identifier])) } - func testRulesFilterExcludesUncorrectableEnabledRules() { + @Test + func rulesFilterExcludesUncorrectableEnabledRules() { let allRules = RuleList( rules: [ RuleMock1.self, @@ -120,10 +114,7 @@ final class RulesFilterTests: XCTestCase { let filteredRules = rulesFilter.getRules(excluding: [.enabled, .uncorrectable]) - XCTAssertEqual( - Set(filteredRules.list.keys), - Set([CorrectableRuleMock.identifier]) - ) + #expect(Set(filteredRules.list.keys) == Set([CorrectableRuleMock.identifier])) } } diff --git a/Tests/FrameworkTests/RulesTests.swift b/Tests/FrameworkTests/RulesTests.swift index 4a236fa607..f5a5415bbc 100644 --- a/Tests/FrameworkTests/RulesTests.swift +++ b/Tests/FrameworkTests/RulesTests.swift @@ -1,27 +1,39 @@ -@testable import SwiftLintBuiltInRules import TestHelpers +import Testing + +@testable import SwiftLintBuiltInRules -final class RulesTests: SwiftLintTestCase { - func testLeadingWhitespace() { - verifyRule(LeadingWhitespaceRule.description, skipDisableCommandTests: true, - testMultiByteOffsets: false, testShebang: false) +@Suite(.rulesRegistered) +struct RulesTests { + @Test + func leadingWhitespace() { + verifyRule( + LeadingWhitespaceRule.description, skipDisableCommandTests: true, + testMultiByteOffsets: false, testShebang: false + ) } - func testMark() { + @Test + func mark() { verifyRule(MarkRule.description, skipCommentTests: true) } - func testRequiredEnumCase() { + @Test + func requiredEnumCase() { let configuration = ["NetworkResponsable": ["notConnected": "error"]] verifyRule(RequiredEnumCaseRule.description, ruleConfiguration: configuration) } - func testTrailingNewline() { - verifyRule(TrailingNewlineRule.description, commentDoesntViolate: false, - stringDoesntViolate: false) + @Test + func trailingNewline() { + verifyRule( + TrailingNewlineRule.description, commentDoesntViolate: false, + stringDoesntViolate: false + ) } - func testOrphanedDocComment() { + @Test + func orphanedDocComment() { verifyRule(OrphanedDocCommentRule.description, commentDoesntViolate: false, skipCommentTests: true) } } diff --git a/Tests/FrameworkTests/StringViewExtensionTests.swift b/Tests/FrameworkTests/StringViewExtensionTests.swift index ad7c1b1760..c265bf98c8 100644 --- a/Tests/FrameworkTests/StringViewExtensionTests.swift +++ b/Tests/FrameworkTests/StringViewExtensionTests.swift @@ -1,23 +1,25 @@ import SourceKittenFramework -import TestHelpers -import XCTest +import Testing -final class StringViewExtensionTests: SwiftLintTestCase { - func testByteOffsetInvalidCases() { +@Suite +struct StringViewExtensionTests { + @Test + func byteOffsetInvalidCases() { let view = StringView("") - XCTAssertNil(view.byteOffset(forLine: 0, bytePosition: 1)) - XCTAssertNil(view.byteOffset(forLine: 1, bytePosition: 0)) - XCTAssertNil(view.byteOffset(forLine: -10, bytePosition: 1)) - XCTAssertNil(view.byteOffset(forLine: 0, bytePosition: -11)) - XCTAssertNil(view.byteOffset(forLine: 2, bytePosition: 1)) + #expect(view.byteOffset(forLine: 0, bytePosition: 1) == nil) + #expect(view.byteOffset(forLine: 1, bytePosition: 0) == nil) + #expect(view.byteOffset(forLine: -10, bytePosition: 1) == nil) + #expect(view.byteOffset(forLine: 0, bytePosition: -11) == nil) + #expect(view.byteOffset(forLine: 2, bytePosition: 1) == nil) } - func testByteOffsetFromLineAndBytePosition() { - XCTAssertEqual(StringView("").byteOffset(forLine: 1, bytePosition: 1), 0) - XCTAssertEqual(StringView("a").byteOffset(forLine: 1, bytePosition: 1), 0) - XCTAssertEqual(StringView("aaa").byteOffset(forLine: 1, bytePosition: 3), 2) - XCTAssertEqual(StringView("a🍰a").byteOffset(forLine: 1, bytePosition: 6), 5) - XCTAssertEqual(StringView("a🍰a\na").byteOffset(forLine: 2, bytePosition: 1), 7) + @Test + func byteOffsetFromLineAndBytePosition() { + #expect(StringView("").byteOffset(forLine: 1, bytePosition: 1) == 0) + #expect(StringView("a").byteOffset(forLine: 1, bytePosition: 1) == 0) + #expect(StringView("aaa").byteOffset(forLine: 1, bytePosition: 3) == 2) + #expect(StringView("a🍰a").byteOffset(forLine: 1, bytePosition: 6) == 5) + #expect(StringView("a🍰a\na").byteOffset(forLine: 2, bytePosition: 1) == 7) } } diff --git a/Tests/FrameworkTests/SwiftSyntaxKindBridgeTests.swift b/Tests/FrameworkTests/SwiftSyntaxKindBridgeTests.swift index 8fdb9da72a..a76dd187db 100644 --- a/Tests/FrameworkTests/SwiftSyntaxKindBridgeTests.swift +++ b/Tests/FrameworkTests/SwiftSyntaxKindBridgeTests.swift @@ -1,58 +1,65 @@ import SourceKittenFramework -import SwiftIDEUtils +import Testing + @testable import SwiftLintCore -import SwiftSyntax -import TestHelpers -import XCTest -final class SwiftSyntaxKindBridgeTests: SwiftLintTestCase { - func testBasicKeywordMapping() { +@Suite +struct SwiftSyntaxKindBridgeTests { + @Test + func basicKeywordMapping() { // Test basic keyword mappings - XCTAssertEqual(SwiftSyntaxKindBridge.mapClassification(.keyword), .keyword) + #expect(SwiftSyntaxKindBridge.mapClassification(.keyword) == .keyword) } - func testIdentifierMapping() { + @Test + func identifierMapping() { // Test identifier mappings - XCTAssertEqual(SwiftSyntaxKindBridge.mapClassification(.identifier), .identifier) - XCTAssertEqual(SwiftSyntaxKindBridge.mapClassification(.dollarIdentifier), .identifier) + #expect(SwiftSyntaxKindBridge.mapClassification(.identifier) == .identifier) + #expect(SwiftSyntaxKindBridge.mapClassification(.dollarIdentifier) == .identifier) } - func testCommentMapping() { + @Test + func commentMapping() { // Test comment mappings - XCTAssertEqual(SwiftSyntaxKindBridge.mapClassification(.lineComment), .comment) - XCTAssertEqual(SwiftSyntaxKindBridge.mapClassification(.blockComment), .comment) - XCTAssertEqual(SwiftSyntaxKindBridge.mapClassification(.docLineComment), .docComment) - XCTAssertEqual(SwiftSyntaxKindBridge.mapClassification(.docBlockComment), .docComment) + #expect(SwiftSyntaxKindBridge.mapClassification(.lineComment) == .comment) + #expect(SwiftSyntaxKindBridge.mapClassification(.blockComment) == .comment) + #expect(SwiftSyntaxKindBridge.mapClassification(.docLineComment) == .docComment) + #expect(SwiftSyntaxKindBridge.mapClassification(.docBlockComment) == .docComment) } - func testLiteralMapping() { + @Test + func literalMapping() { // Test literal mappings - XCTAssertEqual(SwiftSyntaxKindBridge.mapClassification(.stringLiteral), .string) - XCTAssertEqual(SwiftSyntaxKindBridge.mapClassification(.integerLiteral), .number) - XCTAssertEqual(SwiftSyntaxKindBridge.mapClassification(.floatLiteral), .number) + #expect(SwiftSyntaxKindBridge.mapClassification(.stringLiteral) == .string) + #expect(SwiftSyntaxKindBridge.mapClassification(.integerLiteral) == .number) + #expect(SwiftSyntaxKindBridge.mapClassification(.floatLiteral) == .number) } - func testOperatorAndTypeMapping() { + @Test + func operatorAndTypeMapping() { // Test operator and type mappings - XCTAssertEqual(SwiftSyntaxKindBridge.mapClassification(.operator), .operator) - XCTAssertEqual(SwiftSyntaxKindBridge.mapClassification(.type), .typeidentifier) + #expect(SwiftSyntaxKindBridge.mapClassification(.operator) == .operator) + #expect(SwiftSyntaxKindBridge.mapClassification(.type) == .typeidentifier) } - func testSpecialCaseMapping() { + @Test + func specialCaseMapping() { // Test special case mappings - XCTAssertEqual(SwiftSyntaxKindBridge.mapClassification(.attribute), .attributeID) - XCTAssertEqual(SwiftSyntaxKindBridge.mapClassification(.editorPlaceholder), .placeholder) - XCTAssertEqual(SwiftSyntaxKindBridge.mapClassification(.ifConfigDirective), .poundDirectiveKeyword) - XCTAssertEqual(SwiftSyntaxKindBridge.mapClassification(.argumentLabel), .argument) + #expect(SwiftSyntaxKindBridge.mapClassification(.attribute) == .attributeID) + #expect(SwiftSyntaxKindBridge.mapClassification(.editorPlaceholder) == .placeholder) + #expect(SwiftSyntaxKindBridge.mapClassification(.ifConfigDirective) == .poundDirectiveKeyword) + #expect(SwiftSyntaxKindBridge.mapClassification(.argumentLabel) == .argument) } - func testUnmappedClassifications() { + @Test + func unmappedClassifications() { // Test classifications that have no mapping - XCTAssertNil(SwiftSyntaxKindBridge.mapClassification(.none)) - XCTAssertNil(SwiftSyntaxKindBridge.mapClassification(.regexLiteral)) + #expect(SwiftSyntaxKindBridge.mapClassification(.none) == nil) + #expect(SwiftSyntaxKindBridge.mapClassification(.regexLiteral) == nil) } - func testSourceKittenSyntaxKindsGeneration() { + @Test + func sourceKittenSyntaxKindsGeneration() { // Test that we can generate SourceKitten-compatible tokens from a simple Swift file let contents = """ // This is a comment @@ -64,17 +71,18 @@ final class SwiftSyntaxKindBridgeTests: SwiftLintTestCase { let tokens = SwiftSyntaxKindBridge.sourceKittenSyntaxKinds(for: file) // Verify we got some tokens - XCTAssertFalse(tokens.isEmpty) + #expect(!tokens.isEmpty) // Check that we have expected token types let tokenTypes = Set(tokens.map { $0.value.type }) - XCTAssertTrue(tokenTypes.contains(SyntaxKind.comment.rawValue)) - XCTAssertTrue(tokenTypes.contains(SyntaxKind.keyword.rawValue)) - XCTAssertTrue(tokenTypes.contains(SyntaxKind.identifier.rawValue)) - XCTAssertTrue(tokenTypes.contains(SyntaxKind.number.rawValue)) + #expect(tokenTypes.contains(SyntaxKind.comment.rawValue)) + #expect(tokenTypes.contains(SyntaxKind.keyword.rawValue)) + #expect(tokenTypes.contains(SyntaxKind.identifier.rawValue)) + #expect(tokenTypes.contains(SyntaxKind.number.rawValue)) } - func testTokenOffsetAndLength() { + @Test + func tokenOffsetAndLength() { // Test that token offsets and lengths are correct let contents = "let x = 42" let file = SwiftLintFile(contents: contents) @@ -93,19 +101,20 @@ final class SwiftSyntaxKindBridgeTests: SwiftLintTestCase { } return false } - XCTAssertNotNil(letToken) - XCTAssertEqual(letToken?.value.offset.value, 0) - XCTAssertEqual(letToken?.value.length.value, 3) + #expect(letToken != nil) + #expect(letToken?.value.offset.value == 0) + #expect(letToken?.value.length.value == 3) // Find the number token let numberToken = tokens.first { $0.value.type == SyntaxKind.number.rawValue } - XCTAssertNotNil(numberToken) + #expect(numberToken != nil) // "42" starts at offset 8 and has length 2 - XCTAssertEqual(numberToken?.value.offset.value, 8) - XCTAssertEqual(numberToken?.value.length.value, 2) + #expect(numberToken?.value.offset.value == 8) + #expect(numberToken?.value.length.value == 2) } - func testComplexCodeStructure() { + @Test + func complexCodeStructure() { // Test with more complex Swift code let contents = """ import Foundation @@ -128,16 +137,17 @@ final class SwiftSyntaxKindBridgeTests: SwiftLintTestCase { // Verify we have various token types let tokenTypes = Set(tokens.map { $0.value.type }) - XCTAssertTrue(tokenTypes.contains(SyntaxKind.keyword.rawValue)) // import, class, var, let, func - XCTAssertTrue(tokenTypes.contains(SyntaxKind.identifier.rawValue)) // Foundation, MyClass, name, etc. - XCTAssertTrue(tokenTypes.contains(SyntaxKind.docComment.rawValue)) // /// A sample class - XCTAssertTrue(tokenTypes.contains(SyntaxKind.comment.rawValue)) // // Properties - XCTAssertTrue(tokenTypes.contains(SyntaxKind.attributeID.rawValue)) // @objc - XCTAssertTrue(tokenTypes.contains(SyntaxKind.typeidentifier.rawValue)) // String, UUID - XCTAssertTrue(tokenTypes.contains(SyntaxKind.string.rawValue)) // "test", "Hello, \\(name)!" + #expect(tokenTypes.contains(SyntaxKind.keyword.rawValue)) // import, class, var, let, func + #expect(tokenTypes.contains(SyntaxKind.identifier.rawValue)) // Foundation, MyClass, name, etc. + #expect(tokenTypes.contains(SyntaxKind.docComment.rawValue)) // /// A sample class + #expect(tokenTypes.contains(SyntaxKind.comment.rawValue)) // // Properties + #expect(tokenTypes.contains(SyntaxKind.attributeID.rawValue)) // @objc // @objc + #expect(tokenTypes.contains(SyntaxKind.typeidentifier.rawValue)) // String, UUID + #expect(tokenTypes.contains(SyntaxKind.string.rawValue)) // "test", "Hello, \\(name)!" } - func testNoSourceKitCallsAreMade() { + @Test + func noSourceKitCallsAreMade() { // This test verifies that the bridge doesn't make any SourceKit calls // If it did, the validation system would fatal error in test mode @@ -151,21 +161,23 @@ final class SwiftSyntaxKindBridgeTests: SwiftLintTestCase { // This should succeed without any fatal errors from the validation system let tokens = SwiftSyntaxKindBridge.sourceKittenSyntaxKinds(for: file) - XCTAssertFalse(tokens.isEmpty) + #expect(!tokens.isEmpty) } - func testEmptyFileHandling() { + @Test + func emptyFileHandling() { // Test that empty files are handled gracefully let file = SwiftLintFile(contents: "") let tokens = SwiftSyntaxKindBridge.sourceKittenSyntaxKinds(for: file) - XCTAssertTrue(tokens.isEmpty) + #expect(tokens.isEmpty) } - func testWhitespaceOnlyFile() { + @Test + func whitespaceOnlyFile() { // Test files with only whitespace let file = SwiftLintFile(contents: " \n\n \t \n") let tokens = SwiftSyntaxKindBridge.sourceKittenSyntaxKinds(for: file) // Whitespace is not classified, so we should get no tokens - XCTAssertTrue(tokens.isEmpty) + #expect(tokens.isEmpty) } } diff --git a/Tests/FrameworkTests/SwiftVersionTests.swift b/Tests/FrameworkTests/SwiftVersionTests.swift index a27312e350..6e22dc3944 100644 --- a/Tests/FrameworkTests/SwiftVersionTests.swift +++ b/Tests/FrameworkTests/SwiftVersionTests.swift @@ -1,9 +1,10 @@ import SwiftLintFramework -import TestHelpers -import XCTest +import Testing -final class SwiftVersionTests: SwiftLintTestCase { - func testDetectSwiftVersion() { +@Suite +struct SwiftVersionTests { + @Test + func detectSwiftVersion() { #if compiler(>=6.2.0) let version = "6.2.0" #elseif compiler(>=6.1.2) @@ -63,54 +64,57 @@ final class SwiftVersionTests: SwiftLintTestCase { #else #error("Unsupported Swift version") #endif - XCTAssertEqual(SwiftVersion.current.rawValue, version) + #expect(SwiftVersion.current.rawValue == version) } - func testCompareBalancedSwiftVersion() { - XCTAssertNotEqual(SwiftVersion(rawValue: "5"), SwiftVersion(rawValue: "6")) - XCTAssertTrue(SwiftVersion(rawValue: "5") < SwiftVersion(rawValue: "6")) - XCTAssertFalse(SwiftVersion(rawValue: "5") > SwiftVersion(rawValue: "6")) - XCTAssertFalse(SwiftVersion(rawValue: "6") < SwiftVersion(rawValue: "5")) + @Test + func compareBalancedSwiftVersion() { + #expect(SwiftVersion(rawValue: "5") != SwiftVersion(rawValue: "6")) + #expect(SwiftVersion(rawValue: "5") < SwiftVersion(rawValue: "6")) + #expect(!(SwiftVersion(rawValue: "5") > SwiftVersion(rawValue: "6"))) + #expect(!(SwiftVersion(rawValue: "6") < SwiftVersion(rawValue: "5"))) - XCTAssertNotEqual(SwiftVersion(rawValue: "5.1"), SwiftVersion(rawValue: "5.2")) - XCTAssertTrue(SwiftVersion(rawValue: "5.1") < SwiftVersion(rawValue: "5.2")) - XCTAssertFalse(SwiftVersion(rawValue: "5.1") > SwiftVersion(rawValue: "5.2")) - XCTAssertFalse(SwiftVersion(rawValue: "5.2") < SwiftVersion(rawValue: "5.1")) + #expect(SwiftVersion(rawValue: "5.1") != SwiftVersion(rawValue: "5.2")) + #expect(SwiftVersion(rawValue: "5.1") < SwiftVersion(rawValue: "5.2")) + #expect(!(SwiftVersion(rawValue: "5.1") > SwiftVersion(rawValue: "5.2"))) + #expect(!(SwiftVersion(rawValue: "5.2") < SwiftVersion(rawValue: "5.1"))) - XCTAssertNotEqual(SwiftVersion(rawValue: "5.1.1"), SwiftVersion(rawValue: "5.1.2")) - XCTAssertTrue(SwiftVersion(rawValue: "5.1.1") < SwiftVersion(rawValue: "5.1.2")) - XCTAssertFalse(SwiftVersion(rawValue: "5.1.1") > SwiftVersion(rawValue: "5.1.2")) - XCTAssertFalse(SwiftVersion(rawValue: "5.1.2") < SwiftVersion(rawValue: "5.1.1")) + #expect(SwiftVersion(rawValue: "5.1.1") != SwiftVersion(rawValue: "5.1.2")) + #expect(SwiftVersion(rawValue: "5.1.1") < SwiftVersion(rawValue: "5.1.2")) + #expect(!(SwiftVersion(rawValue: "5.1.1") > SwiftVersion(rawValue: "5.1.2"))) + #expect(!(SwiftVersion(rawValue: "5.1.2") < SwiftVersion(rawValue: "5.1.1"))) } - func testCompareUnbalancedSwiftVersion() { - XCTAssertEqual(SwiftVersion(rawValue: "5"), SwiftVersion(rawValue: "5.0")) - XCTAssertFalse(SwiftVersion(rawValue: "5") < SwiftVersion(rawValue: "5.0")) - XCTAssertFalse(SwiftVersion(rawValue: "5") > SwiftVersion(rawValue: "5.0")) + @Test + func compareUnbalancedSwiftVersion() { + #expect(SwiftVersion(rawValue: "5") == SwiftVersion(rawValue: "5.0")) + #expect(!(SwiftVersion(rawValue: "5") < SwiftVersion(rawValue: "5.0"))) + #expect(!(SwiftVersion(rawValue: "5") > SwiftVersion(rawValue: "5.0"))) - XCTAssertNotEqual(SwiftVersion(rawValue: "5.9"), SwiftVersion(rawValue: "6")) - XCTAssertTrue(SwiftVersion(rawValue: "5.9") < SwiftVersion(rawValue: "6")) - XCTAssertFalse(SwiftVersion(rawValue: "5.9") > SwiftVersion(rawValue: "6")) - XCTAssertFalse(SwiftVersion(rawValue: "6") < SwiftVersion(rawValue: "5.9")) + #expect(SwiftVersion(rawValue: "5.9") != SwiftVersion(rawValue: "6")) + #expect(SwiftVersion(rawValue: "5.9") < SwiftVersion(rawValue: "6")) + #expect(!(SwiftVersion(rawValue: "5.9") > SwiftVersion(rawValue: "6"))) + #expect(!(SwiftVersion(rawValue: "6") < SwiftVersion(rawValue: "5.9"))) - XCTAssertNotEqual(SwiftVersion(rawValue: "5.2"), SwiftVersion(rawValue: "5.10.3")) - XCTAssertTrue(SwiftVersion(rawValue: "5.2") < SwiftVersion(rawValue: "5.10.3")) - XCTAssertFalse(SwiftVersion(rawValue: "5.2") > SwiftVersion(rawValue: "5.10.3")) - XCTAssertFalse(SwiftVersion(rawValue: "5.10.3") < SwiftVersion(rawValue: "5.2")) + #expect(SwiftVersion(rawValue: "5.2") != SwiftVersion(rawValue: "5.10.3")) + #expect(SwiftVersion(rawValue: "5.2") < SwiftVersion(rawValue: "5.10.3")) + #expect(!(SwiftVersion(rawValue: "5.2") > SwiftVersion(rawValue: "5.10.3"))) + #expect(!(SwiftVersion(rawValue: "5.10.3") < SwiftVersion(rawValue: "5.2"))) } - func testCompareProblematicSwiftVersion() { - XCTAssertEqual(SwiftVersion(rawValue: "5.010"), SwiftVersion(rawValue: "5.10")) - XCTAssertFalse(SwiftVersion(rawValue: "5.010") < SwiftVersion(rawValue: "5.10")) - XCTAssertFalse(SwiftVersion(rawValue: "5.010") > SwiftVersion(rawValue: "5.10")) + @Test + func compareProblematicSwiftVersion() { + #expect(SwiftVersion(rawValue: "5.010") == SwiftVersion(rawValue: "5.10")) + #expect(!(SwiftVersion(rawValue: "5.010") < SwiftVersion(rawValue: "5.10"))) + #expect(!(SwiftVersion(rawValue: "5.010") > SwiftVersion(rawValue: "5.10"))) - XCTAssertNotEqual(SwiftVersion(rawValue: "-10"), SwiftVersion(rawValue: "-1")) - XCTAssertTrue(SwiftVersion(rawValue: "-10") < SwiftVersion(rawValue: "-1")) + #expect(SwiftVersion(rawValue: "-10") != SwiftVersion(rawValue: "-1")) + #expect(SwiftVersion(rawValue: "-10") < SwiftVersion(rawValue: "-1")) - XCTAssertNotEqual(SwiftVersion(rawValue: "0"), SwiftVersion(rawValue: "10")) - XCTAssertTrue(SwiftVersion(rawValue: "0") < SwiftVersion(rawValue: "10")) + #expect(SwiftVersion(rawValue: "0") != SwiftVersion(rawValue: "10")) + #expect(SwiftVersion(rawValue: "0") < SwiftVersion(rawValue: "10")) - XCTAssertNotEqual(SwiftVersion(rawValue: "alpha"), SwiftVersion(rawValue: "beta")) - XCTAssertTrue(SwiftVersion(rawValue: "alpha") < SwiftVersion(rawValue: "beta")) + #expect(SwiftVersion(rawValue: "alpha") != SwiftVersion(rawValue: "beta")) + #expect(SwiftVersion(rawValue: "alpha") < SwiftVersion(rawValue: "beta")) } } diff --git a/Tests/FrameworkTests/YamlParserTests.swift b/Tests/FrameworkTests/YamlParserTests.swift index 0d8145fa75..3bf7746cce 100644 --- a/Tests/FrameworkTests/YamlParserTests.swift +++ b/Tests/FrameworkTests/YamlParserTests.swift @@ -1,61 +1,71 @@ +import Testing + @testable import SwiftLintFramework -import TestHelpers -import XCTest -final class YamlParserTests: SwiftLintTestCase { - func testParseEmptyString() { - XCTAssertEqual((try YamlParser.parse("", env: [:])).count, 0, - "Parsing empty YAML string should succeed") +@Suite +struct YamlParserTests { + @Test + func parseEmptyString() throws { + let result = try YamlParser.parse("", env: [:]) + #expect(result.isEmpty, "Parsing empty YAML string should succeed") } - func testParseValidString() { - XCTAssertEqual(try YamlParser.parse("a: 1\nb: 2", env: [:]).count, 2, - "Parsing valid YAML string should succeed") + @Test + func parseValidString() throws { + let result = try YamlParser.parse("a: 1\nb: 2", env: [:]) + #expect(result.count == 2, "Parsing valid YAML string should succeed") } - func testParseReplacesEnvVar() throws { + @Test + func parseReplacesEnvVar() throws { let env = ["PROJECT_NAME": "SwiftLint"] let string = "excluded:\n - ${PROJECT_NAME}/Extensions" let result = try YamlParser.parse(string, env: env) - XCTAssertEqual(result["excluded"] as? [String] ?? [], ["SwiftLint/Extensions"]) + #expect(result["excluded"] as? [String] ?? [] == ["SwiftLint/Extensions"]) } - func testParseTreatNoAsString() throws { + @Test + func parseTreatNoAsString() throws { let string = "excluded:\n - no" let result = try YamlParser.parse(string, env: [:]) - XCTAssertEqual(result["excluded"] as? [String] ?? [], ["no"]) + #expect(result["excluded"] as? [String] ?? [] == ["no"]) } - func testParseTreatYesAsString() throws { + @Test + func parseTreatYesAsString() throws { let string = "excluded:\n - yes" let result = try YamlParser.parse(string, env: [:]) - XCTAssertEqual(result["excluded"] as? [String] ?? [], ["yes"]) + #expect(result["excluded"] as? [String] ?? [] == ["yes"]) } - func testParseTreatOnAsString() throws { + @Test + func parseTreatOnAsString() throws { let string = "excluded:\n - on" let result = try YamlParser.parse(string, env: [:]) - XCTAssertEqual(result["excluded"] as? [String] ?? [], ["on"]) + #expect(result["excluded"] as? [String] ?? [] == ["on"]) } - func testParseTreatOffAsString() throws { + @Test + func parseTreatOffAsString() throws { let string = "excluded:\n - off" let result = try YamlParser.parse(string, env: [:]) - XCTAssertEqual(result["excluded"] as? [String] ?? [], ["off"]) + #expect(result["excluded"] as? [String] ?? [] == ["off"]) } - func testParseInvalidStringThrows() { - checkError(Issue.yamlParsing("2:1: error: parser: did not find expected :\na\n^")) { + @Test + func parseInvalidStringThrows() { + #expect(throws: Issue.yamlParsing("2:1: error: parser: did not find expected :\na\n^")) { _ = try YamlParser.parse("|\na", env: [:]) } } - func testTreatAllEnvVarsAsStringsWithoutCasting() throws { + @Test + func treatAllEnvVarsAsStringsWithoutCasting() throws { let env = [ "INT": "1", "FLOAT": "1.0", @@ -71,13 +81,14 @@ final class YamlParserTests: SwiftLintTestCase { let result = try YamlParser.parse(string, env: env) - XCTAssertEqual(result["int"] as? String, "1") - XCTAssertEqual(result["float"] as? String, "1.0") - XCTAssertEqual(result["bool"] as? String, "true") - XCTAssertEqual(result["string"] as? String, "string") + #expect(result["int"] as? String == "1") + #expect(result["float"] as? String == "1.0") + #expect(result["bool"] as? String == "true") + #expect(result["string"] as? String == "string") } - func testRespectCastsOnEnvVars() throws { + @Test + func respectCastsOnEnvVars() throws { let env = [ "INT": "1", "FLOAT": "1.0", @@ -93,9 +104,9 @@ final class YamlParserTests: SwiftLintTestCase { let result = try YamlParser.parse(string, env: env) - XCTAssertEqual(result["int"] as? Int, 1) - XCTAssertEqual(result["float"] as? Double, 1.0) - XCTAssertEqual(result["bool"] as? Bool, true) - XCTAssertEqual(result["string"] as? String, "string") + #expect(result["int"] as? Int == 1) + #expect(result["float"] as? Double == 1.0) + #expect(result["bool"] as? Bool == true) + #expect(result["string"] as? String == "string") } } diff --git a/Tests/GeneratedTests/GeneratedTests_01.swift b/Tests/GeneratedTests/GeneratedTests_01.swift index 39903d1af5..85edeb2072 100644 --- a/Tests/GeneratedTests/GeneratedTests_01.swift +++ b/Tests/GeneratedTests/GeneratedTests_01.swift @@ -3,156 +3,208 @@ // 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 -final class AccessibilityLabelForImageRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct AccessibilityLabelForImageRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(AccessibilityLabelForImageRule.description) } } -final class AccessibilityTraitForButtonRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct AccessibilityTraitForButtonRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(AccessibilityTraitForButtonRule.description) } } -final class AnonymousArgumentInMultilineClosureRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct AnonymousArgumentInMultilineClosureRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(AnonymousArgumentInMultilineClosureRule.description) } } -final class ArrayInitRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct ArrayInitRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(ArrayInitRule.description) } } -final class AsyncWithoutAwaitRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct AsyncWithoutAwaitRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(AsyncWithoutAwaitRule.description) } } -final class AttributeNameSpacingRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct AttributeNameSpacingRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(AttributeNameSpacingRule.description) } } -final class AttributesRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct AttributesRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(AttributesRule.description) } } -final class BalancedXCTestLifecycleRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct BalancedXCTestLifecycleRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(BalancedXCTestLifecycleRule.description) } } -final class BlanketDisableCommandRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct BlanketDisableCommandRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(BlanketDisableCommandRule.description) } } -final class BlockBasedKVORuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct BlockBasedKVORuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(BlockBasedKVORule.description) } } -final class CaptureVariableRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct CaptureVariableRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(CaptureVariableRule.description) } } -final class ClassDelegateProtocolRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct ClassDelegateProtocolRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(ClassDelegateProtocolRule.description) } } -final class ClosingBraceRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct ClosingBraceRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(ClosingBraceRule.description) } } -final class ClosureBodyLengthRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct ClosureBodyLengthRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(ClosureBodyLengthRule.description) } } -final class ClosureEndIndentationRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct ClosureEndIndentationRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(ClosureEndIndentationRule.description) } } -final class ClosureParameterPositionRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct ClosureParameterPositionRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(ClosureParameterPositionRule.description) } } -final class ClosureSpacingRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct ClosureSpacingRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(ClosureSpacingRule.description) } } -final class CollectionAlignmentRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct CollectionAlignmentRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(CollectionAlignmentRule.description) } } -final class ColonRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct ColonRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(ColonRule.description) } } -final class CommaInheritanceRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct CommaInheritanceRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(CommaInheritanceRule.description) } } -final class CommaRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct CommaRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(CommaRule.description) } } -final class CommentSpacingRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct CommentSpacingRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(CommentSpacingRule.description) } } -final class CompilerProtocolInitRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct CompilerProtocolInitRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(CompilerProtocolInitRule.description) } } -final class ComputedAccessorsOrderRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct ComputedAccessorsOrderRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(ComputedAccessorsOrderRule.description) } } -final class ConditionalReturnsOnNewlineRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct ConditionalReturnsOnNewlineRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(ConditionalReturnsOnNewlineRule.description) } } diff --git a/Tests/GeneratedTests/GeneratedTests_02.swift b/Tests/GeneratedTests/GeneratedTests_02.swift index c8d05b2749..77b69afd70 100644 --- a/Tests/GeneratedTests/GeneratedTests_02.swift +++ b/Tests/GeneratedTests/GeneratedTests_02.swift @@ -3,156 +3,208 @@ // 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 -final class ContainsOverFilterCountRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct ContainsOverFilterCountRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(ContainsOverFilterCountRule.description) } } -final class ContainsOverFilterIsEmptyRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct ContainsOverFilterIsEmptyRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(ContainsOverFilterIsEmptyRule.description) } } -final class ContainsOverFirstNotNilRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct ContainsOverFirstNotNilRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(ContainsOverFirstNotNilRule.description) } } -final class ContainsOverRangeNilComparisonRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct ContainsOverRangeNilComparisonRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(ContainsOverRangeNilComparisonRule.description) } } -final class ContrastedOpeningBraceRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct ContrastedOpeningBraceRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(ContrastedOpeningBraceRule.description) } } -final class ControlStatementRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct ControlStatementRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(ControlStatementRule.description) } } -final class ConvenienceTypeRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct ConvenienceTypeRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(ConvenienceTypeRule.description) } } -final class CyclomaticComplexityRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct CyclomaticComplexityRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(CyclomaticComplexityRule.description) } } -final class DeploymentTargetRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct DeploymentTargetRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(DeploymentTargetRule.description) } } -final class DirectReturnRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct DirectReturnRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(DirectReturnRule.description) } } -final class DiscardedNotificationCenterObserverRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct DiscardedNotificationCenterObserverRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(DiscardedNotificationCenterObserverRule.description) } } -final class DiscouragedAssertRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct DiscouragedAssertRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(DiscouragedAssertRule.description) } } -final class DiscouragedDirectInitRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct DiscouragedDirectInitRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(DiscouragedDirectInitRule.description) } } -final class DiscouragedNoneNameRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct DiscouragedNoneNameRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(DiscouragedNoneNameRule.description) } } -final class DiscouragedObjectLiteralRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct DiscouragedObjectLiteralRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(DiscouragedObjectLiteralRule.description) } } -final class DiscouragedOptionalBooleanRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct DiscouragedOptionalBooleanRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(DiscouragedOptionalBooleanRule.description) } } -final class DiscouragedOptionalCollectionRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct DiscouragedOptionalCollectionRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(DiscouragedOptionalCollectionRule.description) } } -final class DuplicateConditionsRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct DuplicateConditionsRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(DuplicateConditionsRule.description) } } -final class DuplicateEnumCasesRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct DuplicateEnumCasesRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(DuplicateEnumCasesRule.description) } } -final class DuplicateImportsRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct DuplicateImportsRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(DuplicateImportsRule.description) } } -final class DuplicatedKeyInDictionaryLiteralRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct DuplicatedKeyInDictionaryLiteralRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(DuplicatedKeyInDictionaryLiteralRule.description) } } -final class DynamicInlineRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct DynamicInlineRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(DynamicInlineRule.description) } } -final class EmptyCollectionLiteralRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct EmptyCollectionLiteralRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(EmptyCollectionLiteralRule.description) } } -final class EmptyCountRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct EmptyCountRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(EmptyCountRule.description) } } -final class EmptyEnumArgumentsRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct EmptyEnumArgumentsRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(EmptyEnumArgumentsRule.description) } } diff --git a/Tests/GeneratedTests/GeneratedTests_03.swift b/Tests/GeneratedTests/GeneratedTests_03.swift index d90a7c1169..95232d0c27 100644 --- a/Tests/GeneratedTests/GeneratedTests_03.swift +++ b/Tests/GeneratedTests/GeneratedTests_03.swift @@ -3,156 +3,208 @@ // 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 -final class EmptyParametersRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct EmptyParametersRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(EmptyParametersRule.description) } } -final class EmptyParenthesesWithTrailingClosureRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct EmptyParenthesesWithTrailingClosureRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(EmptyParenthesesWithTrailingClosureRule.description) } } -final class EmptyStringRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct EmptyStringRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(EmptyStringRule.description) } } -final class EmptyXCTestMethodRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct EmptyXCTestMethodRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(EmptyXCTestMethodRule.description) } } -final class EnumCaseAssociatedValuesLengthRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct EnumCaseAssociatedValuesLengthRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(EnumCaseAssociatedValuesLengthRule.description) } } -final class ExpiringTodoRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct ExpiringTodoRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(ExpiringTodoRule.description) } } -final class ExplicitACLRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct ExplicitACLRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(ExplicitACLRule.description) } } -final class ExplicitEnumRawValueRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct ExplicitEnumRawValueRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(ExplicitEnumRawValueRule.description) } } -final class ExplicitInitRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct ExplicitInitRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(ExplicitInitRule.description) } } -final class ExplicitSelfRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct ExplicitSelfRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(ExplicitSelfRule.description) } } -final class ExplicitTopLevelACLRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct ExplicitTopLevelACLRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(ExplicitTopLevelACLRule.description) } } -final class ExplicitTypeInterfaceRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct ExplicitTypeInterfaceRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(ExplicitTypeInterfaceRule.description) } } -final class ExtensionAccessModifierRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct ExtensionAccessModifierRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(ExtensionAccessModifierRule.description) } } -final class FallthroughRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct FallthroughRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(FallthroughRule.description) } } -final class FatalErrorMessageRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct FatalErrorMessageRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(FatalErrorMessageRule.description) } } -final class FileHeaderRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct FileHeaderRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(FileHeaderRule.description) } } -final class FileLengthRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct FileLengthRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(FileLengthRule.description) } } -final class FileNameNoSpaceRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct FileNameNoSpaceRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(FileNameNoSpaceRule.description) } } -final class FileNameRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct FileNameRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(FileNameRule.description) } } -final class FileTypesOrderRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct FileTypesOrderRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(FileTypesOrderRule.description) } } -final class FinalTestCaseRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct FinalTestCaseRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(FinalTestCaseRule.description) } } -final class FirstWhereRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct FirstWhereRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(FirstWhereRule.description) } } -final class FlatMapOverMapReduceRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct FlatMapOverMapReduceRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(FlatMapOverMapReduceRule.description) } } -final class ForWhereRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct ForWhereRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(ForWhereRule.description) } } -final class ForceCastRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct ForceCastRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(ForceCastRule.description) } } diff --git a/Tests/GeneratedTests/GeneratedTests_04.swift b/Tests/GeneratedTests/GeneratedTests_04.swift index 7162ba3e33..563dd9c89b 100644 --- a/Tests/GeneratedTests/GeneratedTests_04.swift +++ b/Tests/GeneratedTests/GeneratedTests_04.swift @@ -3,156 +3,208 @@ // 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 -final class ForceTryRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct ForceTryRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(ForceTryRule.description) } } -final class ForceUnwrappingRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct ForceUnwrappingRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(ForceUnwrappingRule.description) } } -final class FunctionBodyLengthRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct FunctionBodyLengthRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(FunctionBodyLengthRule.description) } } -final class FunctionDefaultParameterAtEndRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct FunctionDefaultParameterAtEndRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(FunctionDefaultParameterAtEndRule.description) } } -final class FunctionNameWhitespaceRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct FunctionNameWhitespaceRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(FunctionNameWhitespaceRule.description) } } -final class FunctionParameterCountRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct FunctionParameterCountRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(FunctionParameterCountRule.description) } } -final class GenericTypeNameRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct GenericTypeNameRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(GenericTypeNameRule.description) } } -final class IBInspectableInExtensionRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct IBInspectableInExtensionRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(IBInspectableInExtensionRule.description) } } -final class IdenticalOperandsRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct IdenticalOperandsRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(IdenticalOperandsRule.description) } } -final class IdentifierNameRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct IdentifierNameRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(IdentifierNameRule.description) } } -final class ImplicitGetterRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct ImplicitGetterRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(ImplicitGetterRule.description) } } -final class ImplicitOptionalInitializationRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct ImplicitOptionalInitializationRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(ImplicitOptionalInitializationRule.description) } } -final class ImplicitReturnRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct ImplicitReturnRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(ImplicitReturnRule.description) } } -final class ImplicitlyUnwrappedOptionalRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct ImplicitlyUnwrappedOptionalRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(ImplicitlyUnwrappedOptionalRule.description) } } -final class InclusiveLanguageRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct InclusiveLanguageRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(InclusiveLanguageRule.description) } } -final class IndentationWidthRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct IndentationWidthRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(IndentationWidthRule.description) } } -final class InvalidSwiftLintCommandRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct InvalidSwiftLintCommandRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(InvalidSwiftLintCommandRule.description) } } -final class IsDisjointRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct IsDisjointRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(IsDisjointRule.description) } } -final class JoinedDefaultParameterRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct JoinedDefaultParameterRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(JoinedDefaultParameterRule.description) } } -final class LargeTupleRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct LargeTupleRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(LargeTupleRule.description) } } -final class LastWhereRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct LastWhereRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(LastWhereRule.description) } } -final class LeadingWhitespaceRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct LeadingWhitespaceRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(LeadingWhitespaceRule.description) } } -final class LegacyCGGeometryFunctionsRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct LegacyCGGeometryFunctionsRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(LegacyCGGeometryFunctionsRule.description) } } -final class LegacyConstantRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct LegacyConstantRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(LegacyConstantRule.description) } } -final class LegacyConstructorRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct LegacyConstructorRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(LegacyConstructorRule.description) } } diff --git a/Tests/GeneratedTests/GeneratedTests_05.swift b/Tests/GeneratedTests/GeneratedTests_05.swift index 26a5a1a72a..49adaa538e 100644 --- a/Tests/GeneratedTests/GeneratedTests_05.swift +++ b/Tests/GeneratedTests/GeneratedTests_05.swift @@ -3,156 +3,208 @@ // 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 -final class LegacyHashingRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct LegacyHashingRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(LegacyHashingRule.description) } } -final class LegacyMultipleRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct LegacyMultipleRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(LegacyMultipleRule.description) } } -final class LegacyNSGeometryFunctionsRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct LegacyNSGeometryFunctionsRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(LegacyNSGeometryFunctionsRule.description) } } -final class LegacyObjcTypeRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct LegacyObjcTypeRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(LegacyObjcTypeRule.description) } } -final class LegacyRandomRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct LegacyRandomRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(LegacyRandomRule.description) } } -final class LetVarWhitespaceRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct LetVarWhitespaceRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(LetVarWhitespaceRule.description) } } -final class LineLengthRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct LineLengthRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(LineLengthRule.description) } } -final class LiteralExpressionEndIndentationRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct LiteralExpressionEndIndentationRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(LiteralExpressionEndIndentationRule.description) } } -final class LocalDocCommentRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct LocalDocCommentRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(LocalDocCommentRule.description) } } -final class LowerACLThanParentRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct LowerACLThanParentRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(LowerACLThanParentRule.description) } } -final class MarkRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct MarkRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(MarkRule.description) } } -final class MissingDocsRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct MissingDocsRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(MissingDocsRule.description) } } -final class ModifierOrderRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct ModifierOrderRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(ModifierOrderRule.description) } } -final class MultilineArgumentsBracketsRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct MultilineArgumentsBracketsRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(MultilineArgumentsBracketsRule.description) } } -final class MultilineArgumentsRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct MultilineArgumentsRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(MultilineArgumentsRule.description) } } -final class MultilineFunctionChainsRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct MultilineFunctionChainsRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(MultilineFunctionChainsRule.description) } } -final class MultilineLiteralBracketsRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct MultilineLiteralBracketsRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(MultilineLiteralBracketsRule.description) } } -final class MultilineParametersBracketsRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct MultilineParametersBracketsRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(MultilineParametersBracketsRule.description) } } -final class MultilineParametersRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct MultilineParametersRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(MultilineParametersRule.description) } } -final class MultipleClosuresWithTrailingClosureRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct MultipleClosuresWithTrailingClosureRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(MultipleClosuresWithTrailingClosureRule.description) } } -final class NSLocalizedStringKeyRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct NSLocalizedStringKeyRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(NSLocalizedStringKeyRule.description) } } -final class NSLocalizedStringRequireBundleRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct NSLocalizedStringRequireBundleRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(NSLocalizedStringRequireBundleRule.description) } } -final class NSNumberInitAsFunctionReferenceRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct NSNumberInitAsFunctionReferenceRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(NSNumberInitAsFunctionReferenceRule.description) } } -final class NSObjectPreferIsEqualRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct NSObjectPreferIsEqualRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(NSObjectPreferIsEqualRule.description) } } -final class NestingRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct NestingRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(NestingRule.description) } } diff --git a/Tests/GeneratedTests/GeneratedTests_06.swift b/Tests/GeneratedTests/GeneratedTests_06.swift index 1f586a1f32..6952145575 100644 --- a/Tests/GeneratedTests/GeneratedTests_06.swift +++ b/Tests/GeneratedTests/GeneratedTests_06.swift @@ -3,156 +3,208 @@ // 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 -final class NimbleOperatorRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct NimbleOperatorRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(NimbleOperatorRule.description) } } -final class NoEmptyBlockRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct NoEmptyBlockRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(NoEmptyBlockRule.description) } } -final class NoExtensionAccessModifierRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct NoExtensionAccessModifierRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(NoExtensionAccessModifierRule.description) } } -final class NoFallthroughOnlyRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct NoFallthroughOnlyRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(NoFallthroughOnlyRule.description) } } -final class NoGroupingExtensionRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct NoGroupingExtensionRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(NoGroupingExtensionRule.description) } } -final class NoMagicNumbersRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct NoMagicNumbersRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(NoMagicNumbersRule.description) } } -final class NoSpaceInMethodCallRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct NoSpaceInMethodCallRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(NoSpaceInMethodCallRule.description) } } -final class NonOptionalStringDataConversionRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct NonOptionalStringDataConversionRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(NonOptionalStringDataConversionRule.description) } } -final class NonOverridableClassDeclarationRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct NonOverridableClassDeclarationRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(NonOverridableClassDeclarationRule.description) } } -final class NotificationCenterDetachmentRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct NotificationCenterDetachmentRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(NotificationCenterDetachmentRule.description) } } -final class NumberSeparatorRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct NumberSeparatorRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(NumberSeparatorRule.description) } } -final class ObjectLiteralRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct ObjectLiteralRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(ObjectLiteralRule.description) } } -final class OneDeclarationPerFileRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct OneDeclarationPerFileRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(OneDeclarationPerFileRule.description) } } -final class OpeningBraceRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct OpeningBraceRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(OpeningBraceRule.description) } } -final class OperatorUsageWhitespaceRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct OperatorUsageWhitespaceRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(OperatorUsageWhitespaceRule.description) } } -final class OptionalDataStringConversionRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct OptionalDataStringConversionRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(OptionalDataStringConversionRule.description) } } -final class OptionalEnumCaseMatchingRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct OptionalEnumCaseMatchingRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(OptionalEnumCaseMatchingRule.description) } } -final class OrphanedDocCommentRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct OrphanedDocCommentRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(OrphanedDocCommentRule.description) } } -final class OverriddenSuperCallRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct OverriddenSuperCallRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(OverriddenSuperCallRule.description) } } -final class OverrideInExtensionRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct OverrideInExtensionRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(OverrideInExtensionRule.description) } } -final class PatternMatchingKeywordsRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct PatternMatchingKeywordsRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(PatternMatchingKeywordsRule.description) } } -final class PeriodSpacingRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct PeriodSpacingRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(PeriodSpacingRule.description) } } -final class PreferConditionListRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct PreferConditionListRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(PreferConditionListRule.description) } } -final class PreferKeyPathRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct PreferKeyPathRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(PreferKeyPathRule.description) } } -final class PreferNimbleRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct PreferNimbleRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(PreferNimbleRule.description) } } diff --git a/Tests/GeneratedTests/GeneratedTests_07.swift b/Tests/GeneratedTests/GeneratedTests_07.swift index a27cb25e98..52ce5690f1 100644 --- a/Tests/GeneratedTests/GeneratedTests_07.swift +++ b/Tests/GeneratedTests/GeneratedTests_07.swift @@ -3,156 +3,208 @@ // 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 -final class PreferSelfInStaticReferencesRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct PreferSelfInStaticReferencesRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(PreferSelfInStaticReferencesRule.description) } } -final class PreferSelfTypeOverTypeOfSelfRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct PreferSelfTypeOverTypeOfSelfRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(PreferSelfTypeOverTypeOfSelfRule.description) } } -final class PreferTypeCheckingRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct PreferTypeCheckingRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(PreferTypeCheckingRule.description) } } -final class PreferZeroOverExplicitInitRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct PreferZeroOverExplicitInitRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(PreferZeroOverExplicitInitRule.description) } } -final class PrefixedTopLevelConstantRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct PrefixedTopLevelConstantRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(PrefixedTopLevelConstantRule.description) } } -final class PrivateActionRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct PrivateActionRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(PrivateActionRule.description) } } -final class PrivateOutletRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct PrivateOutletRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(PrivateOutletRule.description) } } -final class PrivateOverFilePrivateRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct PrivateOverFilePrivateRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(PrivateOverFilePrivateRule.description) } } -final class PrivateSubjectRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct PrivateSubjectRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(PrivateSubjectRule.description) } } -final class PrivateSwiftUIStatePropertyRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct PrivateSwiftUIStatePropertyRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(PrivateSwiftUIStatePropertyRule.description) } } -final class PrivateUnitTestRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct PrivateUnitTestRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(PrivateUnitTestRule.description) } } -final class ProhibitedInterfaceBuilderRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct ProhibitedInterfaceBuilderRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(ProhibitedInterfaceBuilderRule.description) } } -final class ProhibitedSuperRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct ProhibitedSuperRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(ProhibitedSuperRule.description) } } -final class ProtocolPropertyAccessorsOrderRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct ProtocolPropertyAccessorsOrderRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(ProtocolPropertyAccessorsOrderRule.description) } } -final class QuickDiscouragedCallRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct QuickDiscouragedCallRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(QuickDiscouragedCallRule.description) } } -final class QuickDiscouragedFocusedTestRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct QuickDiscouragedFocusedTestRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(QuickDiscouragedFocusedTestRule.description) } } -final class QuickDiscouragedPendingTestRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct QuickDiscouragedPendingTestRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(QuickDiscouragedPendingTestRule.description) } } -final class RawValueForCamelCasedCodableEnumRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct RawValueForCamelCasedCodableEnumRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(RawValueForCamelCasedCodableEnumRule.description) } } -final class ReduceBooleanRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct ReduceBooleanRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(ReduceBooleanRule.description) } } -final class ReduceIntoRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct ReduceIntoRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(ReduceIntoRule.description) } } -final class RedundantDiscardableLetRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct RedundantDiscardableLetRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(RedundantDiscardableLetRule.description) } } -final class RedundantNilCoalescingRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct RedundantNilCoalescingRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(RedundantNilCoalescingRule.description) } } -final class RedundantObjcAttributeRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct RedundantObjcAttributeRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(RedundantObjcAttributeRule.description) } } -final class RedundantSelfInClosureRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct RedundantSelfInClosureRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(RedundantSelfInClosureRule.description) } } -final class RedundantSendableRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct RedundantSendableRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(RedundantSendableRule.description) } } diff --git a/Tests/GeneratedTests/GeneratedTests_08.swift b/Tests/GeneratedTests/GeneratedTests_08.swift index 068ffab49e..79b6b00160 100644 --- a/Tests/GeneratedTests/GeneratedTests_08.swift +++ b/Tests/GeneratedTests/GeneratedTests_08.swift @@ -3,156 +3,208 @@ // 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 -final class RedundantSetAccessControlRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct RedundantSetAccessControlRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(RedundantSetAccessControlRule.description) } } -final class RedundantStringEnumValueRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct RedundantStringEnumValueRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(RedundantStringEnumValueRule.description) } } -final class RedundantTypeAnnotationRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct RedundantTypeAnnotationRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(RedundantTypeAnnotationRule.description) } } -final class RedundantVoidReturnRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct RedundantVoidReturnRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(RedundantVoidReturnRule.description) } } -final class RequiredDeinitRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct RequiredDeinitRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(RequiredDeinitRule.description) } } -final class RequiredEnumCaseRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct RequiredEnumCaseRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(RequiredEnumCaseRule.description) } } -final class ReturnArrowWhitespaceRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct ReturnArrowWhitespaceRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(ReturnArrowWhitespaceRule.description) } } -final class ReturnValueFromVoidFunctionRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct ReturnValueFromVoidFunctionRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(ReturnValueFromVoidFunctionRule.description) } } -final class SelfBindingRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct SelfBindingRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(SelfBindingRule.description) } } -final class SelfInPropertyInitializationRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct SelfInPropertyInitializationRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(SelfInPropertyInitializationRule.description) } } -final class ShorthandArgumentRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct ShorthandArgumentRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(ShorthandArgumentRule.description) } } -final class ShorthandOperatorRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct ShorthandOperatorRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(ShorthandOperatorRule.description) } } -final class ShorthandOptionalBindingRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct ShorthandOptionalBindingRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(ShorthandOptionalBindingRule.description) } } -final class SingleTestClassRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct SingleTestClassRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(SingleTestClassRule.description) } } -final class SortedEnumCasesRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct SortedEnumCasesRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(SortedEnumCasesRule.description) } } -final class SortedFirstLastRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct SortedFirstLastRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(SortedFirstLastRule.description) } } -final class SortedImportsRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct SortedImportsRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(SortedImportsRule.description) } } -final class StatementPositionRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct StatementPositionRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(StatementPositionRule.description) } } -final class StaticOperatorRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct StaticOperatorRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(StaticOperatorRule.description) } } -final class StaticOverFinalClassRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct StaticOverFinalClassRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(StaticOverFinalClassRule.description) } } -final class StrictFilePrivateRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct StrictFilePrivateRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(StrictFilePrivateRule.description) } } -final class StrongIBOutletRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct StrongIBOutletRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(StrongIBOutletRule.description) } } -final class SuperfluousElseRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct SuperfluousElseRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(SuperfluousElseRule.description) } } -final class SwitchCaseAlignmentRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct SwitchCaseAlignmentRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(SwitchCaseAlignmentRule.description) } } -final class SwitchCaseOnNewlineRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct SwitchCaseOnNewlineRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(SwitchCaseOnNewlineRule.description) } } diff --git a/Tests/GeneratedTests/GeneratedTests_09.swift b/Tests/GeneratedTests/GeneratedTests_09.swift index 1d8dc7614d..b06b9a5400 100644 --- a/Tests/GeneratedTests/GeneratedTests_09.swift +++ b/Tests/GeneratedTests/GeneratedTests_09.swift @@ -3,156 +3,208 @@ // 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 -final class SyntacticSugarRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct SyntacticSugarRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(SyntacticSugarRule.description) } } -final class TestCaseAccessibilityRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct TestCaseAccessibilityRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(TestCaseAccessibilityRule.description) } } -final class TodoRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct TodoRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(TodoRule.description) } } -final class ToggleBoolRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct ToggleBoolRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(ToggleBoolRule.description) } } -final class TrailingClosureRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct TrailingClosureRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(TrailingClosureRule.description) } } -final class TrailingCommaRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct TrailingCommaRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(TrailingCommaRule.description) } } -final class TrailingNewlineRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct TrailingNewlineRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(TrailingNewlineRule.description) } } -final class TrailingSemicolonRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct TrailingSemicolonRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(TrailingSemicolonRule.description) } } -final class TrailingWhitespaceRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct TrailingWhitespaceRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(TrailingWhitespaceRule.description) } } -final class TypeBodyLengthRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct TypeBodyLengthRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(TypeBodyLengthRule.description) } } -final class TypeContentsOrderRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct TypeContentsOrderRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(TypeContentsOrderRule.description) } } -final class TypeNameRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct TypeNameRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(TypeNameRule.description) } } -final class TypesafeArrayInitRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct TypesafeArrayInitRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(TypesafeArrayInitRule.description) } } -final class UnavailableConditionRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct UnavailableConditionRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(UnavailableConditionRule.description) } } -final class UnavailableFunctionRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct UnavailableFunctionRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(UnavailableFunctionRule.description) } } -final class UnhandledThrowingTaskRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct UnhandledThrowingTaskRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(UnhandledThrowingTaskRule.description) } } -final class UnneededBreakInSwitchRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct UnneededBreakInSwitchRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(UnneededBreakInSwitchRule.description) } } -final class UnneededOverrideRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct UnneededOverrideRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(UnneededOverrideRule.description) } } -final class UnneededParenthesesInClosureArgumentRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct UnneededParenthesesInClosureArgumentRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(UnneededParenthesesInClosureArgumentRule.description) } } -final class UnneededSynthesizedInitializerRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct UnneededSynthesizedInitializerRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(UnneededSynthesizedInitializerRule.description) } } -final class UnownedVariableCaptureRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct UnownedVariableCaptureRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(UnownedVariableCaptureRule.description) } } -final class UntypedErrorInCatchRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct UntypedErrorInCatchRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(UntypedErrorInCatchRule.description) } } -final class UnusedClosureParameterRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct UnusedClosureParameterRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(UnusedClosureParameterRule.description) } } -final class UnusedControlFlowLabelRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct UnusedControlFlowLabelRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(UnusedControlFlowLabelRule.description) } } -final class UnusedDeclarationRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct UnusedDeclarationRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(UnusedDeclarationRule.description) } } diff --git a/Tests/GeneratedTests/GeneratedTests_10.swift b/Tests/GeneratedTests/GeneratedTests_10.swift index a5ce334fc5..8a6ec47358 100644 --- a/Tests/GeneratedTests/GeneratedTests_10.swift +++ b/Tests/GeneratedTests/GeneratedTests_10.swift @@ -3,114 +3,152 @@ // 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 -final class UnusedEnumeratedRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct UnusedEnumeratedRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(UnusedEnumeratedRule.description) } } -final class UnusedImportRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct UnusedImportRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(UnusedImportRule.description) } } -final class UnusedOptionalBindingRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct UnusedOptionalBindingRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(UnusedOptionalBindingRule.description) } } -final class UnusedParameterRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct UnusedParameterRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(UnusedParameterRule.description) } } -final class UnusedSetterValueRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct UnusedSetterValueRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(UnusedSetterValueRule.description) } } -final class ValidIBInspectableRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct ValidIBInspectableRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(ValidIBInspectableRule.description) } } -final class VerticalParameterAlignmentOnCallRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct VerticalParameterAlignmentOnCallRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(VerticalParameterAlignmentOnCallRule.description) } } -final class VerticalParameterAlignmentRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct VerticalParameterAlignmentRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(VerticalParameterAlignmentRule.description) } } -final class VerticalWhitespaceBetweenCasesRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct VerticalWhitespaceBetweenCasesRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(VerticalWhitespaceBetweenCasesRule.description) } } -final class VerticalWhitespaceClosingBracesRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct VerticalWhitespaceClosingBracesRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(VerticalWhitespaceClosingBracesRule.description) } } -final class VerticalWhitespaceOpeningBracesRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct VerticalWhitespaceOpeningBracesRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(VerticalWhitespaceOpeningBracesRule.description) } } -final class VerticalWhitespaceRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct VerticalWhitespaceRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(VerticalWhitespaceRule.description) } } -final class VoidFunctionInTernaryConditionRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct VoidFunctionInTernaryConditionRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(VoidFunctionInTernaryConditionRule.description) } } -final class VoidReturnRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct VoidReturnRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(VoidReturnRule.description) } } -final class WeakDelegateRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct WeakDelegateRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(WeakDelegateRule.description) } } -final class XCTFailMessageRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct XCTFailMessageRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(XCTFailMessageRule.description) } } -final class XCTSpecificMatcherRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct XCTSpecificMatcherRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(XCTSpecificMatcherRule.description) } } -final class YodaConditionRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { +@Suite(.rulesRegistered) +struct YodaConditionRuleGeneratedTests { + @Test + func withDefaultConfiguration() { verifyRule(YodaConditionRule.description) } } diff --git a/Tests/IntegrationTests/IntegrationTests.swift b/Tests/IntegrationTests/IntegrationTests.swift index 0406d0e901..a00fc13343 100644 --- a/Tests/IntegrationTests/IntegrationTests.swift +++ b/Tests/IntegrationTests/IntegrationTests.swift @@ -1,30 +1,29 @@ import Foundation import SwiftLintFramework import TestHelpers -import XCTest +import Testing -private let config: Configuration = { - let bazelWorkspaceDirectory = ProcessInfo.processInfo.environment["BUILD_WORKSPACE_DIRECTORY"] - let rootProjectDirectory = bazelWorkspaceDirectory ?? #filePath.bridge() - .deletingLastPathComponent.bridge() - .deletingLastPathComponent.bridge() - .deletingLastPathComponent - _ = FileManager.default.changeCurrentDirectoryPath(rootProjectDirectory) - return Configuration(configurationFiles: [Configuration.defaultFileName]) -}() +private let bazelWorkspaceDirectory = ProcessInfo.processInfo.environment["BUILD_WORKSPACE_DIRECTORY"] +private let rootProjectDirectory = bazelWorkspaceDirectory ?? #filePath.bridge() + .deletingLastPathComponent.bridge() + .deletingLastPathComponent.bridge() + .deletingLastPathComponent -final class IntegrationTests: SwiftLintTestCase { - func testSwiftLintLints() throws { - try XCTSkipUnless( - ProcessInfo.processInfo.environment["SKIP_INTEGRATION_TESTS"] == nil, - "Will be covered by separate linting job" - ) +@Suite(.rulesRegistered) +struct IntegrationTests { + @Test(.enabled( + if: ProcessInfo.processInfo.environment["SKIP_INTEGRATION_TESTS"] == nil, + "Will be covered by separate linting job" + )) + @WorkingDirectory(path: rootProjectDirectory) + func lint() throws { // This is as close as we're ever going to get to a self-hosting linter. + let config = Configuration(configurationFiles: [Configuration.defaultFileName]) let swiftFiles = config.lintableFiles( inPath: "", forceExclude: false, excludeBy: .paths(excludedPaths: config.excludedPaths())) - XCTAssert( + try #require( swiftFiles.contains(where: { #filePath.bridge().absolutePathRepresentation() == $0.path }), "current file should be included" ) @@ -33,18 +32,26 @@ final class IntegrationTests: SwiftLintTestCase { let violations = swiftFiles.parallelFlatMap { Linter(file: $0, configuration: config).collect(into: storage).styleViolations(using: storage) } - violations.forEach { violation in - violation.location.file!.withStaticString { - XCTFail(violation.reason, file: $0, line: UInt(violation.location.line!)) - } + for violation in violations { + Issue.record( + Comment(rawValue: violation.reason), + sourceLocation: SourceLocation( + fileID: #fileID, + filePath: violation.location.file!, + line: violation.location.line ?? 1, + column: violation.location.character ?? 1 + ) + ) } } - func testSwiftLintAutoCorrects() throws { - try XCTSkipUnless( - ProcessInfo.processInfo.environment["SKIP_INTEGRATION_TESTS"] == nil, - "Corrections are not verified in CI" - ) + @Test(.enabled( + if: ProcessInfo.processInfo.environment["SKIP_INTEGRATION_TESTS"] == nil, + "Corrections are not verified in CI" + )) + @WorkingDirectory(path: rootProjectDirectory) + func correct() throws { + let config = Configuration(configurationFiles: [Configuration.defaultFileName]) let swiftFiles = config.lintableFiles( inPath: "", forceExclude: false, @@ -53,6 +60,6 @@ final class IntegrationTests: SwiftLintTestCase { let corrections = swiftFiles.parallelMap { Linter(file: $0, configuration: config).collect(into: storage).correct(using: storage) } - XCTAssert(corrections.allSatisfy { $0.isEmpty }, "Unexpected corrections have been applied") + try #require(corrections.allSatisfy { $0.isEmpty }, "Unexpected corrections have been applied") } } diff --git a/Tests/MacroTests/AcceptableByConfigurationElementTests.swift b/Tests/MacroTests/AcceptableByConfigurationElementTests.swift index 7728d8f5e8..da8b1b3162 100644 --- a/Tests/MacroTests/AcceptableByConfigurationElementTests.swift +++ b/Tests/MacroTests/AcceptableByConfigurationElementTests.swift @@ -1,7 +1,6 @@ import SwiftSyntaxMacroExpansion import SwiftSyntaxMacrosGenericTestSupport -import SwiftSyntaxMacrosTestSupport -import XCTest +import Testing @testable import SwiftLintCoreMacros @@ -9,8 +8,10 @@ private let macros = [ "AcceptableByConfigurationElement": MacroSpec(type: AcceptableByConfigurationElement.self) ] -final class AcceptableByConfigurationElementTests: XCTestCase { - func testNoEnum() { +@Suite +struct AcceptableByConfigurationElementTests { + @Test + func noEnum() { assertMacroExpansion( """ @AcceptableByConfigurationElement @@ -26,11 +27,12 @@ final class AcceptableByConfigurationElementTests: XCTestCase { DiagnosticSpec(message: SwiftLintCoreMacroError.notEnum.message, line: 1, column: 1) ], macroSpecs: macros, - failureHandler: failureHandler + failureHandler: FailureHandler.instance ) } - func testNoStringRawType() { + @Test + func noStringRawType() { assertMacroExpansion( """ @AcceptableByConfigurationElement @@ -46,11 +48,12 @@ final class AcceptableByConfigurationElementTests: XCTestCase { DiagnosticSpec(message: SwiftLintCoreMacroError.noStringRawType.message, line: 1, column: 1) ], macroSpecs: macros, - failureHandler: failureHandler + failureHandler: FailureHandler.instance ) } - func testPrivateEnum() { + @Test + func privateEnum() { assertMacroExpansion( """ @AcceptableByConfigurationElement @@ -66,7 +69,7 @@ final class AcceptableByConfigurationElementTests: XCTestCase { private func asOption() -> OptionType { .symbol(rawValue) } - private init(fromAny value: Any, context ruleID: String) throws(Issue) { + private init(fromAny value: Any, context ruleID: String) throws(SwiftLintCore.Issue) { if let value = value as? String, let newSelf = Self(rawValue: value) { self = newSelf } else { @@ -76,11 +79,12 @@ final class AcceptableByConfigurationElementTests: XCTestCase { } """, macroSpecs: macros, - failureHandler: failureHandler + failureHandler: FailureHandler.instance ) } - func testPublicEnum() { + @Test + func publicEnum() { assertMacroExpansion( """ @AcceptableByConfigurationElement @@ -96,7 +100,7 @@ final class AcceptableByConfigurationElementTests: XCTestCase { public func asOption() -> OptionType { .symbol(rawValue) } - public init(fromAny value: Any, context ruleID: String) throws(Issue) { + public init(fromAny value: Any, context ruleID: String) throws(SwiftLintCore.Issue) { if let value = value as? String, let newSelf = Self(rawValue: value) { self = newSelf } else { @@ -106,7 +110,7 @@ final class AcceptableByConfigurationElementTests: XCTestCase { } """, macroSpecs: macros, - failureHandler: failureHandler + failureHandler: FailureHandler.instance ) } } diff --git a/Tests/MacroTests/AutoConfigParserTests.swift b/Tests/MacroTests/AutoConfigParserTests.swift index a254855d29..e8863c9b30 100644 --- a/Tests/MacroTests/AutoConfigParserTests.swift +++ b/Tests/MacroTests/AutoConfigParserTests.swift @@ -1,7 +1,6 @@ import SwiftSyntaxMacroExpansion import SwiftSyntaxMacrosGenericTestSupport -import SwiftSyntaxMacrosTestSupport -import XCTest +import Testing @testable import SwiftLintCoreMacros @@ -9,8 +8,10 @@ private let macros = [ "AutoConfigParser": MacroSpec(type: AutoConfigParser.self) ] -final class AutoConfigParserTests: XCTestCase { - func testAttachToClass() { +@Suite +struct AutoConfigParserTests { + @Test + func attachToClass() { assertMacroExpansion( """ @AutoConfigParser @@ -26,11 +27,12 @@ final class AutoConfigParserTests: XCTestCase { DiagnosticSpec(message: SwiftLintCoreMacroError.notStruct.message, line: 1, column: 1) ], macroSpecs: macros, - failureHandler: failureHandler + failureHandler: FailureHandler.instance ) } - func testNoConfigurationElements() { + @Test + func noConfigurationElements() { assertMacroExpansion( """ @AutoConfigParser @@ -41,24 +43,28 @@ final class AutoConfigParserTests: XCTestCase { """ struct S { - mutating func apply(configuration: Any) throws(Issue) { + mutating func apply(configuration: Any) throws(SwiftLintCore.Issue) { guard let configuration = configuration as? [String: Any] else { throw .invalidConfiguration(ruleID: Parent.identifier) } 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() } try validate() } } """, macroSpecs: macros, - failureHandler: failureHandler + failureHandler: FailureHandler.instance ) } - func testConfigurationElementsWithoutKeys() { + @Test + func configurationElementsWithoutKeys() { assertMacroExpansion( """ @AutoConfigParser @@ -77,7 +83,7 @@ final class AutoConfigParserTests: XCTestCase { @ConfigurationElement(key: "name") var eB = 2 - mutating func apply(configuration: Any) throws(Issue) { + mutating func apply(configuration: Any) throws(SwiftLintCore.Issue) { if $eA.key.isEmpty { $eA.key = "e_a" } @@ -95,18 +101,22 @@ final class AutoConfigParserTests: XCTestCase { } 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() } try validate() } } """, macroSpecs: macros, - failureHandler: failureHandler + failureHandler: FailureHandler.instance ) } - func testInlinedConfigurationElements() { + @Test + func inlinedConfigurationElements() { assertMacroExpansion( """ @AutoConfigParser @@ -129,7 +139,7 @@ final class AutoConfigParserTests: XCTestCase { @ConfigurationElement(inline: false) var eC = 3 - mutating func apply(configuration: Any) throws(Issue) { + mutating func apply(configuration: Any) throws(SwiftLintCore.Issue) { if $eA.key.isEmpty { $eA.key = "e_a" } @@ -138,7 +148,7 @@ final class AutoConfigParserTests: XCTestCase { } do { try eB.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. } guard let configuration = configuration as? [String: Any] else { @@ -152,17 +162,21 @@ final class AutoConfigParserTests: XCTestCase { } 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() } try validate() } } """, macroSpecs: macros, - failureHandler: failureHandler) + failureHandler: FailureHandler.instance ) } - func testSeverityBasedConfigurationWithoutSeverityProperty() { + @Test + func severityBasedConfigurationWithoutSeverityProperty() { assertMacroExpansion( """ @AutoConfigParser @@ -173,13 +187,16 @@ final class AutoConfigParserTests: XCTestCase { """ struct S: SeverityBasedRuleConfiguration { - mutating func apply(configuration: Any) throws(Issue) { + mutating func apply(configuration: Any) throws(SwiftLintCore.Issue) { guard let configuration = configuration as? [String: Any] else { throw .invalidConfiguration(ruleID: Parent.identifier) } 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() } try validate() } @@ -193,11 +210,12 @@ final class AutoConfigParserTests: XCTestCase { ), ], macroSpecs: macros, - failureHandler: failureHandler + failureHandler: FailureHandler.instance ) } - func testSeverityAppliedTwice() { + @Test + func severityAppliedTwice() { assertMacroExpansion( """ @AutoConfigParser @@ -216,7 +234,7 @@ final class AutoConfigParserTests: XCTestCase { @ConfigurationElement var foo = 2 - mutating func apply(configuration: Any) throws(Issue) { + mutating func apply(configuration: Any) throws(SwiftLintCore.Issue) { if $severityConfiguration.key.isEmpty { $severityConfiguration.key = "severity_configuration" } @@ -225,7 +243,7 @@ final class AutoConfigParserTests: XCTestCase { } do { try severityConfiguration.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. } guard let configuration = configuration as? [String: Any] else { @@ -239,14 +257,17 @@ final class AutoConfigParserTests: XCTestCase { } 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() } try validate() } } """, macroSpecs: macros, - failureHandler: failureHandler + failureHandler: FailureHandler.instance ) } } diff --git a/Tests/MacroTests/FailureHandler.swift b/Tests/MacroTests/FailureHandler.swift new file mode 100644 index 0000000000..8e9aaf2192 --- /dev/null +++ b/Tests/MacroTests/FailureHandler.swift @@ -0,0 +1,16 @@ +import SwiftSyntaxMacrosGenericTestSupport +import Testing + +enum FailureHandler { + static func instance(_ spec: TestFailureSpec) { + Issue.record( + Comment(rawValue: spec.message), + sourceLocation: .init( + fileID: spec.location.fileID, + filePath: spec.location.filePath, + line: spec.location.line, + column: spec.location.column + ) + ) + } +} diff --git a/Tests/MacroTests/SwiftSyntaxRuleTests.swift b/Tests/MacroTests/SwiftSyntaxRuleTests.swift index eb137b6643..d74ee0b9a3 100644 --- a/Tests/MacroTests/SwiftSyntaxRuleTests.swift +++ b/Tests/MacroTests/SwiftSyntaxRuleTests.swift @@ -1,7 +1,6 @@ import SwiftSyntaxMacroExpansion import SwiftSyntaxMacrosGenericTestSupport -import SwiftSyntaxMacrosTestSupport -import XCTest +import Testing @testable import SwiftLintCoreMacros @@ -9,8 +8,10 @@ private let macros = [ "SwiftSyntaxRule": MacroSpec(type: SwiftSyntaxRule.self) ] -final class SwiftSyntaxRuleTests: XCTestCase { - func testNoArguments() { +@Suite +struct SwiftSyntaxRuleTests { + @Test + func noArguments() { assertMacroExpansion( """ @SwiftSyntaxRule @@ -26,11 +27,12 @@ final class SwiftSyntaxRuleTests: XCTestCase { } """, macroSpecs: macros, - failureHandler: failureHandler + failureHandler: FailureHandler.instance ) } - func testFalseArguments() { + @Test + func falseArguments() { assertMacroExpansion( """ @SwiftSyntaxRule(foldExpressions: false, explicitRewriter: false, correctable: false, optIn: false) @@ -46,11 +48,12 @@ final class SwiftSyntaxRuleTests: XCTestCase { } """, macroSpecs: macros, - failureHandler: failureHandler + failureHandler: FailureHandler.instance ) } - func testTrueArguments() { + @Test + func trueArguments() { assertMacroExpansion( """ @SwiftSyntaxRule(foldExpressions: true, explicitRewriter: true, correctable: true, optIn: true) @@ -81,11 +84,12 @@ final class SwiftSyntaxRuleTests: XCTestCase { } """, macroSpecs: macros, - failureHandler: failureHandler + failureHandler: FailureHandler.instance ) } - func testCorrectableWithoutExplcitRewriter() { + @Test + func correctableWithoutExplcitRewriter() { assertMacroExpansion( """ @SwiftSyntaxRule(correctable: true) @@ -104,11 +108,12 @@ final class SwiftSyntaxRuleTests: XCTestCase { } """, macroSpecs: macros, - failureHandler: failureHandler + failureHandler: FailureHandler.instance ) } - func testArbitraryArguments() { + @Test + func arbitraryArguments() { // Fail with a diagnostic because the macro definition explicitly requires bool arguments. assertMacroExpansion( """ @@ -131,7 +136,7 @@ final class SwiftSyntaxRuleTests: XCTestCase { DiagnosticSpec(message: SwiftLintCoreMacroError.noBooleanLiteral.message, line: 1, column: 88), ], macroSpecs: macros, - failureHandler: failureHandler + failureHandler: FailureHandler.instance ) } } diff --git a/Tests/MacroTests/XCTestCase+FailureHandler.swift b/Tests/MacroTests/XCTestCase+FailureHandler.swift deleted file mode 100644 index 01e9a360b6..0000000000 --- a/Tests/MacroTests/XCTestCase+FailureHandler.swift +++ /dev/null @@ -1,15 +0,0 @@ -import SwiftSyntaxMacrosGenericTestSupport -import TestHelpers -import XCTest - -extension XCTestCase { - func failureHandler(_ spec: TestFailureSpec) { - spec.location.filePath.withStaticString { filePath in - XCTFail( - spec.message, - file: filePath, - line: UInt(spec.location.line), - ) - } - } -} diff --git a/Tests/TestHelpers/SwiftLintTestCase.swift b/Tests/TestHelpers/SwiftLintTestCase.swift deleted file mode 100644 index ad8b591e3b..0000000000 --- a/Tests/TestHelpers/SwiftLintTestCase.swift +++ /dev/null @@ -1,10 +0,0 @@ -import SwiftLintFramework -import XCTest - -// swiftlint:disable:next balanced_xctest_lifecycle -open class SwiftLintTestCase: XCTestCase { - override open class func setUp() { - super.setUp() - RuleRegistry.registerAllRulesOnce() - } -} diff --git a/Tests/TestHelpers/TestHelpers.swift b/Tests/TestHelpers/TestHelpers.swift index 116cefb3ff..c378c198ee 100644 --- a/Tests/TestHelpers/TestHelpers.swift +++ b/Tests/TestHelpers/TestHelpers.swift @@ -289,262 +289,294 @@ private func addShebang(_ example: Example) -> Example { example.with(code: "#!/usr/bin/env swift\n\(example.code)") } -public extension XCTestCase { - var isRunningWithBazel: Bool { FileManager.default.currentDirectoryPath.contains("bazel-out") } - - func verifyRule(_ ruleDescription: RuleDescription, - ruleConfiguration: Any? = nil, - commentDoesntViolate: Bool = true, - stringDoesntViolate: Bool = true, - skipCommentTests: Bool = false, - skipStringTests: Bool = false, - skipDisableCommandTests: Bool = false, - testMultiByteOffsets: Bool = true, - testShebang: Bool = true, - file: StaticString = #filePath, - line: UInt = #line) { - guard ruleDescription.minSwiftVersion <= .current else { - return +public var isRunningWithBazel: Bool { FileManager.default.currentDirectoryPath.contains("bazel-out") } + +public func verifyCorrections(_ ruleDescription: RuleDescription, + config: Configuration, + disableCommands: [String], + testMultiByteOffsets: Bool, + parserDiagnosticsDisabledForTests: Bool = true) { + let ruleDescription = ruleDescription.focused() + SwiftLintCore.$parserDiagnosticsDisabledForTests.withValue(parserDiagnosticsDisabledForTests) { + // corrections + ruleDescription.corrections.forEach { + testCorrection($0, configuration: config, testMultiByteOffsets: testMultiByteOffsets) } - - guard let config = makeConfig( - ruleConfiguration, - ruleDescription.identifier, - skipDisableCommandTests: skipDisableCommandTests) else { - XCTFail("Failed to create configuration", file: (file), line: line) - return + // make sure strings that don't trigger aren't corrected + ruleDescription.nonTriggeringExamples.forEach { + testCorrection(($0, $0), configuration: config, testMultiByteOffsets: testMultiByteOffsets) } - let disableCommands: [String] - if skipDisableCommandTests { - disableCommands = [] - } else { - disableCommands = ruleDescription.allIdentifiers.map { "// swiftlint:disable \($0)\n" } + // "disable" commands do not correct + ruleDescription.corrections.forEach { before, _ in + for command in disableCommands { + let beforeDisabled = command + before.code + let expectedCleaned = before.with(code: cleanedContentsAndMarkerOffsets(from: beforeDisabled).0) + config.assertCorrection(expectedCleaned, expected: expectedCleaned) + } } + } +} - self.verifyLint(ruleDescription, config: config, commentDoesntViolate: commentDoesntViolate, - stringDoesntViolate: stringDoesntViolate, skipCommentTests: skipCommentTests, - skipStringTests: skipStringTests, disableCommands: disableCommands, - testMultiByteOffsets: testMultiByteOffsets, testShebang: testShebang, - file: file, line: line) - self.verifyCorrections(ruleDescription, config: config, disableCommands: disableCommands, - testMultiByteOffsets: testMultiByteOffsets) - } - - // swiftlint:disable:next function_body_length - func verifyLint(_ ruleDescription: RuleDescription, - config: Configuration, - commentDoesntViolate: Bool = true, - stringDoesntViolate: Bool = true, - skipCommentTests: Bool = false, - skipStringTests: Bool = false, - disableCommands: [String] = [], - testMultiByteOffsets: Bool = true, - testShebang: Bool = true, - file: StaticString = #filePath, - line: UInt = #line) { - func verify(triggers: [Example], nonTriggers: [Example]) { - verifyExamples(triggers: triggers, nonTriggers: nonTriggers, configuration: config, - requiresFileOnDisk: ruleDescription.requiresFileOnDisk) - } - func makeViolations(_ example: Example) -> [StyleViolation] { - violations(example, config: config, requiresFileOnDisk: ruleDescription.requiresFileOnDisk) - } +public func verifyRule(_ ruleDescription: RuleDescription, + ruleConfiguration: Any? = nil, + commentDoesntViolate: Bool = true, + stringDoesntViolate: Bool = true, + skipCommentTests: Bool = false, + skipStringTests: Bool = false, + skipDisableCommandTests: Bool = false, + testMultiByteOffsets: Bool = true, + testShebang: Bool = true, + file: StaticString = #filePath, + line: UInt = #line) { + guard ruleDescription.minSwiftVersion <= .current else { + return + } - let focusedRuleDescription = ruleDescription.focused() - let (triggers, nonTriggers) = ( - focusedRuleDescription.triggeringExamples, - focusedRuleDescription.nonTriggeringExamples + guard let config = makeConfig( + ruleConfiguration, + ruleDescription.identifier, + skipDisableCommandTests: skipDisableCommandTests) else { + XCTFail("Failed to create configuration", file: (file), line: line) + return + } + + let disableCommands: [String] + if skipDisableCommandTests { + disableCommands = [] + } else { + disableCommands = ruleDescription.allIdentifiers.map { "// swiftlint:disable \($0)\n" } + } + + verifyLint( + ruleDescription, + config: config, + commentDoesntViolate: commentDoesntViolate, + stringDoesntViolate: stringDoesntViolate, + skipCommentTests: skipCommentTests, + skipStringTests: skipStringTests, + disableCommands: disableCommands, + testMultiByteOffsets: testMultiByteOffsets, + testShebang: testShebang, + file: file, + line: line + ) + verifyCorrections( + ruleDescription, + config: config, + disableCommands: disableCommands, + testMultiByteOffsets: testMultiByteOffsets + ) +} + +// swiftlint:disable:next function_body_length +func verifyLint(_ ruleDescription: RuleDescription, + config: Configuration, + commentDoesntViolate: Bool = true, + stringDoesntViolate: Bool = true, + skipCommentTests: Bool = false, + skipStringTests: Bool = false, + disableCommands: [String] = [], + testMultiByteOffsets: Bool = true, + testShebang: Bool = true, + file: StaticString = #filePath, + line: UInt = #line) { + func verify(triggers: [Example], nonTriggers: [Example]) { + verifyExamples( + triggers: triggers, + nonTriggers: nonTriggers, + configuration: config, + requiresFileOnDisk: ruleDescription.requiresFileOnDisk ) - verify(triggers: triggers, nonTriggers: nonTriggers) + } + func makeViolations(_ example: Example) -> [StyleViolation] { + violations(example, config: config, requiresFileOnDisk: ruleDescription.requiresFileOnDisk) + } - if testMultiByteOffsets { - verify(triggers: triggers.filter(\.testMultiByteOffsets).map(addEmoji), - nonTriggers: nonTriggers.filter(\.testMultiByteOffsets).map(addEmoji)) - } + let focusedRuleDescription = ruleDescription.focused() + let (triggers, nonTriggers) = ( + focusedRuleDescription.triggeringExamples, + focusedRuleDescription.nonTriggeringExamples + ) + verify(triggers: triggers, nonTriggers: nonTriggers) + + if testMultiByteOffsets { + verify( + triggers: triggers.filter(\.testMultiByteOffsets).map(addEmoji), + nonTriggers: nonTriggers.filter(\.testMultiByteOffsets).map(addEmoji) + ) + } - if testShebang { - verify(triggers: triggers.filter(\.testMultiByteOffsets).map(addShebang), - nonTriggers: nonTriggers.filter(\.testMultiByteOffsets).map(addShebang)) - } + if testShebang { + verify( + triggers: triggers.filter(\.testMultiByteOffsets).map(addShebang), + nonTriggers: nonTriggers.filter(\.testMultiByteOffsets).map(addShebang) + ) + } - // Comment doesn't violate - if !skipCommentTests { - let triggersToCheck = triggers.filter(\.testWrappingInComment) - XCTAssertEqual( - triggersToCheck.flatMap { makeViolations($0.with(code: "/*\n " + $0.code + "\n */")) }.count, - commentDoesntViolate ? 0 : triggersToCheck.count, - "Violation(s) still triggered when code was nested inside a comment", - file: (file), line: line - ) - } + // Comment doesn't violate + if !skipCommentTests { + let triggersToCheck = triggers.filter(\.testWrappingInComment) + XCTAssertEqual( + triggersToCheck.flatMap { makeViolations($0.with(code: "/*\n " + $0.code + "\n */")) }.count, + commentDoesntViolate ? 0 : triggersToCheck.count, + "Violation(s) still triggered when code was nested inside a comment", + file: (file), line: line + ) + } - // String doesn't violate - if !skipStringTests { - let triggersToCheck = triggers.filter(\.testWrappingInString) - XCTAssertEqual( - triggersToCheck.flatMap({ makeViolations($0.with(code: $0.code.toStringLiteral())) }).count, - stringDoesntViolate ? 0 : triggersToCheck.count, - "Violation(s) still triggered when code was nested inside a string literal", - file: (file), line: line - ) - } + // String doesn't violate + if !skipStringTests { + let triggersToCheck = triggers.filter(\.testWrappingInString) + XCTAssertEqual( + triggersToCheck.flatMap({ makeViolations($0.with(code: $0.code.toStringLiteral())) }).count, + stringDoesntViolate ? 0 : triggersToCheck.count, + "Violation(s) still triggered when code was nested inside a string literal", + file: (file), line: line + ) + } - // Disabled rule doesn't violate and disable command isn't superfluous - for command in disableCommands { - let disabledTriggers = triggers - .filter(\.testDisableCommand) - .map { $0.with(code: command + $0.code) } - - for trigger in disabledTriggers { - let violationsPartitionedByType = makeViolations(trigger) - .partitioned { $0.ruleIdentifier == SuperfluousDisableCommandRule.identifier } - - XCTAssert(violationsPartitionedByType.first.isEmpty, - "Violation(s) still triggered although rule was disabled", - file: trigger.file, - line: trigger.line) - XCTAssert(violationsPartitionedByType.second.isEmpty, - "Disable command was superfluous since no violations(s) triggered", - file: trigger.file, - line: trigger.line) - } - } + // Disabled rule doesn't violate and disable command isn't superfluous + for command in disableCommands { + let disabledTriggers = triggers + .filter(\.testDisableCommand) + .map { $0.with(code: command + $0.code) } + + for trigger in disabledTriggers { + let violationsPartitionedByType = makeViolations(trigger) + .partitioned { $0.ruleIdentifier == SuperfluousDisableCommandRule.identifier } - // Severity can be changed - let ruleType = RuleRegistry.shared.rule(forID: ruleDescription.identifier) - if ruleType?.init().configuration is (any SeverityBasedRuleConfiguration), - let example = triggers.first(where: { $0.configuration == nil }) { - let withWarning = Example(example.code, configuration: ["severity": "warning"]) XCTAssert( - violations(withWarning, config: config).allSatisfy { $0.severity == .warning }, - "Violation severity cannot be changed to warning", - file: example.file, - line: 1 + violationsPartitionedByType.first.isEmpty, + "Violation(s) still triggered although rule was disabled", + file: trigger.file, + line: trigger.line ) - - let withError = Example(example.code, configuration: ["severity": "error"]) XCTAssert( - violations(withError, config: config).allSatisfy { $0.severity == .error }, - "Violation severity cannot be changed to error", - file: example.file, - line: 1 + violationsPartitionedByType.second.isEmpty, + "Disable command was superfluous since no violations(s) triggered", + file: trigger.file, + line: trigger.line ) } } - func verifyCorrections(_ ruleDescription: RuleDescription, - config: Configuration, - disableCommands: [String], - testMultiByteOffsets: Bool, - parserDiagnosticsDisabledForTests: Bool = true) { - let ruleDescription = ruleDescription.focused() + // Severity can be changed + let ruleType = RuleRegistry.shared.rule(forID: ruleDescription.identifier) + if ruleType?.init().configuration is (any SeverityBasedRuleConfiguration), + let example = triggers.first(where: { $0.configuration == nil }) { + let withWarning = Example(example.code, configuration: ["severity": "warning"]) + XCTAssert( + violations(withWarning, config: config).allSatisfy { $0.severity == .warning }, + "Violation severity cannot be changed to warning", + file: example.file, + line: 1 + ) - SwiftLintCore.$parserDiagnosticsDisabledForTests.withValue(parserDiagnosticsDisabledForTests) { - // corrections - ruleDescription.corrections.forEach { - testCorrection($0, configuration: config, testMultiByteOffsets: testMultiByteOffsets) - } - // make sure strings that don't trigger aren't corrected - ruleDescription.nonTriggeringExamples.forEach { - testCorrection(($0, $0), configuration: config, testMultiByteOffsets: testMultiByteOffsets) - } + let withError = Example(example.code, configuration: ["severity": "error"]) + XCTAssert( + violations(withError, config: config).allSatisfy { $0.severity == .error }, + "Violation severity cannot be changed to error", + file: example.file, + line: 1 + ) + } +} - // "disable" commands do not correct - ruleDescription.corrections.forEach { before, _ in - for command in disableCommands { - let beforeDisabled = command + before.code - let expectedCleaned = before.with(code: cleanedContentsAndMarkerOffsets(from: beforeDisabled).0) - config.assertCorrection(expectedCleaned, expected: expectedCleaned) - } - } - } +// swiftlint:disable:next function_body_length +private func verifyExamples(triggers: [Example], + nonTriggers: [Example], + configuration config: Configuration, + requiresFileOnDisk: Bool) { + // Non-triggering examples don't violate + for nonTrigger in nonTriggers { + let unexpectedViolations = violations( + nonTrigger, + config: config, + requiresFileOnDisk: requiresFileOnDisk + ) + if unexpectedViolations.isEmpty { continue } + let nonTriggerWithViolations = render(violations: unexpectedViolations, in: nonTrigger.code) + XCTFail( + "nonTriggeringExample violated: \n\(nonTriggerWithViolations)", + file: nonTrigger.file, + line: nonTrigger.line) } - private func verifyExamples(triggers: [Example], - nonTriggers: [Example], - configuration config: Configuration, - requiresFileOnDisk: Bool) { - // Non-triggering examples don't violate - for nonTrigger in nonTriggers { - let unexpectedViolations = violations(nonTrigger, config: config, - requiresFileOnDisk: requiresFileOnDisk) - if unexpectedViolations.isEmpty { continue } - let nonTriggerWithViolations = render(violations: unexpectedViolations, in: nonTrigger.code) - XCTFail( - "nonTriggeringExample violated: \n\(nonTriggerWithViolations)", - file: nonTrigger.file, - line: nonTrigger.line) - } + // Triggering examples violate + for trigger in triggers { + let triggerViolations = violations( + trigger, + config: config, + requiresFileOnDisk: requiresFileOnDisk + ) - // Triggering examples violate - for trigger in triggers { - let triggerViolations = violations(trigger, config: config, - requiresFileOnDisk: requiresFileOnDisk) - - // Triggering examples with violation markers violate at the marker's location - let (cleanTrigger, markerOffsets) = cleanedContentsAndMarkerOffsets(from: trigger.code) - if markerOffsets.isEmpty { - if triggerViolations.isEmpty { - XCTFail( - "triggeringExample did not violate: \n```\n\(trigger.code)\n```", - file: trigger.file, - line: trigger.line) - } - continue - } - let file = SwiftLintFile.testFile(withContents: cleanTrigger) - let expectedLocations = markerOffsets.map { Location(file: file, characterOffset: $0) } - - // Assert violations on unexpected location - let violationsAtUnexpectedLocation = triggerViolations - .filter { !expectedLocations.contains($0.location) } - if !violationsAtUnexpectedLocation.isEmpty { - XCTFail("triggeringExample violated at unexpected location: \n" + - "\(render(violations: violationsAtUnexpectedLocation, in: cleanTrigger))", + // Triggering examples with violation markers violate at the marker's location + let (cleanTrigger, markerOffsets) = cleanedContentsAndMarkerOffsets(from: trigger.code) + if markerOffsets.isEmpty { + if triggerViolations.isEmpty { + XCTFail( + "triggeringExample did not violate: \n```\n\(trigger.code)\n```", file: trigger.file, line: trigger.line) } + continue + } + let file = SwiftLintFile.testFile(withContents: cleanTrigger) + let expectedLocations = markerOffsets.map { Location(file: file, characterOffset: $0) } + + // Assert violations on unexpected location + let violationsAtUnexpectedLocation = triggerViolations + .filter { !expectedLocations.contains($0.location) } + if !violationsAtUnexpectedLocation.isEmpty { + XCTFail("triggeringExample violated at unexpected location: \n" + + "\(render(violations: violationsAtUnexpectedLocation, in: cleanTrigger))", + file: trigger.file, + line: trigger.line) + } - // Assert locations missing violation - let violatedLocations = triggerViolations.map(\.location) - let locationsWithoutViolation = expectedLocations - .filter { !violatedLocations.contains($0) } - if !locationsWithoutViolation.isEmpty { - XCTFail("triggeringExample did not violate at expected location: \n" + - "\(render(locations: locationsWithoutViolation, in: cleanTrigger))", - file: trigger.file, - line: trigger.line) - } + // Assert locations missing violation + let violatedLocations = triggerViolations.map(\.location) + let locationsWithoutViolation = expectedLocations + .filter { !violatedLocations.contains($0) } + if !locationsWithoutViolation.isEmpty { + XCTFail("triggeringExample did not violate at expected location: \n" + + "\(render(locations: locationsWithoutViolation, in: cleanTrigger))", + file: trigger.file, + line: trigger.line) + } - XCTAssertEqual(triggerViolations.count, expectedLocations.count, - file: trigger.file, line: trigger.line) - for (triggerViolation, expectedLocation) in zip(triggerViolations, expectedLocations) { - XCTAssertEqual( - triggerViolation.location, expectedLocation, - "'\(trigger)' violation didn't match expected location.", - file: trigger.file, - line: trigger.line) - } + XCTAssertEqual( + triggerViolations.count, + expectedLocations.count, + file: trigger.file, + line: trigger.line + ) + for (triggerViolation, expectedLocation) in zip(triggerViolations, expectedLocations) { + XCTAssertEqual( + triggerViolation.location, expectedLocation, + "'\(trigger)' violation didn't match expected location.", + file: trigger.file, + line: trigger.line) } } +} - // file and line parameters are first so we can use trailing closure syntax with the closure - func checkError( - file: StaticString = #filePath, - line: UInt = #line, - _ error: T, - closure: () throws -> Void) { - do { - try closure() - XCTFail("No error caught", file: (file), line: line) - } catch let rError as T { - if error != rError { - XCTFail("Wrong error caught. Got \(rError) but was expecting \(error)", file: (file), line: line) - } - } catch { - XCTFail("Wrong error caught", file: (file), line: line) +// file and line parameters are first so we can use trailing closure syntax with the closure +public func checkError( + file: StaticString = #filePath, + line: UInt = #line, + _ error: T, + closure: () throws -> Void) { + do { + try closure() + XCTFail("No error caught", file: (file), line: line) + } catch let rError as T { + if error != rError { + XCTFail("Wrong error caught. Got \(rError) but was expecting \(error)", file: (file), line: line) } + } catch { + XCTFail("Wrong error caught", file: (file), line: line) } } diff --git a/Tests/TestHelpers/Traits.swift b/Tests/TestHelpers/Traits.swift new file mode 100644 index 0000000000..26c4858c39 --- /dev/null +++ b/Tests/TestHelpers/Traits.swift @@ -0,0 +1,52 @@ +import Foundation +import SwiftLintCore +import Testing + +public struct RuleRegisterer: TestScoping, SuiteTrait, TestTrait { + public func provideScope( + for _: Test, + testCase _: Test.Case?, + performing function: () async throws -> Void + ) async throws { + RuleRegistry.registerAllRulesOnce() + try await function() + } +} + +public extension Trait where Self == RuleRegisterer { + static var rulesRegistered: Self { Self() } +} + +public struct SourceKitRequestsWithoutRule: TestScoping, SuiteTrait, TestTrait { + public func provideScope( + for _: Test, + testCase _: Test.Case?, + performing function: () async throws -> Void + ) async throws { + try await CurrentRule.$allowSourceKitRequestWithoutRule.withValue(true) { + try await function() + } + } +} + +public extension Trait where Self == SourceKitRequestsWithoutRule { + static var sourceKitRequestsWithoutRule: Self { Self() } +} + +public struct DisableParserDiagnosticsInTests: TestScoping, SuiteTrait, TestTrait { + fileprivate let value: Bool + + public func provideScope( + for _: Test, + testCase _: Test.Case?, + performing function: () async throws -> Void + ) async throws { + try await $parserDiagnosticsDisabledForTests.withValue(!value) { + try await function() + } + } +} + +public extension Trait where Self == DisableParserDiagnosticsInTests { + static func parserDiagnosticsEnabled(_ value: Bool) -> Self { Self(value: value) } +}