import Foundation @main struct ExpenseTemplateTests { static func rejects(_ action: () throws -> Void) { do { try action() preconditionFailure("Unexpected success") } catch { precondition(!error.localizedDescription.isEmpty) } } static func main() throws { let root = FileManager.default.temporaryDirectory.appendingPathComponent(UUID().uuidString) try FileManager.default.createDirectory(at: root, withIntermediateDirectories: true) defer { try? FileManager.default.removeItem(at: root) } let source = root.appendingPathComponent("原模板.xlsx") let data = Data("Synthetic template fixture".utf8) try data.write(to: source) let storage = ExpenseTemplateStorage(root: root) let initial = try storage.load() precondition(initial == nil) let mapping = ExpenseTemplateMapping(sheetName: "组 A", startRow: 5, endRow: 10, columns: ["purpose": "B", "amount": "F"], cells: ["recipient": "B12"]) let validation = ExpenseTemplateValidation(templateVersion: "mapped-xlsx-v1", fingerprint: ExpenseTemplateStorage.fingerprint(data), mapping: mapping, mappingDigest: "test-mapping-digest") let saved = try storage.save(name: source.lastPathComponent, source: source, validation: validation) let reloadedStorage = ExpenseTemplateStorage(root: root) let reloaded = try reloadedStorage.load()! precondition(reloaded.mapping == mapping) precondition(reloaded.name == "原模板.xlsx") let reloadedData = try Data(contentsOf: reloadedStorage.file(for: reloaded)) precondition(reloadedData == data) let workspace = root.appendingPathComponent("workspace.json") try Data("current expense data".utf8).write(to: workspace) try Data("{}".utf8).write(to: workspace, options: .atomic) let afterWorkspaceClear = try reloadedStorage.load() precondition(afterWorkspaceClear?.fingerprint == saved.fingerprint) let next = try storage.save(name: "新模板.xlsx", source: source, validation: validation) precondition(!FileManager.default.fileExists(atPath: storage.directory.appendingPathComponent(saved.fileName).path)) precondition(next.fileName != saved.fileName) var bad = validation bad.fingerprint = "wrong" rejects { _ = try storage.save(name: "invalid", source: source, validation: bad) } let afterFailedSave = try storage.load() precondition(afterFailedSave?.fileName == next.fileName) var traversal = next traversal.fileName = "../原模板.xlsx" rejects { _ = try storage.file(for: traversal) } let result = try JSONSerialization.data(withJSONObject: [ "templateVersion": "mapped-xlsx-v1", "templateFingerprint": saved.fingerprint, "templateMappingDigest": saved.mappingDigest ]) try ExpenseTemplateStorage.validateExport(result, template: saved) rejects { try ExpenseTemplateStorage.validateExport(Data("{}".utf8), template: saved) } var differentMapping = saved differentMapping.mappingDigest = "different" rejects { try ExpenseTemplateStorage.validateExport(result, template: differentMapping) } let storedFile = try storage.file(for: next) try Data("changed".utf8).write(to: storedFile) rejects { _ = try storage.file(for: next) } try storage.remove() let afterRemoval = try storage.load() precondition(afterRemoval == nil) precondition(!FileManager.default.fileExists(atPath: storage.directory.path)) let originalData = try Data(contentsOf: source) precondition(originalData == data) precondition(FileManager.default.fileExists(atPath: workspace.path)) try storage.remove() print("Template persistence, replacement, reset isolation and export fingerprint tests passed") } }