import Testing @testable import PureXML /// `validate(_:schemaLoader:)` honors an instance's `xsi:schemaLocation`, /// loading the referenced schema documents so a strict (or lax) wildcard can /// resolve elements declared in another document (#147, XSTS particles set). @Suite("Multi-document validation via xsi:schemaLocation") struct SchemaMultiDocumentTests { private let mainXSD = """ """ private let otherXSD = """ """ private let instance = """ 5 """ @Test("A strict wildcard resolves an element from the xsi:schemaLocation schema") func test_resolvesAcrossDocuments() throws { let doc = try PureXML.Schema.Document(mainXSD) let loader: (String) -> String? = { [otherXSD] in $0 == "other.xsd" ? otherXSD : nil } #expect(try doc.validate(instance, schemaLoader: loader).isEmpty) } @Test("The loaded declaration's type is still enforced") func test_loadedTypeEnforced() throws { let doc = try PureXML.Schema.Document(mainXSD) let loader: (String) -> String? = { [otherXSD] in $0 == "other.xsd" ? otherXSD : nil } let bad = instance.replacingOccurrences(of: "5", with: "notint") #expect(try !doc.validate(bad, schemaLoader: loader).isEmpty) } @Test("Without the loader a strict wildcard cannot resolve the element") func test_strictUnresolvedWithoutLoader() throws { let doc = try PureXML.Schema.Document(mainXSD) #expect(try !doc.validate(instance).isEmpty) } @Test("Streaming validation honors xsi:schemaLocation the same as the tree path") func test_streamingResolvesAcrossDocuments() throws { let doc = try PureXML.Schema.Document(mainXSD) let loader: (String) -> String? = { [otherXSD] in $0 == "other.xsd" ? otherXSD : nil } let tree = try doc.validate(instance, schemaLoader: loader).map(\.reason).sorted() let streamed = try doc.validate(streaming: instance, schemaLoader: loader).map(\.reason).sorted() #expect(tree == streamed) #expect(tree.isEmpty) } @Test("Streaming strict wildcard fails without the loader") func test_streamingStrictUnresolvedWithoutLoader() throws { let doc = try PureXML.Schema.Document(mainXSD) #expect(try !doc.validate(streaming: instance).isEmpty) } }