From 4f56443d64820e17b18fbe76a154ae2b5f6f9bbd Mon Sep 17 00:00:00 2001 From: hollandcloud Date: Sun, 18 Oct 2026 09:53:47 -0400 Subject: [PATCH] Keep test settings out of ~/Library/Preferences ScratchSettings gave every test its own ClearedTests. defaults suite and called removePersistentDomain in deinit. That empties the domain but leaves a 42-byte plist behind in ~/Library/Preferences, so each test run added one file per test (72 had piled up). Name the suite with an absolute path in the temporary directory instead. CFPreferences stores such a domain as a plain plist at that path, so nothing reaches ~/Library/Preferences, and deinit deletes the file. Deleting a leaked plist from ~/Library/Preferences in teardown is not reliable: the preferences daemon can write it back while the domain is still cached. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01ExCvUisv1HRzoGqhBztmCk --- Tests/ClearedTests/AppModelTests.swift | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/Tests/ClearedTests/AppModelTests.swift b/Tests/ClearedTests/AppModelTests.swift index 6eb57fa..7f8680e 100644 --- a/Tests/ClearedTests/AppModelTests.swift +++ b/Tests/ClearedTests/AppModelTests.swift @@ -4,17 +4,24 @@ import Foundation /// Settings backed by a throwaway defaults domain, so a test never reads or /// writes the preferences of the person running it. +/// +/// The suite name is an absolute path in the temporary directory, which +/// CFPreferences stores as a plain plist file there. A named suite would live in +/// ~/Library/Preferences, and `removePersistentDomain` empties it but leaves the +/// plist behind, so every test run used to add one file per test. @MainActor final class ScratchSettings { let settings: Settings - private let domain = "ClearedTests.\(UUID().uuidString)" + private let path = FileManager.default.temporaryDirectory + .appending(path: "ClearedTests.\(UUID().uuidString)").path init() { - settings = Settings(defaults: UserDefaults(suiteName: domain)!) + settings = Settings(defaults: UserDefaults(suiteName: path)!) } deinit { - UserDefaults.standard.removePersistentDomain(forName: domain) + // Best effort: anything left over sits in the temporary directory, which the system clears. + try? FileManager.default.removeItem(atPath: path + ".plist") } }