import Testing @testable import PureXML /// A schema `blockDefault` supplies the `{disallowed substitutions}` of an element /// and the `{prohibited substitutions}` of a complex type that state no `block` of /// their own, blocking an `xsi:type` substitution by a listed derivation method /// (XSD 1.0 Structures section 3.3.2 / 3.4.2; cvc-elt.4.3.2.1). An explicit /// `block=""` overrides the default back to acceptance. @Suite("schema blockDefault on xsi:type substitution") struct SchemaBlockDefaultTests { /// A schema with the given `blockDefault` plus optional explicit `block` /// overrides on the element and its declared type. `ShapeT` is the declared /// type; `CircleT` extends it and `PointT` restricts it. private func schema(blockDefault: String, elementBlock: String? = nil, typeBlock: String? = nil) -> String { let defaultAttribute = blockDefault.isEmpty ? "" : " blockDefault=\"\(blockDefault)\"" let elementAttribute = elementBlock.map { " block=\"\($0)\"" } ?? "" let typeAttribute = typeBlock.map { " block=\"\($0)\"" } ?? "" return """ """ } private let extensionInstance = "a1" private let restrictionInstance = "a" private func validate(_ xsd: String, _ instance: String) throws -> [PureXML.Validation.ValidationError] { try PureXML.Schema.Document(xsd).validate(instance) } @Test("blockDefault=extension blocks an extension xsi:type") func test_blockDefaultBlocksExtension() throws { #expect(try !validate(schema(blockDefault: "extension"), extensionInstance).isEmpty) } @Test("blockDefault=extension still allows a restriction xsi:type") func test_blockDefaultAllowsRestriction() throws { #expect(try validate(schema(blockDefault: "extension"), restrictionInstance).isEmpty) } @Test("blockDefault=#all blocks both extension and restriction") func test_blockDefaultAllBlocksBoth() throws { #expect(try !validate(schema(blockDefault: "#all"), extensionInstance).isEmpty) #expect(try !validate(schema(blockDefault: "#all"), restrictionInstance).isEmpty) } @Test("explicit block=\"\" on the element and its type overrides blockDefault back to acceptance") func test_emptyBlockOverridesDefault() throws { // cvc-elt.4.3.2.1 unions the element's {disallowed substitutions} with the // declared type's {prohibited substitutions}, so both must be cleared. let xsd = schema(blockDefault: "#all", elementBlock: "", typeBlock: "") #expect(try validate(xsd, extensionInstance).isEmpty) #expect(try validate(xsd, restrictionInstance).isEmpty) } }