import Testing @testable import PureXML @Suite("XInclude") struct XIncludeTests { // MARK: URI resolution @Test("Relative references resolve against a base per RFC 3986") func test_uriResolution() { let resolve = PureXML.XInclude.URIReference.resolve #expect(resolve("g", "http://a/b/c/d") == "http://a/b/c/g") #expect(resolve("../g", "http://a/b/c/d") == "http://a/b/g") #expect(resolve("../../g", "http://a/b/c/d") == "http://a/g") #expect(resolve("/g", "http://a/b/c/d") == "http://a/g") #expect(resolve("http://x/y", "http://a/b/c/d") == "http://x/y") #expect(resolve("./g", "http://a/b/c/d") == "http://a/b/c/g") } // MARK: Processing private func process(_ xml: String, _ load: @escaping (String) -> String?) throws -> String { let node = try PureXML.XInclude.process(xml, base: "http://example.com/doc.xml", loadingURI: load) return PureXML.serialize(node, options: .compact) } @Test("xi:include parse=xml substitutes the document element") func test_includeXML() throws { let xml = "" let result = try process(xml) { uri in uri == "http://example.com/frag.xml" ? "hi" : nil } #expect(result == "hi") } @Test("xi:include parse=text substitutes raw text") func test_includeText() throws { let xml = "" + "" let result = try process(xml) { _ in "a < b" } #expect(result == "a < b") } @Test("xi:include with an xpointer selects a fragment") func test_includeWithXPointer() throws { let xml = "" + "" let result = try process(xml) { _ in "onetwo" } #expect(result == "two") } @Test("xi:include with an xpointer range() includes the covering range") func test_includeRange() throws { let xml = "" + "" let result = try process(xml) { _ in "onetwo" } #expect(result == "two") } @Test("xi:include with a string-range xpointer includes the matched text") func test_includeStringRange() throws { let xml = "" + "" let result = try process(xml) { _ in "onetwo" } #expect(result == "wo") } @Test("href resolves against an xml:base on an ancestor") func test_xmlBase() throws { let xml = "" + "" var requested = "" let result = try process(xml) { uri in requested = uri return "" } #expect(requested == "http://example.com/sub/frag.xml") #expect(result == "") } @Test("A failed include uses its xi:fallback") func test_fallback() throws { let xml = "" + "" let result = try process(xml) { _ in nil } #expect(result == "") } @Test("A failed include with no fallback throws") func test_unresolved() { let xml = "" #expect(throws: PureXML.XInclude.XIncludeError.self) { _ = try PureXML.XInclude.process(xml, loadingURI: { _ in nil }) } } @Test("Includes nest: an included document's own includes resolve") func test_nestedInclude() throws { let xml = "" let result = try process(xml) { uri in switch uri { case "http://example.com/a.xml": "" case "http://example.com/b.xml": "" default: nil } } #expect(result == "") } }