PureYAML/Tests/SequencePropertyIndentTests.swift
Mihaela M 5528ce9aa4 fix(parsing): bind an indented property to a zero-indent sequence
A node property written on its own indented line can sit above a block sequence
whose entries return to the mapping key's own indentation (`seq:` then
` &anchor` then `- a` at the key's column). The grammar allows a block-in-block
sequence at its parent's indent n while the property sits at n+1, so the
indent's matching dedent falls between the property and the entries.

The parser consumed the property as an empty anchored value and then rejected
the entries as an unexpected block entry. It now recognises the property-then-
dedent-then-entry shape, consumes that dedent, and binds the property to the
block sequence that follows.

Fixes yaml-test-suite SKE5; raises parse-level conformance to 311/333 (93.4%)
and value-level to 204/204 (100.0%), with the should-error rate unchanged.
2026-06-29 03:44:53 +02:00

34 lines
1.8 KiB
Swift

@testable import PureYAML
import Testing
@Suite("A node property may sit indented above a zero-indent block sequence")
struct SequencePropertyIndentTests {
/// yaml-test-suite SKE5: a block sequence may sit at its parent mapping key's indentation while a
/// property written above it is more indented (`seq:` / ` &anchor` / `- a`). The property binds to
/// the sequence, not to an empty anchored value, so the entries are not orphaned.
@Test("An anchor indented above a zero-indent block sequence binds to the sequence")
func test_anchorAboveZeroIndentSequence() throws {
let mapping = try requireMapping(PureYAML.parse("---\nseq:\n &anchor\n- a\n- b\n"))
#expect(mapping?["seq"] == .sequence([.string("a"), .string("b")]))
}
/// The plain zero-indent block sequence (no property) keeps working: a sequence whose entries are
/// at the mapping key's own column is the value of that key.
@Test("A zero-indent block sequence without a property is unaffected")
func test_zeroIndentSequenceWithoutProperty() throws {
let mapping = try requireMapping(PureYAML.parse("seq:\n- a\n- b\n"))
#expect(mapping?["seq"] == .sequence([.string("a"), .string("b")]))
}
/// A property on its own indented line above an indented nested mapping still binds to that
/// mapping, so an alias resolves to the whole mapping rather than the sequence path above.
@Test("An anchor above an indented nested mapping still binds to the mapping")
func test_anchorAboveNestedMapping() throws {
let mapping = try requireMapping(PureYAML.parse("key:\n &a\n nested: v\nx: *a\n"))
let key = try requireMapping(#require(mapping?["key"]))
let alias = try requireMapping(#require(mapping?["x"]))
#expect(key?["nested"] == .string("v"))
#expect(alias?["nested"] == .string("v"))
}
}