fix(parsing): accept a tab after the colon value indicator
A tab is separation white space in YAML, so it follows the `:` mapping-value
indicator exactly as a space does. isMappingValueBoundary (flow) and
isBlockMappingValueBoundary (block) accepted only a space, line break, comma,
or closing bracket, so `foo:\tbar` folded into the plain scalar `foo:\tbar`
instead of the mapping `{foo: bar}`.
Accept a tab in both. A `:` with no following white space (`foo:bar`) is still
plain scalar content, and the symmetric counterpart for a tab after a leading
indicator landed in the previous change.
Raises yaml-test-suite parse-level to 300/333 (90.1%) with the should-error
rejection rate unchanged. 433 tests pass.
This commit is contained in:
parent
37e84b5eb4
commit
738408d458
@ -84,6 +84,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
### Fixed
|
||||
|
||||
- A tab now follows the `:` mapping-value indicator the way a space does, in both block and flow
|
||||
context, since a tab is separation white space in YAML. `foo:\tbar` is the mapping `{foo: bar}`
|
||||
rather than the plain scalar `foo:\tbar`. A `:` with no following white space at all (`foo:bar`)
|
||||
stays plain scalar content. Raises yaml-test-suite parse-level conformance to 300/333 (90.1%), with
|
||||
the should-error rejection rate unchanged.
|
||||
|
||||
- A tab now ends a leading indicator the way a space does, since a tab is separation white space in
|
||||
YAML (only indentation forbids a tab). A document marker, block entry, or explicit key followed by a
|
||||
tab (`---\tscalar`, `-\titem`, `?\tkey`) is recognized as the indicator rather than folded into a
|
||||
|
||||
@ -53,7 +53,9 @@ extension PureYAML.Parsing.Scanner {
|
||||
guard let character else {
|
||||
return true
|
||||
}
|
||||
// A tab is separation white space, so it follows a `:` value indicator as a space does.
|
||||
return character == " "
|
||||
|| character == "\t"
|
||||
|| isLineBreak(character)
|
||||
|| character == ","
|
||||
|| character == "]"
|
||||
@ -64,7 +66,7 @@ extension PureYAML.Parsing.Scanner {
|
||||
guard let character else {
|
||||
return true
|
||||
}
|
||||
return character == " " || isLineBreak(character)
|
||||
return character == " " || character == "\t" || isLineBreak(character)
|
||||
}
|
||||
|
||||
func isTokenTerminator(_ character: Character) -> Bool {
|
||||
|
||||
34
Tests/MappingValueTabBoundaryTests.swift
Normal file
34
Tests/MappingValueTabBoundaryTests.swift
Normal file
@ -0,0 +1,34 @@
|
||||
@testable import PureYAML
|
||||
import Testing
|
||||
|
||||
/// A tab is separation white space in YAML, so it follows the `:` mapping-value indicator as a space
|
||||
/// does, in both block and flow context. A `:` with no following white space at all stays plain
|
||||
/// scalar content (`foo:bar`), unchanged.
|
||||
@Suite("Mapping value tab boundary")
|
||||
struct MappingValueTabBoundaryTests {
|
||||
@Test("A block mapping value may follow the colon after a tab")
|
||||
func test_blockValueTab() throws {
|
||||
#expect(try PureYAML.parse("foo:\tbar\n") == .mapping(.init([
|
||||
.init(key: "foo", value: .string("bar")),
|
||||
])))
|
||||
}
|
||||
|
||||
@Test("A block sequence item mapping accepts a tab after the colon")
|
||||
func test_blockSequenceItemTab() throws {
|
||||
#expect(try PureYAML.parse("- foo:\tbar\n") == .sequence([
|
||||
.mapping(.init([.init(key: "foo", value: .string("bar"))])),
|
||||
]))
|
||||
}
|
||||
|
||||
@Test("A flow mapping value may follow the colon after a tab")
|
||||
func test_flowValueTab() throws {
|
||||
#expect(try PureYAML.parse("{a:\tb}\n") == .mapping(.init([
|
||||
.init(key: "a", value: .string("b")),
|
||||
])))
|
||||
}
|
||||
|
||||
@Test("A colon with no following white space stays plain scalar content")
|
||||
func test_colonWithoutWhitespaceUnchanged() throws {
|
||||
#expect(try PureYAML.parse("foo:bar\n") == .string("foo:bar"))
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user