diff --git a/Source/SwiftLintBuiltInRules/Rules/Lint/UnusedImportRuleExamples.swift b/Source/SwiftLintBuiltInRules/Rules/Lint/UnusedImportRuleExamples.swift index fdd33285e1..91e06e138f 100644 --- a/Source/SwiftLintBuiltInRules/Rules/Lint/UnusedImportRuleExamples.swift +++ b/Source/SwiftLintBuiltInRules/Rules/Lint/UnusedImportRuleExamples.swift @@ -190,7 +190,7 @@ struct UnusedImportRuleExamples { "allowed_transitive_imports": ["CoreFoundation", "Dispatch"], ] as [String: any Sendable], ], - ] as [String: any Sendable], testMultiByteOffsets: false, testOnLinux: false): + ] as [String: any Sendable], testMultiByteOffsets: false, testOnLinux: false, testOnWindows: false): Example(""" import Foundation typealias Foo = CFArray @@ -202,7 +202,7 @@ struct UnusedImportRuleExamples { dispatchMain() """, configuration: [ "require_explicit_imports": true - ], testMultiByteOffsets: false, testOnLinux: false): + ], testMultiByteOffsets: false, testOnLinux: false, testOnWindows: false): Example(""" import CoreFoundation import Dispatch @@ -236,7 +236,7 @@ struct UnusedImportRuleExamples { class A {} """, configuration: [ "require_explicit_imports": true - ], testMultiByteOffsets: false, testOnLinux: false): + ], testMultiByteOffsets: false, testOnLinux: false, testOnWindows: false): Example(""" import CoreFoundation import Foundation diff --git a/Source/SwiftLintCore/Models/Example.swift b/Source/SwiftLintCore/Models/Example.swift index cc9e46737e..f1a232b505 100644 --- a/Source/SwiftLintCore/Models/Example.swift +++ b/Source/SwiftLintCore/Models/Example.swift @@ -28,6 +28,8 @@ public struct Example: Sendable { package private(set) var testDisableCommand: Bool /// Whether the example should be tested on Linux public private(set) var testOnLinux: Bool + /// Whether the example should be tested on Windows + public private(set) var testOnWindows: Bool /// The path to the file where the example was created public private(set) var file: StaticString /// The line in the file where the example was created @@ -68,6 +70,7 @@ public extension Example { testWrappingInString: Bool = true, testDisableCommand: Bool = true, testOnLinux: Bool = true, + testOnWindows: Bool = true, file: StaticString = #filePath, line: UInt = #line, excludeFromDocumentation: Bool = false) { @@ -75,6 +78,7 @@ public extension Example { self.configuration = configuration self.testMultiByteOffsets = testMultiByteOffsets self.testOnLinux = testOnLinux + self.testOnWindows = testOnWindows self.file = file self.line = line self.excludeFromDocumentation = excludeFromDocumentation diff --git a/Tests/TestHelpers/TestHelpers.swift b/Tests/TestHelpers/TestHelpers.swift index 07d6e107fb..5c03260836 100644 --- a/Tests/TestHelpers/TestHelpers.swift +++ b/Tests/TestHelpers/TestHelpers.swift @@ -4,6 +4,45 @@ import XCTest import SwiftLintFramework +#if os(Windows) +private struct PlatformInfo { + struct DefaultProperties { + let versionXCTest: String + let versionSwiftTesting: String + let swiftFlags: [String]? + } + + let defaults: DefaultProperties +} + +extension PlatformInfo.DefaultProperties: Decodable { + enum CodingKeys: String, CodingKey { + case versionXCTest = "XCTEST_VERSION" + case versionSwiftTesting = "SWIFT_TESTING_VERSION" + case swiftFlags = "SWIFTC_FLAGS" + } +} + +extension PlatformInfo: Decodable { + enum CodingKeys: String, CodingKey { + case defaults = "DefaultProperties" + } +} + +private let info: PlatformInfo = { + let sdk = URL(fileURLWithPath: sdkPath(), isDirectory: true) + .deletingLastPathComponent() + .deletingLastPathComponent() + .deletingLastPathComponent() + .appendingPathComponent("Info.plist") + guard let data = try? Data(contentsOf: sdk), + let info = try? PropertyListDecoder().decode(PlatformInfo.self, from: data) else { + fatalError("invalid platform SDK - couldn't decode \(sdk.path)") + } + return info +}() +#endif + // swiftlint:disable file_length private let violationMarker = "↓" @@ -28,12 +67,29 @@ private extension SwiftLintFile { .appendingPathComponent("Library") .appendingPathComponent("Frameworks") .path - return [ - "-F", - frameworks, + + let arguments = [ + "-F", frameworks, "-sdk", sdk, - "-j4", path!, + "-Xfrontend", "-enable-objc-interop", + "-j4", + path!, ] +#if os(Windows) + let XCTestPath = URL(fileURLWithPath: sdk, isDirectory: true) + .deletingLastPathComponent() + .deletingLastPathComponent() + .appendingPathComponent("Library") + .appendingPathComponent("XCTest-\(info.defaults.versionXCTest)") + .appendingPathComponent("usr") + .appendingPathComponent("lib") + .appendingPathComponent("swift") + .appendingPathComponent("windows") + .path + return ["-I", XCTestPath] + arguments +#else + return arguments +#endif } } @@ -265,6 +321,11 @@ private func testCorrection(_ correction: (Example, Example), guard correction.0.testOnLinux else { return } +#endif +#if os(Windows) + guard correction.0.testOnWindows else { + return + } #endif var config = configuration if let correctionConfiguration = correction.0.configuration,