diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index d14c4db..7162e8a 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -9,19 +9,41 @@ on: permissions: contents: read +env: + SWIFT_VERSION: '6.2' + jobs: test: name: Run Tests - runs-on: macos-latest + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: + - macos-latest + - ubuntu-22.04 + - windows-2022 steps: - name: Checkout code uses: actions/checkout@v4 - name: Setup Swift + if: matrix.os != 'windows-2022' uses: swift-actions/setup-swift@v2 with: - swift-version: '6.2' + swift-version: ${{ env.SWIFT_VERSION }} + + - name: Setup Swift (Windows) + if: matrix.os == 'windows-2022' + uses: SwiftyLab/setup-swift@latest + with: + swift-version: ${{ env.SWIFT_VERSION }} + + - name: Run Swift tests + if: matrix.os != 'windows-2022' + run: swift test - name: Run Swift tests + if: matrix.os == 'windows-2022' run: swift test + shell: bash diff --git a/Tests/GameCLITests/RunLogPersistenceTests.swift b/Tests/GameCLITests/RunLogPersistenceTests.swift index 060840c..c5c83ba 100644 --- a/Tests/GameCLITests/RunLogPersistenceTests.swift +++ b/Tests/GameCLITests/RunLogPersistenceTests.swift @@ -2,6 +2,10 @@ import Foundation import XCTest @testable import GameCLI +#if os(Windows) +import WinSDK +#endif + final class RunLogPersistenceTests: XCTestCase { func testRunLogService_stripsANSIAndAddsTimestamp() { print("🧪 测试:testRunLogService_stripsANSIAndAddsTimestamp") @@ -39,6 +43,13 @@ final class RunLogPersistenceTests: XCTestCase { defer { try? FileManager.default.removeItem(at: tmp) } let key = "SALU_DATA_DIR" +#if os(Windows) + let old = ProcessInfo.processInfo.environment[key] + defer { + setEnvironmentVariable(key, old) + } + setEnvironmentVariable(key, tmp.path) +#else let old = getenv(key).flatMap { String(cString: $0) } defer { if let old { @@ -48,6 +59,7 @@ final class RunLogPersistenceTests: XCTestCase { } } setenv(key, tmp.path, 1) +#endif let store = FileRunLogStore() store.appendLine("line1\n") @@ -91,3 +103,17 @@ private final class InMemoryRunLogStore: RunLogStore, @unchecked Sendable { clearCount += 1 } } + +#if os(Windows) +private func setEnvironmentVariable(_ key: String, _ value: String?) { + let result: Bool = key.withCString(encodedAs: UTF16.self) { keyPtr in + if let value { + return value.withCString(encodedAs: UTF16.self) { valuePtr in + SetEnvironmentVariableW(keyPtr, valuePtr) + } + } + return SetEnvironmentVariableW(keyPtr, nil) + } + XCTAssertTrue(result, "Failed to set environment variable \(key)") +} +#endif diff --git a/Tests/GameCLITests/ScreenAndRoomCoverageTests.swift b/Tests/GameCLITests/ScreenAndRoomCoverageTests.swift index 67471db..d8c8d0a 100644 --- a/Tests/GameCLITests/ScreenAndRoomCoverageTests.swift +++ b/Tests/GameCLITests/ScreenAndRoomCoverageTests.swift @@ -3,6 +3,13 @@ import XCTest @testable import GameCLI import GameCore +#if os(Windows) +final class ScreenAndRoomCoverageTests: XCTestCase { + func testWindowsSkip() throws { + throw XCTSkip("Screen output capture uses POSIX APIs that are unavailable on Windows.") + } +} +#else #if canImport(Darwin) @preconcurrency import Darwin #else @@ -199,6 +206,7 @@ final class ScreenAndRoomCoverageTests: XCTestCase { XCTAssertEqual(store.records.first?.won, true) } } +#endif private extension String { func strippingANSICodes() -> String {