@testable import PureXML import Testing @Suite("Schematron") struct SchematronTests { private let schema = """ a book must have a title a book must have an isbn more than two authors """ private func validate(_ xml: String) throws -> [PureXML.Validation.ValidationError] { try PureXML.Validation.Schematron(schema: schema).validate(xml) } @Test("A conforming document produces no issues") func test_valid() throws { let xml = "TA" #expect(try validate(xml).isEmpty) } @Test("A failed assert is reported as an error located at its context node") func test_failedAssert() throws { let xml = "A" let issues = try validate(xml) #expect(issues.count == 1) #expect(issues.first?.severity == .error) #expect(issues.first?.reason == "a book must have a title") #expect(String(describing: issues[0]) == "a book must have a title at path: library/book") } @Test("Multiple failed asserts each report") func test_multipleAsserts() throws { let xml = "A" let messages = try validate(xml).map(\.reason) #expect(messages.contains("a book must have a title")) #expect(messages.contains("a book must have an isbn")) } @Test("A matched report is a warning") func test_report() throws { let xml = "T" + "ABC" let issues = try validate(xml) #expect(issues.count == 1) #expect(issues.first?.severity == .warning) #expect(issues.first?.reason == "more than two authors") } @Test("Rules fire once per matching node across the document") func test_perNode() throws { let xml = "" + "T" + "A" + "" // The second book is missing both title and isbn. let issues = try validate(xml) #expect(issues.count == 2) #expect(issues.allSatisfy { $0.severity == .error }) } @Test("An invalid test expression is rejected at compile time") func test_invalidSchema() { let bad = """ x """ #expect(throws: Error.self) { _ = try PureXML.Validation.Schematron(schema: bad) } } }