LocalData/Tests/LocalDataTests/ModularRegistryTests.swift
Matt Bruce 0afaf34c78 Tests AnyStorageKeyTests.swift, AuditTests.swift, LocalDataTests.swift (+13 more)
Summary:
- Tests: AnyStorageKeyTests.swift, AuditTests.swift, LocalDataTests.swift, MigrationAdditionalTests.swift, MigrationIntegrationTests.swift (+11 more)
- Added symbols: func makeStringKey, func makeUserDefaultsKey, func makeFileKey, func makeLegacyStringKey, func makeModernStringKey, func makePhoneOnlyKey (+14 more)
- Removed symbols: struct StringKey, typealias Value, struct TestKey, struct TestUserDefaultsKey, struct TestFileKey, struct LegacyStringKey (+19 more)

Stats:
- 16 files changed, 329 insertions(+), 386 deletions(-)
2026-01-18 14:53:30 -06:00

97 lines
3.2 KiB
Swift

import Foundation
import Testing
@testable import LocalData
private func makeRegistryKey(
name: String,
owner: String = "Test",
description: String = "Test"
) -> StorageKey<String> {
StorageKey(
name: name,
domain: .userDefaults(suite: nil),
security: .none,
owner: owner,
description: description
)
}
private struct CatalogA: StorageKeyCatalog {
var allKeys: [AnyStorageKey] {
[.key(makeRegistryKey(name: "key.a", owner: "ModuleA"))]
}
}
private struct CatalogB: StorageKeyCatalog {
var allKeys: [AnyStorageKey] {
[.key(makeRegistryKey(name: "key.b", owner: "ModuleB"))]
}
}
private struct CatalogCollision: StorageKeyCatalog {
var allKeys: [AnyStorageKey] {
[.key(makeRegistryKey(name: "key.a", owner: "ModuleCollision"))]
}
}
@Suite(.serialized)
struct ModularRegistryTests {
@Test func testAdditiveRegistration() async throws {
let router = StorageRouter(keychain: MockKeychainHelper())
try await router.registerCatalog(CatalogA())
#expect(await router.allRegisteredEntries().count == 1)
#expect(await router.allRegisteredEntries().contains { $0.descriptor.name == "key.a" })
try await router.registerCatalog(CatalogB())
#expect(await router.allRegisteredEntries().count == 2)
#expect(await router.allRegisteredEntries().contains { $0.descriptor.name == "key.b" })
}
@Test func testCollisionDetectionAcrossCatalogs() async throws {
let router = StorageRouter(keychain: MockKeychainHelper())
try await router.registerCatalog(CatalogA())
await #expect(throws: StorageError.self) {
try await router.registerCatalog(CatalogCollision())
}
}
@Test func testGlobalAuditReport() async throws {
let router = StorageRouter(keychain: MockKeychainHelper())
try await router.registerCatalog(CatalogA())
try await router.registerCatalog(CatalogB())
// Note: StorageAuditReport.renderGlobalRegistry() uses the shared router.
// For testing isolation, we should probably add a parameter to it or
// rely on the shared instance if we can reset it.
// Since StorageRouter is a singleton-heavy actor, we use renderText directly on the router's entries.
let entries = await router.allRegisteredEntries()
let report = StorageAuditReport.renderText(entries)
#expect(report.contains("key.a"))
#expect(report.contains("key.b"))
#expect(report.contains("catalog=CatalogA"))
#expect(report.contains("catalog=CatalogB"))
#expect(report.contains("ModuleA"))
#expect(report.contains("ModuleB"))
}
@Test func testGlobalAuditReportGrouped() async throws {
let router = StorageRouter(keychain: MockKeychainHelper())
try await router.registerCatalog(CatalogA())
try await router.registerCatalog(CatalogB())
let catalogs = await router.allRegisteredCatalogs()
#expect(catalogs.count == 2)
#expect(catalogs["CatalogA"] != nil)
#expect(catalogs["CatalogB"] != nil)
}
}