import Foundation final class MemoryPayeeStorage: PayeeStorage { var data: Data? var failRead = false var failWrite = false var failDelete = false func read() throws -> Data? { if failRead { throw PayeeFailure(message: "Read failed") } return data } func write(_ value: Data) throws { if failWrite { throw PayeeFailure(message: "Write failed") } data = value } func delete() throws { if failDelete { throw PayeeFailure(message: "Delete failed") } data = nil } } @main struct PayeeProfileTests { @MainActor static func main() throws { let storage = MemoryPayeeStorage() let store = PayeeProfileStore(storage: storage) precondition(store.profile == nil && store.loadError == nil) let empty = try store.exportFields() precondition(empty.isEmpty) precondition((try? PayeeProfile().validated()) == nil) let draft = PayeeProfile(recipient: " 测试收款人 ", bankName: " 测试银行支行 ", accountNumber: " 0012 3456 7890 ", preparer: "") try store.save(draft) precondition(store.profile?.accountNumber == "001234567890") precondition(store.profile?.recipient == "测试收款人") precondition(store.profile?.exportFields["preparer"] == "测试收款人") let restored = PayeeProfileStore(storage: storage) precondition(restored.profile == store.profile) var changed = draft changed.preparer = "测试制单人" try store.save(changed) precondition(store.profile?.exportFields["preparer"] == "测试制单人") let saved = store.profile let savedData = storage.data storage.failWrite = true do { try store.save(draft) preconditionFailure("Failed storage must not report success") } catch {} precondition(store.profile == saved && storage.data == savedData) storage.failWrite = false storage.failDelete = true do { try store.clear() preconditionFailure("Failed delete must retain profile") } catch {} precondition(store.profile == saved) storage.failDelete = false try store.clear() precondition(storage.data == nil && store.profile == nil) try store.save(draft) storage.failRead = true store.reload() precondition(store.profile == nil && store.loadError != nil) precondition((try? store.exportFields()) == nil) precondition((try? store.save(draft)) == nil) storage.failRead = false store.reload() precondition(store.profile != nil && store.loadError == nil) storage.data = Data("corrupt".utf8) store.reload() precondition(store.loadError != nil && store.profile == nil) var invalid = draft invalid.bankName = String(repeating: "行", count: 201) precondition((try? invalid.validated()) == nil) invalid = draft invalid.recipient = "测试\n收款人" precondition((try? invalid.validated()) == nil) print("Payee profile validation, persistence, update, delete and failure tests passed") } }