An explicit key that is only a node property (`? &e` then `: &a`) parsed to an `expectedNode` error. Unlike the implicit form (`&a : v`), the scanner emits no synthesized empty scalar for an explicit key, so the block parser read the key via parseNode, consumed the property, then hit the `:` value indicator with no node and threw. parseNode now treats a `:` in node position as an empty key carrying any properties, reusing emitEmptyNodeOrThrow (the node it already produced for a property at end of input) without consuming the `:`, so the mapping machinery reads the `:` as the value indicator. To stay within the cyclomatic-complexity limit, the scalar case is extracted to parseScalarNode. yaml-test-suite PW8X now passes (parse-level 314/333 to 315/333). should-error rejections and value-level matches are unchanged, and a value-level test pins the produced tree for the anchored and tagged property-only explicit keys.
48 lines
1.6 KiB
Swift
48 lines
1.6 KiB
Swift
@testable import PureYAML
|
|
import Testing
|
|
|
|
@Suite("Explicit keys")
|
|
struct ExplicitKeyTests {
|
|
@Test("Explicit keys with no value each map to null")
|
|
func test_explicitKeysWithoutValuesMapToNull() throws {
|
|
// Several `? key` entries in a row (a set, for instance) are valid; each maps to null.
|
|
let value = try PureYAML.parse("""
|
|
? a
|
|
? b
|
|
c:
|
|
""")
|
|
#expect(value == .mapping(.init([
|
|
.init(key: "a", value: .null),
|
|
.init(key: "b", value: .null),
|
|
.init(key: "c", value: .null),
|
|
])))
|
|
}
|
|
|
|
@Test("Explicit keys with values still parse")
|
|
func test_explicitKeysWithValues() throws {
|
|
let value = try PureYAML.parse("""
|
|
? a
|
|
: b
|
|
? c
|
|
: d
|
|
""")
|
|
#expect(value == .mapping(.init([
|
|
.init(key: "a", value: .string("b")),
|
|
.init(key: "c", value: .string("d")),
|
|
])))
|
|
}
|
|
|
|
@Test("An explicit key that is only a property is an empty key carrying it")
|
|
func test_explicitPropertyOnlyKey() throws {
|
|
// `? &e` is an anchored empty key, `: &a` an anchored empty value: an empty plain scalar
|
|
// resolves to the empty string as a key and to null as a value, the property binding to each
|
|
// during construction. The key is no longer rejected for having no scalar before its `:`.
|
|
#expect(try PureYAML.parse("? &e\n: &a\n") == .mapping(.init([
|
|
.init(keyNode: .string(""), value: .null),
|
|
])))
|
|
#expect(try PureYAML.parse("? !!str\n: !!null\n") == .mapping(.init([
|
|
.init(keyNode: .string(""), value: .null),
|
|
])))
|
|
}
|
|
}
|