import Testing @testable import PureXML /// DTD content-model conformance, driven through the validation framework (its /// own suite to keep the main corpus under the cap). @Suite("Conformance corpus: DTD content models") struct ConformanceDTDTests { private struct DTDSpec { let name: String let model: String let xml: String let valid: Bool } /// Sequences, choices, occurrence indicators, mixed, EMPTY, and ANY content /// models, validated against the verdict the XML 1.0 DTD rules prescribe. private func corpus() throws -> [PureXML.Validation.ConformanceCase] { let specs = [ DTDSpec(name: "sequence-ok", model: "(b,c)", xml: "", valid: true), DTDSpec(name: "sequence-wrong-order", model: "(b,c)", xml: "", valid: false), DTDSpec(name: "sequence-missing", model: "(b,c)", xml: "", valid: false), DTDSpec(name: "choice-ok", model: "(b|c)", xml: "", valid: true), DTDSpec(name: "choice-both-rejected", model: "(b|c)", xml: "", valid: false), DTDSpec(name: "star-empty", model: "(b)*", xml: "", valid: true), DTDSpec(name: "star-many", model: "(b)*", xml: "", valid: true), DTDSpec(name: "plus-requires-one", model: "(b)+", xml: "", valid: false), DTDSpec(name: "optional-too-many", model: "(b)?", xml: "", valid: false), DTDSpec(name: "pcdata-text", model: "(#PCDATA)", xml: "t", valid: true), DTDSpec(name: "pcdata-rejects-child", model: "(#PCDATA)", xml: "", valid: false), DTDSpec(name: "mixed-content", model: "(#PCDATA|b)*", xml: "tu", valid: true), DTDSpec(name: "empty-rejects-content", model: "EMPTY", xml: "x", valid: false), DTDSpec(name: "any-allows-anything", model: "ANY", xml: "x", valid: true), ] return try specs.map { spec in let dtd = "" let doc = "\(spec.xml)" let errors = try PureXML.validateAgainstInternalDTD(doc) return PureXML.Validation.ConformanceCase( name: spec.name, actual: errors.isEmpty ? "valid" : "invalid", expected: spec.valid ? "valid" : "invalid", ) } } @Test("The DTD content-model conformance corpus passes with no located failures") func test_dtdCorpusConforms() throws { let failures = try PureXML.Validation.Conformance.failures(in: corpus()) #expect(failures.isEmpty, "\(failures.map(\.reason))") } }