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 "- one
- two
" }
#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 "- one
- two
" }
#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 "- one
- two
" }
#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 == "")
}
}