chore(tests): type-check test sources without Xcode - #142
Merged
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
swift testneeds the XCTest module, which only ships with full Xcode. On aCommand Line Tools-only machine the whole test target fails to load — so the test
sources are the one part of this repo that never gets compiled locally.
That has a concrete cost. On #139, tightening
series()to require asource:parameter broke 12 call sites in
UsageHistoryTests.swift. Every production filehad been type-checked; the test file could not be, so
swift testfailed in CI ona pure build error. Signature-tightening changes are exactly the ones that break
callers you cannot see.
Change
make typecheck-testscompiles the test sources in-module against the real paneltypes, with XCTest swapped for stand-ins in
scripts/xctest-shim.swift. Takes afew seconds and would have caught the above before pushing.
It does not run assertions —
make testand CI remain the authority on whethertests pass. Not wired into CI, which runs the real
swift testand subsumes this.How it works
import XCTestreplaced byimport AppKit/import SwiftUI, and@testable importdropped sinceeverything compiles as one module.
panel/main.swiftis excluded so its top-level code doesn't clash;build.shtype-checks that file as part of the real build.
panel/carries a stack of pre-existing macOS 14deprecation warnings that would bury the errors this exists to surface.
Tests/StackNudgePanelCoreTests/, so errors name the file you actually editrather than a temp dir that no longer exists.
Shim fidelity
Four details produced false errors before being fixed, all worth knowing if the
shim ever needs extending:
import XCTest, don't delete it — XCTest re-exports Foundation, andseveral test files rely on that for
Calendar/TimeZone.XCTAssertEqual(_:_:accuracy:)needs its own FloatingPoint overload(
EventListenerTestsuses it).XCTestCaseneedssetUp/tearDown/setUpWithError/tearDownWithError.@MainActor, matching real XCTest — otherwise a@MainActortest class's override becomes nonisolated and can't touch its own properties.
If the suite starts using an undeclared
XCTAssertvariant, the type-check failswith "cannot find 'XCTAssertSomething' in scope"; the fix is to add the overload.
Testing
the required
source:argument): exits 1, and namesTests/StackNudgePanelCoreTests/…rather than the temp path.bash -nandshellcheck --severity=warningclean, so the new script satisfiesthe checks CI already runs over tracked shell.
swift buildand./build.shboth unaffected by the newscripts/directory —the shim is never compiled into the app, since both take their sources from
panel/andshared/only.