import Testing @testable import PureXML enum ValidationRuleTestSupport { typealias DTDSchema = PureXML.Validation.DTDSchema typealias XSDContext = PureXML.Validation.XSDContext /// `xmlns:xsi` namespace declaration, spliced into instance fixtures that need /// `xsi:nil`/`xsi:type`. static let xsiNS = "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"" /// Compiles `schema`, parses `instance`, and runs `rule` alone (isolated via /// `.blank.validating(rule)`) against the root element declared `rootName`. /// Shared by every `ValidationRuleXSD*Tests` suite. static func xsdErrors( _ rule: PureXML.Validation.Validation, schema: String, instance: String, rootName: String, ) throws -> [PureXML.Validation.ValidationError] { let compiled = try PureXML.Schema.XSDParser.parse(schema) let node = try PureXML.parse(instance) guard case let .document(children) = node, let root = children.compactMap(\.element).first else { Issue.record("no root element") return [] } let context = XSDContext( types: compiled.types, constraints: compiled.constraints, rootDeclaration: compiled.elements[rootName], nillableElements: compiled.nillableElements, elementConstraints: compiled.elementConstraints, abstractTypes: compiled.nsAbstractTypes, typeBlock: compiled.nsTypeBlock, elementBlock: compiled.nsElementBlock, typeDerivation: compiled.nsTypeDerivation, unionMembers: compiled.nsUnionMembers, globalAttributes: compiled.globalAttributes, identityFieldTypes: compiled.identityFieldTypes, identityFieldConstraints: compiled.identityFieldConstraints, identityNonSimpleFields: compiled.identityNonSimpleFields, ) return PureXML.Validation.Validator.blank .validating(rule) .errors(for: .element(root), in: context) } static func dtd(_ xml: String, resolver: PureXML.Parsing.EntityResolver = .refusing) throws -> (PureXML.Model.Node, DTDSchema) { let parsed = try PureXML.Parsing.Parser().parseWithDocumentType(xml, limits: .init(allowDoctype: true), resolver: resolver) let standalone = parsed.declaration?.standalone == true return (parsed.node, DTDSchema(parsed.documentType, standalone: standalone)) } static let standaloneExternalDTD = """ """ static func standaloneResolver() -> PureXML.Parsing.EntityResolver { let dtd = standaloneExternalDTD return PureXML.Parsing.EntityResolver( resolveEntity: { _, _ in nil }, resolveExternalSubset: { _ in dtd }, ) } static func path(_ error: PureXML.Validation.ValidationError) -> [String] { error.codingPath.map(\.stringValue) } }