A node property always attaches to a node, and an empty node is allowed, so an anchor or tag with nothing after it (a bare '&anchor', a 'key: &a', or a '!!str'/'!!null' with no value) denotes that property applied to a null node. parseNode rejected it as a missing node. parseNode now emits a null scalar carrying the properties when a node position holds only an anchor or tag, via a small helper to stay within the complexity limit; with no properties, a missing node is still an error. A '!!str' empty node resolves to the empty string and '!!null' to null. The error-path test that asserted a dangling property throws is corrected, as the construct is valid per the grammar and the official test-suite. Measured against the official YAML test-suite, parse-level conformance rises from 287/333 (86.2%) to 288/333 (86.5%), with value-level up one and no regression.
43 lines
1.8 KiB
Swift
43 lines
1.8 KiB
Swift
@testable import PureYAML
|
|
import Testing
|
|
|
|
@Suite("Parsing Error Paths")
|
|
struct ParsingErrorPathTests {
|
|
@Test("A node property with no following node is an empty (null) node")
|
|
func test_danglingNodePropertyIsEmptyNode() throws {
|
|
// A property always attaches to a node, and an empty node is allowed, so a dangling anchor
|
|
// or tag denotes a null node carrying that property rather than being an error.
|
|
#expect(try PureYAML.parse("&anchor\n") == .null)
|
|
#expect(try PureYAML.parse("root:\n key: &a\nother: 1\n") == .mapping(.init([
|
|
.init(key: "root", value: .mapping(.init([.init(key: "key", value: .null)]))),
|
|
.init(key: "other", value: .int(1)),
|
|
])))
|
|
}
|
|
|
|
@Test("An unterminated flow mapping throws at stream end")
|
|
func test_unterminatedFlowMappingThrows() {
|
|
expectParseError("x: {a: b", .unexpectedToken(
|
|
expected: "flow entry or flow mapping end",
|
|
actual: "streamEnd",
|
|
line: 1,
|
|
column: 9,
|
|
))
|
|
}
|
|
|
|
@Test("Block scalar content less indented than the explicit indicator throws")
|
|
func test_explicitBlockScalarIndentationUnderIndentThrows() {
|
|
expectParseError("k: |2\n a\n", .unexpectedIndentation(line: 2))
|
|
}
|
|
|
|
@Test("Diagnostic validation reports an invalid merge value via the buffered composer")
|
|
func test_diagnosticValidationRejectsInvalidMergeValue() {
|
|
let report = PureYAML.diagnosticValidationReport("a: &x 1\nb:\n <<: *x\n", file: "merge.yaml")
|
|
#expect(!report.isValid)
|
|
#expect(report.diagnostics.count == 1)
|
|
let diagnostic = report.diagnostics.first
|
|
#expect(diagnostic?.kind == .parse)
|
|
#expect(diagnostic?.code == "invalidMergeValue")
|
|
#expect(diagnostic?.line == 3)
|
|
}
|
|
}
|