PureYAML/Tests/DocumentEndContentTests.swift
Mihaela M fcba4e1f57 fix(parsing): reject content after a document end marker
A document-end marker takes no node on its own line: only a comment or
blank may follow. The scanner skipped the rest of the marker's line, so
content such as the 'invalid' in '... invalid' was silently dropped and
the document accepted.

scanDocumentMarker now distinguishes the two markers after skipping spaces:
a document start may carry the root node on its line and leaves it for the
main loop, while a document end rejects any real content (a comment or
blank still passes). A '...' not followed by an indicator boundary is not
a marker at all and remains an ordinary plain scalar, so '...junk' still
parses as content.

Measured against the official YAML test-suite, parse-level conformance
rises from 255/333 (76.6%) to 256/333 (76.9%) with no regression.
2026-06-27 17:56:37 +02:00

28 lines
1.1 KiB
Swift

@testable import PureYAML
import Testing
@Suite("Content after a document end marker")
struct DocumentEndContentTests {
@Test("Real content on a `...` marker's line is rejected")
func test_contentAfterDocumentEndRejected() throws {
#expect(throws: PureYAML.Parsing.ParseError.self) {
try PureYAML.parse("---\nkey: value\n... invalid\n")
}
}
@Test("A bare `...`, or one followed only by a comment, is accepted", arguments: [
"---\nx\n...\n", // nothing after the marker
"---\nx\n... # comment\n", // only a comment follows
"---\nx\n... \n", // only trailing spaces follow
])
func test_bareDocumentEndAccepted(_ yaml: String) throws {
#expect(try PureYAML.parse(yaml) == .string("x"))
}
@Test("`...` not followed by a boundary is a plain scalar, not a marker")
func test_dotsWithoutBoundaryIsScalar() throws {
// `...junk` is not a document-end marker, so it continues the plain scalar `x`.
#expect(try PureYAML.parse("---\nx\n...junk\n") == .string("x ...junk"))
}
}