PureYAML/Tests/BlockScalarTabContentTests.swift
Mihaela M 4b0dc9375e fix(parsing): keep tabs in block scalar content verbatim
A block scalar is indented with spaces only, so a tab past the content
indentation is literal content. The indentation scan measured the leading
whitespace as a tab-expanded width and rebuilt the surplus beyond the
indentation as spaces, so a line like `␣\ttext` under a one-space indent came
out `   text` rather than `\ttext`: the tab became three spaces.

Record the literal leading-whitespace characters during the indentation scan
and reconstruct the surplus from them, walking columns the way the width scan
does and keeping the remainder verbatim. A tab stays a tab; surplus spaces
stay spaces; the blank-line surplus path uses the same reconstruction.

Raises yaml-test-suite value-level conformance to 180/194 (92.8%) with the
parse-level and should-error rejection rates unchanged. 438 tests pass.
2026-06-28 20:53:40 +02:00

24 lines
1.0 KiB
Swift

@testable import PureYAML
import Testing
/// A block scalar's indentation is measured in spaces only; a tab past that indentation is literal
/// content, kept verbatim rather than re-expanded to spaces. The surplus whitespace beyond the
/// content indentation is reconstructed from the actual leading characters, so a tab stays a tab.
@Suite("Block scalar tab content")
struct BlockScalarTabContentTests {
@Test("A tab after the content indentation is kept literally")
func test_tabAfterIndent() throws {
#expect(try PureYAML.parse("|\n literal\n \ttext\n") == .string("literal\n\ttext\n"))
}
@Test("A deeper space indentation still keeps the content tab")
func test_tabAfterDeeperIndent() throws {
#expect(try PureYAML.parse("|\n literal\n \ttext\n") == .string("literal\n\ttext\n"))
}
@Test("Surplus spaces beyond the indentation are still preserved as spaces")
func test_spaceSurplusUnchanged() throws {
#expect(try PureYAML.parse("|\n text\n more\n") == .string("text\n more\n"))
}
}