import Testing @testable import PureXML /// Schematron conformance, driven through the validation framework (kept in its /// own suite so the main corpus stays under the type-body cap). @Suite("Conformance corpus: Schematron") struct ConformanceSchematronTests { private struct SchematronSpec { let name: String let rule: String let xml: String let valid: Bool } /// An `assert` fires when its test is false, a `report` when its test is true, /// and a rule whose context matches nothing is inert. private func schematronCorpus() throws -> [PureXML.Validation.ConformanceCase] { let assertRule = "missing b" let ageRule = "too high" let reportRule = "flagged" let specs = [ SchematronSpec(name: "assert-satisfied", rule: assertRule, xml: "", valid: true), SchematronSpec(name: "assert-violated", rule: assertRule, xml: "", valid: false), SchematronSpec(name: "context-no-match-inert", rule: "never", xml: "", valid: true), SchematronSpec(name: "number-comparison-ok", rule: ageRule, xml: "50", valid: true), SchematronSpec(name: "number-comparison-fail", rule: ageRule, xml: "150", valid: false), SchematronSpec(name: "report-not-fired", rule: reportRule, xml: "", valid: true), SchematronSpec(name: "report-fired", rule: reportRule, xml: "", valid: false), ] return try specs.map { spec in let schema = "\(spec.rule)" let errors = try PureXML.Validation.Schematron(schema: schema).validate(spec.xml) return PureXML.Validation.ConformanceCase( name: spec.name, actual: errors.isEmpty ? "valid" : "invalid", expected: spec.valid ? "valid" : "invalid", ) } } @Test("The Schematron conformance corpus passes with no located failures") func test_schematronCorpusConforms() throws { let failures = try PureXML.Validation.Conformance.failures(in: schematronCorpus()) #expect(failures.isEmpty, "\(failures.map(\.reason))") } }