The ported engine wins every conflict: main's post-fork patches to the hand-rolled Scanner and TokenEventParser land on deleted files and are dropped; their behaviors are carried by the port and guarded by the whole-suite conformance gate (402/402 passing). Merge adaptations, all gates green (style, namespacing, forbidden patterns, changelog, roadmap, swiftformat, swiftlint strict, build, full test suite, whole-suite conformance sweep): - PureYAMLJSON representability rules move onto the Check algebra, replacing the retired legacy Rule type. - The permissive tag-handle pre-pass is removed; the port rejects an undefined handle at parse time (suite case QLJ7) and the validation report carries it as a parse diagnostic. - EventStreamComposer's nested types split one-per-file per the namespacing gate. - Tests pinned to old-engine behavior were re-verified against the reference and updated: libyaml rejects an explicit-key continuation ending at a value colon, and suite case QB6E requires rejecting a quoted continuation at column 0. - CHANGELOG unreleased entries from both lines are preserved in two groups with a provenance note. Closes #1, closes #3
46 lines
1.9 KiB
Swift
46 lines
1.9 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", .malformed(
|
|
reason: "while parsing a flow mapping, did not find expected ',' or '}'",
|
|
line: 1,
|
|
column: 4,
|
|
))
|
|
}
|
|
|
|
@Test("Block scalar content less indented than the explicit indicator throws")
|
|
func test_explicitBlockScalarIndentationUnderIndentThrows() {
|
|
expectParseError("k: |2\n a\n", .malformed(
|
|
reason: "while parsing a block mapping, did not find expected key",
|
|
line: 1,
|
|
column: 1,
|
|
))
|
|
}
|
|
|
|
@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)
|
|
}
|
|
}
|