import Testing @testable import PureXML @Suite("Push parser") struct PushParserTests { /// Feeds the chunks through a push parser and returns a flat list of event /// descriptions. private func collect(_ chunks: [String]) throws -> [String] { var events: [String] = [] let handler = PureXML.Parsing.SAXHandler( startElement: { name, attributes in let attrs = attributes.map { " \($0.name.description)=\($0.value)" }.joined() events.append("start:\(name.description)\(attrs)") }, endElement: { events.append("end:\($0.description)") }, characters: { events.append("text:\($0)") }, cdata: { events.append("cdata:\($0)") }, comment: { events.append("comment:\($0)") }, processingInstruction: { events.append("pi:\($0):\($1)") }, ) var parser = PureXML.Parsing.PushParser(sax: handler) for chunk in chunks { try parser.feed(chunk) } try parser.finish() return events } private let document = "" + "hi & byetail" @Test("A whole document produces the expected events") func test_whole() throws { #expect(try collect([document]) == [ "start:root a=1 xmlns:n=urn:x", "start:n:b", "text:hi & bye", "end:n:b", "comment: c ", "cdata:x", "", "", "", "a < b", ] for fragment in cases { let whole = try collect([fragment]) let mid = fragment.index(fragment.startIndex, offsetBy: fragment.count / 2) let parts = [String(fragment[..", "a", "b", ""] let stream = AsyncStream { continuation in for chunk in chunks { continuation.yield(chunk) } continuation.finish() } var names: [String] = [] for try await event in PureXML.events(feeding: stream) { if case let .startElement(name, _) = event { names.append(name.description) } } #expect(names == ["doc", "item", "item"]) } }