PureYAML/Tests/BlockScalarLeadingBlankTabTests.swift
Mihaela M 3b504a9c3a fix(parsing): keep a tab on a leading blank of a block scalar
A blank line within a block scalar keeps any whitespace past the content
indentation as content, but the leading blank lines, those before the first
content line, were only counted and emitted as empty. So an otherwise-blank
`tab` line under a one-space content indent lost its tab, and a folded scalar
beginning with such a line dropped the leading tab.

Record each leading blank line's whitespace verbatim instead of a count, and
once the content indentation is established emit the surplus past it, the same
way an interior blank line does. A leading blank with no surplus still emits an
empty line, and an empty block scalar (no content indentation) still emits
empty lines for its blanks.

Raises yaml-test-suite value-level conformance to 196/197 (99.5%) with the
parse-level and should-error rejection rates unchanged. 482 tests pass.
2026-06-29 01:52:58 +02:00

26 lines
1.2 KiB
Swift

@testable import PureYAML
import Testing
/// A leading blank line of a block scalar (one before the first content line) carries any whitespace
/// past the content indentation as content, the same as a blank line within the scalar. A `␣\t` line
/// under a one-space content indent keeps the tab, so a folded scalar begins with that tab. A leading
/// blank with no surplus is still just a line break.
@Suite("Block scalar leading blank tab")
struct BlockScalarLeadingBlankTabTests {
@Test("A leading blank line keeps a tab past the content indent as content")
func test_leadingBlankTab() throws {
#expect(try PureYAML.parse(">\n \t\n detected\n") == .string("\t\ndetected\n"))
#expect(try PureYAML.parse("|\n \t\n detected\n") == .string("\t\ndetected\n"))
}
@Test("A leading blank line with no surplus is just a line break")
func test_leadingBlankNoSurplus() throws {
#expect(try PureYAML.parse("x: |\n\n content\n") == .mapping(.init([
.init(key: "x", value: .string("\ncontent\n")),
])))
#expect(try PureYAML.parse("x: |\n \n content\n") == .mapping(.init([
.init(key: "x", value: .string("\ncontent\n")),
])))
}
}