import Testing @testable import PureXML /// Every QName a schema names (a `type`/`base`/`itemType`/`memberTypes` type, an /// element/attribute/group/attributeGroup `ref`, an element `substitutionGroup`) /// must resolve to a declared component or a built-in. An undeclared reference /// was previously accepted at compile time and only surfaced (if at all) lazily /// during instance validation. The check is skipped when the document pulls in /// external definitions through `import`/`include`/`redefine`, which the default /// compile does not load. @Suite("Schema reference resolution") struct SchemaReferenceTests { private func compile(_ body: String) throws { _ = try PureXML.Schema.Document(""" \(body) """) } private func rejects(_ body: String) -> Bool { do { try compile(body) return false } catch { return true } } @Test("a reference to a declared component or a built-in resolves") func test_resolves() throws { try compile(#""#) try compile(#""#) try compile(#""#) } @Test("an undeclared reference is rejected") func test_undeclared() { #expect(rejects(#""#)) #expect(rejects(#""#)) #expect(rejects(#""#)) #expect(rejects(#""#)) } @Test("a reference value tolerates surrounding whitespace (whiteSpace collapse)") func test_whitespacePadded() throws { try compile("") } @Test("a ref resolving to the XSD namespace is undeclared") func test_refResolvingToXSDNamespaceIsUndeclared() throws { // The default xmlns is the XSD namespace, so an unprefixed `ref="root"` // resolves to {XSD}root, not {foo}root, and the XSD namespace declares no // referenceable user element: undeclared (XSTS xsd013/xsd014). let refRoot = """ """ #expect(throws: (any Error).self) { _ = try PureXML.Schema.Document(refRoot) } let refUndef = """ """ #expect(throws: (any Error).self) { _ = try PureXML.Schema.Document(refUndef) } // Guard: the same shape with the ref qualified to the target resolves, so the // XSD-namespace rule does not reject a correctly-namespaced reference. let qualified = """ """ _ = try PureXML.Schema.Document(qualified) } @Test("an unprefixed type reference to a target-namespace type is undeclared") func test_unprefixedTypeRefToTargetNamespace() throws { // No default xmlns, so `type="t"` resolves to {}t, not {urn:x}t where the // type is declared: undeclared (XSTS addB009 / test66059). let unprefixed = """ """ #expect(throws: (any Error).self) { _ = try PureXML.Schema.Document(unprefixed) } // Guard: qualifying the reference to the target namespace resolves. let qualified = """ """ _ = try PureXML.Schema.Document(qualified) } @Test("references are not checked when an import may supply them") func test_importSkipsCheck() throws { // A dangling reference into an imported namespace is tolerated: the default // compile does not load the import, so the reference cannot be verified. try compile(#""" """#) } @Test("references are checked strictly against the targetNamespace") func test_referenceNamespaceChecking() throws { // Without targetNamespace, unprefixed ref resolves to no namespace and is accepted _ = try PureXML.Schema.Document(""" """) // With targetNamespace, unprefixed ref without default namespace resolves to no namespace but declaration is in targetNamespace -> rejected #expect(throws: Error.self) { _ = try PureXML.Schema.Document(""" """) } // With targetNamespace, prefix matching targetNamespace is accepted _ = try PureXML.Schema.Document(""" """) // With targetNamespace, default namespace matching targetNamespace is accepted _ = try PureXML.Schema.Document(""" """) } }