@testable import PureYAML import Testing /// A flow mapping entry may begin with its `:` indicator, giving an empty (null) key, e.g. `{ : v }`, /// or carry only properties before the `:`, e.g. `{ !!str : v }`. Both resolve to a null key, which /// the parser now emits rather than demanding a node before the `:`. The allowance is local to flow /// mapping key position, so an entry with no `:` at all (`{ a, }`) is still an error. @Suite("Flow mapping empty key") struct FlowMappingEmptyKeyTests { @Test("A flow mapping entry that begins with a colon has an empty key") func test_emptyKey() throws { #expect(try PureYAML.parse("{ : a }\n") == .mapping(.init([ .init(keyNode: .string(""), value: .string("a")), ]))) } @Test("An empty key sits alongside ordinary entries") func test_emptyKeyAmongEntries() throws { #expect(try PureYAML.parse("{ a: b, : c }\n") == .mapping(.init([ .init(key: "a", value: .string("b")), .init(keyNode: .string(""), value: .string("c")), ]))) } @Test("Both key and value may be empty in one entry") func test_emptyKeyAndValue() throws { #expect(try PureYAML.parse("{ : }\n") == .mapping(.init([ .init(keyNode: .string(""), value: .null), ]))) } @Test("A key carrying only a tag is a null key and parses") func test_propertyOnlyKey() throws { // `{ foo : !!str, !!str : bar }`: the first value and the second key are property-only nulls. _ = try PureYAML.parse("{ foo : !!str, !!str : bar }\n") } @Test("An empty value is still accepted, unchanged") func test_emptyValueUnchanged() throws { #expect(try PureYAML.parse("{ a: }\n") == .mapping(.init([ .init(key: "a", value: .null), ]))) } @Test("A flow mapping entry with no colon is a set-style key mapping to null") func test_entryWithoutColonIsNullValue() throws { // `{ a, }` is a flow set: the entry has no `:`, so its key maps to null. The trailing comma // is allowed. #expect(try PureYAML.parse("{ a, }\n") == .mapping(.init([ .init(key: "a", value: .null), ]))) } }