Stage 2 of the faithful libyaml scanner port. Translates yaml_parser_save_simple_key, yaml_parser_remove_simple_key, yaml_parser_stale_simple_keys, and the flow-level push/pop (yaml_parser_increase_flow_level / decrease) onto a new PureYAML.Parsing.LibYAML.Scanner aggregate that embeds the indent engine. The simple-key mechanism is what lets a quoted scalar, a nested collection, or a property-carrying node become a mapping key when a ':' follows, and is required exactly at the block indent. Modelled faithfully: a potential key goes stale once it spans a line break or exceeds 1024 characters, and a required key that is removed or goes stale is the 'could not find expected colon' error. Unit-tested for the required/not-required, removal-error, staleness, and flow-level cases. No public behavior changed yet.
67 lines
2.9 KiB
Swift
67 lines
2.9 KiB
Swift
@testable import PureYAML
|
|
import Testing
|
|
|
|
/// Verifies the ported simple-key mechanism (`save_simple_key`,
|
|
/// `remove_simple_key`, `stale_simple_keys`, flow-level push/pop) reproduces
|
|
/// libyaml's behavior.
|
|
@Suite("LibYAML Simple Key")
|
|
struct LibYAMLSimpleKeyTests {
|
|
private func mark(line: Int, column: Int, index: Int) -> PureYAML.Parsing.Mark {
|
|
PureYAML.Parsing.Mark(line: line, column: column, index: index)
|
|
}
|
|
|
|
@Test("saves a possible key, required when it sits at the block indent")
|
|
func test_saveSimpleKeyRequiredAtIndent() throws {
|
|
var scanner = PureYAML.Parsing.LibYAML.Scanner()
|
|
scanner.indentEngine.rollIndent(column: 0, number: -1, type: .blockMappingStart, mark: .start)
|
|
scanner.mark = mark(line: 1, column: 0, index: 0)
|
|
try scanner.saveSimpleKey()
|
|
#expect(scanner.simpleKeys.last?.possible == true)
|
|
#expect(scanner.simpleKeys.last?.required == true)
|
|
}
|
|
|
|
@Test("a key not at the block indent is possible but not required")
|
|
func test_saveSimpleKeyNotRequired() throws {
|
|
var scanner = PureYAML.Parsing.LibYAML.Scanner()
|
|
scanner.indentEngine.rollIndent(column: 0, number: -1, type: .blockMappingStart, mark: .start)
|
|
scanner.mark = mark(line: 1, column: 4, index: 4)
|
|
try scanner.saveSimpleKey()
|
|
#expect(scanner.simpleKeys.last?.possible == true)
|
|
#expect(scanner.simpleKeys.last?.required == false)
|
|
}
|
|
|
|
@Test("removing a required possible key is an error")
|
|
func test_removeRequiredKeyThrows() throws {
|
|
var scanner = PureYAML.Parsing.LibYAML.Scanner()
|
|
scanner.indentEngine.rollIndent(column: 0, number: -1, type: .blockMappingStart, mark: .start)
|
|
scanner.mark = mark(line: 1, column: 0, index: 0)
|
|
try scanner.saveSimpleKey()
|
|
#expect(throws: PureYAML.Parsing.LibYAML.ScannerError.self) {
|
|
try scanner.removeSimpleKey()
|
|
}
|
|
}
|
|
|
|
@Test("a non-required key on an earlier line goes stale without error")
|
|
func test_staleNonRequiredKey() throws {
|
|
var scanner = PureYAML.Parsing.LibYAML.Scanner()
|
|
scanner.indentEngine.rollIndent(column: 0, number: -1, type: .blockMappingStart, mark: .start)
|
|
scanner.mark = mark(line: 1, column: 4, index: 4)
|
|
try scanner.saveSimpleKey()
|
|
scanner.mark = mark(line: 2, column: 0, index: 10)
|
|
try scanner.staleSimpleKeys()
|
|
#expect(scanner.simpleKeys.last?.possible == false)
|
|
}
|
|
|
|
@Test("flow level pushes and pops a simple-key slot")
|
|
func test_flowLevelStack() {
|
|
var scanner = PureYAML.Parsing.LibYAML.Scanner()
|
|
#expect(scanner.simpleKeys.count == 1)
|
|
scanner.increaseFlowLevel()
|
|
#expect(scanner.flowLevel == 1)
|
|
#expect(scanner.simpleKeys.count == 2)
|
|
scanner.decreaseFlowLevel()
|
|
#expect(scanner.flowLevel == 0)
|
|
#expect(scanner.simpleKeys.count == 1)
|
|
}
|
|
}
|