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(-)
97 lines
3.2 KiB
Swift
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)
|
|
}
|
|
}
|