Convert test suite to Swift Testing with BDD scenarios - #7
Open
ARamy23 wants to merge 1 commit into
Open
Conversation
Rewrites NightcapAppTests from XCTest to Swift Testing, organised as one @suite per feature with numbered Given/When/Then scenarios. Behaviour is characterised rather than changed: no production code is touched. Notable additions beyond a straight translation: - removeAppRequested had no coverage at all. Three scenarios now cover removing a running app, removing an idle one, and removing one of two running apps (the assertion must survive for the other). - The assertion reason string is asserted when a second watched app launches, so the pmset-visible reason stays truthful. - A scenario covers IOKit refusing the assertion, where the app must not claim the Mac is being kept awake. - test_terminate_event_keeps_assertion_when_another_instance_still_running previously asserted nothing. It now checks that release() is not called. Tests are given an in-memory file storage dependency. Swift Testing runs suites in parallel, and @shared(.fileStorage) would otherwise be shared mutable state across scenarios. scripts/check-domain-coverage.sh enforces a floor on pure-domain coverage from an .xcresult bundle. Live adapters (NSWorkspace, IOKit, SMAppService, StoreKit) and SwiftUI views are excluded by design; covering those means integration tests, not characterisation. 20 scenarios, all passing. Domain coverage 96.04% (291/303), up from 93.70% (284/303). Claude-Session: https://claude.ai/code/session_01WGsVLm7Vs83QN4o1tCaCLw
This was referenced Jul 28, 2026
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.
Rewrites
NightcapAppTestsfrom XCTest to Swift Testing, organised as one@Suiteper feature with numbered Given/When/Then scenarios. No production code is touched — this characterises current behaviour rather than changing it.Gaps this found
removeAppRequestedhad zero coverage. Three scenarios now cover removing a running app, removing an idle one, and removing one of two running apps (the assertion must survive for the other).test_terminate_event_keeps_assertion_when_another_instance_still_runningasserted nothing — it only checked the store didn't mutate. It now verifiesrelease()is never called.IOPMAssertionCreateWithNamefails.pmset -g assertionsstays truthful.Parallelism fix
Swift Testing runs suites in parallel where XCTest ran serially.
AppFeature.Stateuses@Shared(.fileStorage(...))against a real container JSON, which would be shared mutable state across scenarios. Each test store now getsdefaultFileStorage = .inMemory— isolation rather than forcing.serialized, so the suite stays parallel.Coverage
scripts/check-domain-coverage.shenforces a floor on pure-domain coverage from an.xcresult. Live adapters (NSWorkspace, IOKit, SMAppService, StoreKit) and SwiftUI views are excluded by design — covering those means integration tests, not characterisation.WatchedApp.swiftLaunchAtLoginStatus.swiftAppFeature.swiftBaseline measurements are recorded in
docs/roadmap/S1-coverage-baseline.md.One behaviour worth a look
syncAssertioncallsassertion.release()unconditionally whenever no watched app is running — including on.onAppearwhen nothing was ever held.AssertionHolderguards onheld, so it's a harmless no-op at the IOKit layer, but it's visible to any test counting release calls. Characterised as-is rather than changed; happy to tighten it if you'd prefer.Notes
.gitignoregainsproject.local.yml, a local xcodegen spec override.project.ymlpinsDEVELOPMENT_TEAM, so contributors without that team can't build; a local override spec lets them use ad-hoc signing without dirtying the repo.https://claude.ai/code/session_01WGsVLm7Vs83QN4o1tCaCLw