@testable import PureXML import Testing @Suite("HTML tokenizer: references, NUL, RCDATA") struct HTMLTokenizerTests { /// The concatenated text content of the first parsed element. private func text(_ html: String) -> String { guard case let .document(children) = PureXML.HTML.parse(html), case let .element(element) = children.first else { return "" } return element.children.compactMap { if case let .text(value) = $0 { value } else { nil } }.joined() } @Test("A numeric reference to zero, a surrogate, or an out-of-range value yields U+FFFD") func test_numericInvalid() { #expect(text("
") == "\u{FFFD}") #expect(text("") == "\u{FFFD}") #expect(text("") == "\u{FFFD}") } @Test("A numeric reference in the C1 range is mapped to its Windows-1252 character") func test_numericC1() { #expect(text("
") == "\u{20AC}") // euro #expect(text("
") == "\u{2122}") // trade mark } @Test("A valid numeric reference resolves to its code point") func test_numericValid() { #expect(text("AB
") == "AB") } @Test("A literal NUL byte becomes U+FFFD") func test_nullReplacement() { #expect(text("a\u{0}b
") == "a\u{FFFD}b") } @Test("A named reference without a trailing semicolon is still decoded") func test_semicolonless() { #expect(text("&
") == "&") #expect(text("©
") == "\u{A9}") } @Test("RCDATA content (title, textarea) decodes references; raw text (style) does not") func test_rcdataDecoding() { #expect(text("