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
71 lines
2.2 KiB
Swift
71 lines
2.2 KiB
Swift
@testable import PureYAML
|
|
import Testing
|
|
|
|
@Suite("Parsing Block Scalar Indicators")
|
|
struct ParsingBlockScalarIndicatorTests {
|
|
@Test("Parses block scalar text that starts with YAML indicators")
|
|
func test_blockScalarTextThatStartsWithYAMLIndicators() throws {
|
|
let root = try requireMapping(PureYAML.parse(
|
|
"""
|
|
description: |
|
|
**Fine-grained access tokens**
|
|
|
|
* [GitHub App user access tokens](https://docs.github.com)
|
|
- dash list item stays text
|
|
""",
|
|
))
|
|
|
|
// A literal block scalar preserves the blank line between the heading and
|
|
// the list (YAML 1.2 line 8.1.1.1); clip keeps a single trailing newline.
|
|
#expect(root?["description"] == .string(
|
|
"""
|
|
**Fine-grained access tokens**
|
|
|
|
* [GitHub App user access tokens](https://docs.github.com)
|
|
- dash list item stays text
|
|
|
|
""",
|
|
))
|
|
}
|
|
|
|
@Test("Block scalars keep a leading '#' as literal content, not a comment")
|
|
func test_blockScalarLeadingHashIsLiteralContent() throws {
|
|
let root = try requireMapping(PureYAML.parse(
|
|
"""
|
|
folded:
|
|
$ref: >-
|
|
#/components/schemas/foo
|
|
literal:
|
|
$ref: |-
|
|
#/components/schemas/bar
|
|
""",
|
|
))
|
|
|
|
#expect(root?.mapping("folded")?["$ref"] == .string("#/components/schemas/foo"))
|
|
#expect(root?.mapping("literal")?["$ref"] == .string("#/components/schemas/bar"))
|
|
}
|
|
|
|
@Test("A leading '#' is preserved across every line of a block scalar")
|
|
func test_blockScalarLeadingHashAcrossMultipleLines() throws {
|
|
let root = try requireMapping(PureYAML.parse(
|
|
"""
|
|
doc: |-
|
|
#/components/schemas/foo
|
|
plain line
|
|
#/components/schemas/bar
|
|
after: tail
|
|
""",
|
|
))
|
|
|
|
#expect(root?["doc"] == .string(
|
|
"""
|
|
#/components/schemas/foo
|
|
plain line
|
|
#/components/schemas/bar
|
|
""",
|
|
))
|
|
// The block scalar ends at the dedent; the following key is unaffected.
|
|
#expect(root?["after"] == .string("tail"))
|
|
}
|
|
}
|