import Testing @testable import PureXML /// The worked examples of Canonical XML 1.0 section 3 (W3C Recommendation, /// https://www.w3.org/TR/xml-c14n, W3C Software and Document License), run as /// input/expected-output vectors (#132). Each test cites its example number. @Suite("C14N 1.0 spec examples") struct C14NSpecExampleTests { private func canonical( _ input: String, comments: Bool = false, resolver: PureXML.Parsing.EntityResolver = .refusing, ) throws -> String { var options = PureXML.Canonical.Options.inclusive options.includeComments = comments // C14N input is the validating-processor view: DTD defaults applied. let node = try PureXML.parseApplyingInternalDTDDefaults(input, resolver: resolver) return PureXML.Canonical.canonicalize(node, options: options) } @Test("3.1: PIs, comments, and content outside the document element") func test_example31() throws { let input = """ Hello, world! """ let uncommented = """ Hello, world! """ let commented = """ Hello, world! """ #expect(try canonical(input) == uncommented) #expect(try canonical(input, comments: true) == commented) } @Test("3.2: whitespace in document content is preserved") func test_example32() throws { let input = """ A B A B A B C """ // The canonical form is byte-identical for this input. #expect(try canonical(input) == input) } @Test("3.3: start and end tags, attribute sorting, superfluous namespaces") func test_example33() throws { let input = """ ]> """ let expected = """ """ #expect(try canonical(input) == expected) } @Test("3.4: character modifications and character references") func test_example34() throws { let input = """ ]> First line Second line 2 "0" && value<"10" ?"valid":"error"]]> valid """ let expected = """ First line Second line 2 value>"0" && value<"10" ?"valid":"error" valid """ #expect(try canonical(input) == expected) } @Test("3.5: entity references are expanded") func test_example35() throws { let input = """ ]> &ent1;, &ent2;! """ let expected = """ Hello, world! """ let resolver = PureXML.Parsing.EntityResolver( resolveEntity: { name, _ in name == "ent2" ? "world" : nil }, resolveExternalSubset: { _ in nil }, ) #expect(try canonical(input, resolver: resolver) == expected) } @Test("3.6: output is UTF-8 regardless of input encoding") func test_example36() throws { // The declaration names ISO-8859-1 and the byte 0xA9 is the copyright // sign there; the canonical form carries the UTF-8 character. var bytes = Array("\n".utf8) bytes.append(0xA9) bytes += Array("".utf8) let source = try PureXML.Parsing.ByteDecoder.decode(bytes) let node = try PureXML.parse(source) #expect(PureXML.Canonical.canonicalize(node) == "\u{A9}") } }