Injectable UserDefaults to fix race condition in tests (#741)

This commit is contained in:
Islam
2025-10-02 12:59:48 +02:00
committed by GitHub
parent 90273cee2d
commit bd11940151
2 changed files with 18 additions and 14 deletions
+8 -5
View File
@@ -20,8 +20,11 @@ final class GeohashBookmarksStore: ObservableObject {
private let geocoder = CLGeocoder()
private var resolving: Set<String> = []
#endif
private let storage: UserDefaults
private init() {
init(storage: UserDefaults = .standard) {
self.storage = storage
load()
}
@@ -64,7 +67,7 @@ final class GeohashBookmarksStore: ObservableObject {
// MARK: - Persistence
private func load() {
guard let data = UserDefaults.standard.data(forKey: storeKey) else { return }
guard let data = storage.data(forKey: storeKey) else { return }
if let arr = try? JSONDecoder().decode([String].self, from: data) {
// Sanitize, normalize, dedupe while preserving order (first occurrence wins)
var seen = Set<String>()
@@ -81,7 +84,7 @@ final class GeohashBookmarksStore: ObservableObject {
membership = seen
}
// Load any saved names
if let namesData = UserDefaults.standard.data(forKey: namesStoreKey),
if let namesData = storage.data(forKey: namesStoreKey),
let dict = try? JSONDecoder().decode([String: String].self, from: namesData) {
bookmarkNames = dict
}
@@ -89,13 +92,13 @@ final class GeohashBookmarksStore: ObservableObject {
private func persist() {
if let data = try? JSONEncoder().encode(bookmarks) {
UserDefaults.standard.set(data, forKey: storeKey)
storage.set(data, forKey: storeKey)
}
}
private func persistNames() {
if let data = try? JSONEncoder().encode(bookmarkNames) {
UserDefaults.standard.set(data, forKey: namesStoreKey)
storage.set(data, forKey: namesStoreKey)
}
}
+10 -9
View File
@@ -3,23 +3,25 @@ import XCTest
final class GeohashBookmarksStoreTests: XCTestCase {
let storeKey = "locationChannel.bookmarks"
var storage: UserDefaults!
var store: GeohashBookmarksStore!
override func setUp() {
super.setUp()
// Clear persisted state before each test
UserDefaults.standard.removeObject(forKey: storeKey)
GeohashBookmarksStore.shared._resetForTesting()
// Unique instance for each test to avoid race condition
storage = UserDefaults(suiteName: UUID().uuidString)
store = GeohashBookmarksStore(storage: storage!)
}
override func tearDown() {
// Clean after each test
UserDefaults.standard.removeObject(forKey: storeKey)
GeohashBookmarksStore.shared._resetForTesting()
storage.removeObject(forKey: storeKey)
store._resetForTesting()
store = nil
storage = nil
super.tearDown()
}
func testToggleAndNormalize() {
let store = GeohashBookmarksStore.shared
// Start clean
XCTAssertTrue(store.bookmarks.isEmpty)
@@ -35,12 +37,11 @@ final class GeohashBookmarksStoreTests: XCTestCase {
}
func testPersistenceWritten() throws {
let store = GeohashBookmarksStore.shared
store.toggle("ezs42")
store.toggle("u4pruy")
// Verify persisted JSON contains both (order not enforced here)
guard let data = UserDefaults.standard.data(forKey: storeKey) else {
guard let data = storage.data(forKey: storeKey) else {
XCTFail("No persisted data found")
return
}