PureYAML/Tests/BlockScalarPercentContentTests.swift
Mihaela M 942a7ff2bc fix(parsing): keep a leading percent in a block scalar literal
A zero-indent literal or folded block scalar sits at column 0, where the
directive scan runs, so a content line beginning with `%` (`%!PS-Adobe-2.0`)
was misread as a directive and rejected as unsupported.

The directive scan now runs only outside a block scalar, so a leading `%` in
block scalar content is literal text. A real `%YAML` or `%TAG` directive still
parses, and a stray `%` in other content is still rejected rather than silently
accepted, so the should-error behaviour is unchanged.

This is groundwork for yaml-test-suite W4TN, which additionally needs a block
scalar to be terminated by `...` and per-document directives across a multi-
document stream, so conformance counts are unchanged this step.
2026-06-29 05:04:32 +02:00

31 lines
1.5 KiB
Swift

@testable import PureYAML
import Testing
@Suite("A percent inside a block scalar is literal content, not a directive")
struct BlockScalarPercentContentTests {
/// A zero-indent block scalar sits at column 0, where the directive scan runs, so a content line
/// beginning with `%` was misread as a directive and rejected. Inside a block scalar a leading
/// `%` is literal text (groundwork for yaml-test-suite W4TN, which also needs block-scalar
/// termination by `...` and multi-document directives).
@Test("A root literal block scalar keeps a leading percent as content")
func test_rootBlockScalarPercentContent() throws {
#expect(try PureYAML.parse("--- |\n%foo\n") == .string("%foo\n"))
}
/// Every content line of the block scalar keeps its leading percent, not only the first.
@Test("Each block scalar line keeps its leading percent")
func test_multilineBlockScalarPercentContent() throws {
#expect(try PureYAML.parse("--- |\n%one\n%two\n") == .string("%one\n%two\n"))
}
/// The change is scoped to block scalars: a real `%YAML` directive still works, and a stray `%`
/// in other content is still rejected rather than silently accepted.
@Test("A directive still parses and a stray percent in content still errors")
func test_directiveStillWorksAndStrayPercentRejected() throws {
#expect(try PureYAML.parse("%YAML 1.2\n---\nx\n") == .string("x"))
#expect(throws: PureYAML.Parsing.ParseError.self) {
try PureYAML.parse("{ a,\n%x }\n")
}
}
}