test(conformance): track all 402 suite cases; fix 3 regressions

The gap-only manifest stopped guarding a case once it was fixed, so later
work silently regressed previously-fixed cases (caught only by an external
full-suite run, not the gated sweep or full corpus). Replace it with a full
manifest of all 402 official cases (Tests/Fixtures/yaml-test-suite-manifest.yaml),
each carrying its conformant expectation and a passing/gap status, with every
case's files vendored. The gated sweep now asserts every passing case still
passes (the regression guard) and every gap still reproduces, so any regression
fails the build.

The honest gate-enforced count is 329/402 passing (the earlier 348 came from a
more lenient one-time oracle).

Repairs three regressions the new gate revealed: the bucket-6 tab rule
over-rejected tabs in block-scalar content and as separation before a scalar
value (root cause: the batch scanner and the incremental TokenCursor had
divergent line-start loops; unified onto a single scanStep, fixing 96NN/00,
96NN/01, R4YG, Y79Y/001, DK95/00, DK95/03, DK95/07, 6CA3, Q5MG, J3BT); an anchor
on a prior line before an alias key wrongly rejected 26DV; and a tag-only flow
key mis-parsed WZ62. Genuine tab-indentation errors (4EJS, Y79Y/000) still reject.
This commit is contained in:
Mihaela Mihaljevic 2026-06-24 00:16:28 +02:00
parent 16da7248c7
commit ce0585f77e
690 changed files with 6392 additions and 673 deletions

View File

@ -64,6 +64,7 @@ SKIP_PATTERNS=(
'^_archive/'
'^Tests/Fixtures/acme/'
'^Tests/Fixtures/real-yaml/'
'^Tests/Fixtures/yaml-test-suite/'
# Rule files that DEFINE the prohibitions; they MUST be able to cite
# the forbidden strings to document them.
'/github-discipline\.md$'

View File

@ -28,8 +28,8 @@ source for PureYAML.
`Tests/Fixtures/yaml-test-suite/` contains input cases vendored from the official
[YAML test suite](https://github.com/yaml/yaml-test-suite) (`data` branch, commit
`6ad3d2c62885d82fc349026c136ef560838fdf3d`), which is distributed under the MIT
license. Only the cases PureYAML does not yet handle correctly are vendored, each as
its input (`in.yaml`), expected JSON projection (`in.json`), and expected-error
marker (`error`). `Tests/Fixtures/yaml-test-suite-gaps.yaml` records the provenance
and each case's current behavior. These files are test data, not implementation
license. All 402 cases (numbered sub-cases counted) are vendored, each as its input
(`in.yaml`), expected JSON projection (`in.json`), and/or expected-error marker
(`error`). `Tests/Fixtures/yaml-test-suite-manifest.yaml` records the provenance and
each case's conformance status. These files are test data, not implementation
source.

View File

@ -9,6 +9,36 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Fixed
- Make the YAML test suite conformance gate comprehensive and repair the
regressions it revealed. The gap-only manifest (which deleted a case once fixed,
so nothing guarded it afterward and later work could silently regress it) is
replaced by a full manifest of all 402 official cases
(`Tests/Fixtures/yaml-test-suite-manifest.yaml`), each with its `id`, `name`,
`localPath`, conformant `expected` behavior, `oracle`, `byteCount`, `lineCount`,
and a `status` (`passing` | `gap`). Every case's files are vendored under
`Tests/Fixtures/yaml-test-suite/`. The gated sweep
(`PUREYAML_RUN_YAML_TEST_SUITE=1`) now asserts every `passing` case still passes
and every `gap` still reproduces, so a regression in any passing case fails the
sweep. Result at the pinned commit: **329 of 402 passing, 73 gap.**
- Stop over-rejecting tabs. A tab is invalid only as block-structure indentation
(`scanner.c` `scan_to_next_token` / `scan_block_scalar_breaks` /
`scan_plain_scalar`). Block indentation is now measured in spaces only; a tab is
left for the token scanner, which allows it inside block-scalar content once a
leading space fixes the content column (96NN/00, 96NN/01, R4YG, Y79Y/001), as
separation before a scalar value (DK95/00) or a flow node (6CA3, Q5MG, J3BT), and
on a whitespace-only blank line (DK95/03, DK95/07), while still rejecting genuine
tab indentation (4EJS, Y79Y/000, Y79Y/004-008, DK95/06). The batch scanner and the
incremental token cursor were unified onto a single `scanStep`, since their
divergence previously let the streaming parser miss a tab error the batch scanner
caught.
- Restore anchors/aliases as mapping keys for `26DV`: an anchor on a `key:` value
line followed by an indented `*alias :` key now anchors the nested mapping rather
than the alias key (which cannot carry properties); `&b *alias` on one line is
still rejected (SU74).
- Restore flow bare-tag/anchor keys for `WZ62` (`{ foo : !!str, !!str : bar, }` to
`{"foo":"", "":"bar"}`): a flow key introduced by a spliced `mappingKey` uses the
same key parser as the implicit form, so a bare tag before the `:` composes an
empty tagged scalar key instead of a mapping-as-key.
- Complete flow-collection (`[...]`, `{...}`) parsing for keys, empty nodes, and
multi-line scalars, fixing 10 official YAML test suite cases and removing them
from the conformance gap manifest. The scanner now implements libyaml's

View File

@ -164,14 +164,7 @@ extension PureYAML.Parsing.Scanner {
}
state.reader.advance()
}
// A tab where a block-scalar indentation space is expected is rejected,
// matching scanner.c:2993-2997 ("found a tab character where an
// indentation space is expected"). The tab only abuses indentation when
// it sits below the block's indent column (or while indent is still
// being auto-detected).
if state.reader.peek() == "\t", indent == 0 || blockScalarColumn(state) < indent {
throw PureYAML.Parsing.ParseError.tabIndentation(line: state.reader.mark.line)
}
try rejectBlockScalarIndentationTab(indent: indent, state: state)
if blockScalarColumn(state) > maxIndent {
maxIndent = blockScalarColumn(state)
}
@ -193,6 +186,25 @@ extension PureYAML.Parsing.Scanner {
}
}
/// Rejects a tab where a block-scalar indentation space is expected, matching
/// scanner.c:2993-2997 ("found a tab character where an indentation space is
/// expected"). The tab abuses indentation only when it would itself supply the
/// block's indent: with a fixed indent, that is any tab below the content column;
/// while auto-detecting (`indent == 0`), a tab at column 0 (no space established a
/// content column) is illegal, but a tab after one or more leading spaces is the
/// first content character of an indented line, so the spaces fix the indent and
/// the tab is preserved as content.
private func rejectBlockScalarIndentationTab(indent: Int, state: State) throws {
guard state.reader.peek() == "\t" else {
return
}
let column = blockScalarColumn(state)
let abusesIndentation = indent > 0 ? column < indent : column == 0
if abusesIndentation {
throw PureYAML.Parsing.ParseError.tabIndentation(line: state.reader.mark.line)
}
}
/// Reads a single line break, normalizing CR and CRLF to a single `\n`.
private func readBlockScalarLineBreak(_ state: inout State) -> String {
guard isLineBreak(state.reader.peek()) else {

View File

@ -27,30 +27,20 @@ extension PureYAML.Parsing.Scanner {
func scanIndentationWidth(_ state: inout State) throws -> Int {
var width = 0
while let character = state.reader.peek() {
if character == " " {
while state.reader.peek() == " " {
width += 1
state.reader.advance()
} else if character == "\t" {
// A tab may not provide block indentation. At the start of a block
// line a simple key is allowed, so libyaml does not consume the tab
// as whitespace and the line is malformed (scanner.c:1948-1953). A
// tab is only legal here once it follows content on the same line.
if state.flowDepth == 0, state.simpleKeyAllowed {
throw PureYAML.Parsing.ParseError.tabIndentation(line: state.reader.mark.line)
}
width = nextTabStop(after: width)
state.reader.advance()
} else {
// Block indentation (s-indent) is spaces only: a tab is never indentation
// (scanner.c's scan_to_next_token eats only spaces unconditionally). The tab
// is left under the reader so the token scanner can decide whether it is legal
// in-line separation (before a scalar value or flow node) or an illegal tab
// that supplies the indentation of a nested block node; `rejectTabSeparation`
// and the blank-line handling in `scan` make that call. A whitespace-only line
// (spaces and/or tabs followed by a break) is a blank line and carries no
// indentation token.
return width
}
}
return width
}
func nextTabStop(after width: Int) -> Int {
((width / 4) + 1) * 4
}
func shouldProcessIndentation(_ state: State) -> Bool {
guard !state.reader.isAtEnd, !isLineBreak(state.reader.peek()) else {

View File

@ -0,0 +1,85 @@
extension PureYAML.Parsing.Scanner {
/// Result of one scanning iteration over the source. Both the batch ``scan``
/// loop and the incremental ``PureYAML/Parsing/TokenCursor`` driver share the
/// same step so the two paths cannot diverge (a divergence is what once let a
/// tab-indentation error slip past the streaming parser while the batch scanner
/// caught it).
enum Step {
/// Nothing remains; the caller appends stream end and stops.
case endOfInput
/// A line break, blank line, or comment was consumed; restart the loop.
case advanced
/// A directive or document marker was scanned; restart the loop.
case scannedMarker
/// An ordinary token was scanned.
case scannedToken
}
/// Performs one scanning iteration: consumes a leading line break or blank line,
/// scans indentation at a line start, then scans either a directive / document
/// marker or one ordinary token. Resets `simpleKeyAllowed` at every block-context
/// line break so a tab at the next line start is recognized as (illegal)
/// indentation rather than (legal) in-line separation.
func scanStep(_ state: inout State) throws -> Step {
if state.reader.isAtEnd {
return .endOfInput
}
if isLineBreak(state.reader.peek()) {
state.reader.advance()
state.isAtLineStart = true
if state.flowDepth == 0 {
state.simpleKeyAllowed = true
}
return .advanced
}
if state.isAtLineStart {
// A line whose entire content is blanks (spaces and/or tabs) before the
// break is a blank line: it carries no indentation and no token, matching
// scanner.c's scan_to_next_token, which eats the blanks and the break
// before any indent processing. Consuming it here keeps a whitespace-only
// line (e.g. `· \t`) from emitting a spurious indent token or being
// mis-scanned as content.
if consumeBlankLineRemainder(&state) {
return .advanced
}
try scanIndentation(&state)
if state.reader.isAtEnd || isLineBreak(state.reader.peek()) {
return .advanced
}
if try scanDirectiveOrDocumentMarker(&state) {
return .scannedMarker
}
state.isAtLineStart = false
}
try scanToken(&state)
return .scannedToken
}
/// When the reader sits on a run of blanks (spaces and/or tabs) that ends the
/// line (a line break or end of input follows), consumes that run plus the line
/// break and reports true: the line was blank. Otherwise leaves the reader where
/// it was and reports false. Used so a whitespace-only line (e.g. `· \t`) is
/// skipped rather than mis-scanned as plain-scalar content.
func consumeBlankLineRemainder(_ state: inout State) -> Bool {
var offset = 0
while let character = state.reader.peek(offset: offset), character == " " || character == "\t" {
offset += 1
}
let next = state.reader.peek(offset: offset)
guard next == nil || isLineBreak(next) else {
return false
}
for _ in 0 ..< offset {
state.reader.advance()
}
if isLineBreak(state.reader.peek()) {
state.reader.advance()
if state.flowDepth == 0 {
state.simpleKeyAllowed = true
}
}
return true
}
}

View File

@ -6,31 +6,13 @@ extension PureYAML.Parsing {
var state = State(reader: Reader(yaml))
state.append(.streamStart)
while !state.reader.isAtEnd {
if isLineBreak(state.reader.peek()) {
state.reader.advance()
state.isAtLineStart = true
if state.flowDepth == 0 {
state.simpleKeyAllowed = true
}
loop: while !state.reader.isAtEnd {
switch try scanStep(&state) {
case .endOfInput:
break loop
case .advanced, .scannedMarker, .scannedToken:
continue
}
if state.isAtLineStart {
try scanIndentation(&state)
if state.reader.isAtEnd {
break
}
if isLineBreak(state.reader.peek()) {
continue
}
if try scanDirectiveOrDocumentMarker(&state) {
continue
}
state.isAtLineStart = false
}
try scanToken(&state)
}
if state.hasPendingDirective {
@ -132,8 +114,9 @@ extension PureYAML.Parsing.Scanner {
extension PureYAML.Parsing.Scanner {
func scanToken(_ state: inout State) throws {
skipSeparation(&state)
skipSpaceSeparation(&state)
try rejectTabSeparation(&state)
skipSeparation(&state)
guard let character = state.reader.peek(), !isLineBreak(character) else {
return
}
@ -249,12 +232,22 @@ extension PureYAML.Parsing.Scanner {
}
}
func skipSeparation(_ state: inout State) {
func skipSpaceSeparation(_ state: inout State) {
while state.reader.peek() == " " {
state.reader.advance()
}
}
func skipSeparation(_ state: inout State) {
// In-line separation (s-white) is spaces and tabs. `rejectTabSeparation` has
// already rejected any tab that would supply the indentation of a nested block
// node, so a tab still under the reader here is ordinary separation before a
// scalar value or flow node and is consumed like a space (scanner.c IS_BLANK).
while let character = state.reader.peek(), character == " " || character == "\t" {
state.reader.advance()
}
}
func scanFixedToken(
_ kind: PureYAML.Parsing.TokenKind,
state: inout State,

View File

@ -83,7 +83,7 @@ extension PureYAML.Parsing {
// flow collection's tokens must stay in `state.tokens` until it closes
// for the retroactive index to remain valid.
while scannerBox.state.tokens.isEmpty || scannerBox.state.flowDepth > 0 {
guard !scannerBox.state.reader.isAtEnd else {
if scannerBox.state.reader.isAtEnd {
if scannerBox.state.hasPendingDirective {
throw PureYAML.Parsing.ParseError.directiveWithoutDocument(
line: scannerBox.state.reader.mark.line,
@ -96,30 +96,13 @@ extension PureYAML.Parsing {
return
}
if scanner.isLineBreak(scannerBox.state.reader.peek()) {
scannerBox.state.reader.advance()
scannerBox.state.isAtLineStart = true
continue
}
if scannerBox.state.isAtLineStart {
try scanner.scanIndentation(&scannerBox.state)
if scannerBox.state.reader.isAtEnd {
continue
}
if scanner.isLineBreak(scannerBox.state.reader.peek()) {
continue
}
if try scanner.scanDirectiveOrDocumentMarker(&scannerBox.state) {
if !scannerBox.state.tokens.isEmpty {
// Drive the same scanning step the batch scanner uses, so the two
// paths share one source of truth for line breaks, blank lines,
// indentation, and `simpleKeyAllowed` handling.
let step = try scanner.scanStep(&scannerBox.state)
if case .scannedMarker = step, !scannerBox.state.tokens.isEmpty {
break
}
continue
}
scannerBox.state.isAtLineStart = false
}
try scanner.scanToken(&scannerBox.state)
}
drainScannedTokens(from: &scannerBox.state)

View File

@ -129,7 +129,14 @@ extension PureYAML.Parsing.TokenEventParser {
if flowKeyIsEmpty() {
try emitEmptyScalar(properties: .none, mark: keyIndicator.endMark)
} else {
_ = try parseNode()
// The key of a flow pair follows the same rules whether the pair was
// introduced by an explicit `?` or had a `mappingKey` spliced in by the
// simple-key mechanism: a bare tag/anchor before the `:` composes an empty
// tagged scalar key (`{ !!str : bar }`), and an alias before the `:` is the
// key itself. Routing through `parseNode` would instead treat the tag/`:`
// as a nested block mapping, so use the flow key parser shared with the
// implicit form.
try parseFlowMappingImplicitKey()
}
return try parseFlowMappingValue()
}

View File

@ -259,11 +259,18 @@ extension PureYAML.Parsing.TokenEventParser {
// An alias is a complete reference to an already-anchored node and cannot
// itself carry an anchor or tag. libyaml handles ALIAS as the first branch
// of yaml_parser_parse_node (parser.c:563-570), so the property branches
// are unreachable for an alias; mirror that by rejecting `&b *alias`.
if properties.anchor != nil || properties.tag != nil {
// are unreachable for an alias; mirror that by rejecting `&b *alias`. The
// rejection applies only when the property sits on the *same line* as the
// alias: a property scanned on the previous line (e.g. `key: &anchor` then an
// indented `*alias : value`) anchors the enclosing mapping, not the alias key.
let hasProperties = properties.anchor != nil || properties.tag != nil
if hasProperties, properties.mark?.line == token.mark.line {
let mark = properties.mark ?? token.mark
throw PureYAML.Parsing.ParseError.expectedNode(line: mark.line, column: mark.column)
}
// An alias immediately followed by a `:` is the first key of a block mapping;
// any property that reached here belongs to the mapping (it was on a prior
// line, per the check above), so route into the mapping carrying it.
if try cursor.peek()?.kind.isMappingValue == true {
return try parseBlockMapping(
properties: properties,

View File

@ -1,498 +0,0 @@
version: 1
description: PureYAML conformance gaps vs the official YAML test suite
source:
repository: yaml/yaml-test-suite
branch: data
commit: 6ad3d2c62885d82fc349026c136ef560838fdf3d
license: MIT
# Each entry is a case PureYAML does NOT yet handle correctly.
# category: false-reject | json-mismatch | accepted-invalid
# expected: what a conformant parser must do (parse-ok | reject)
# current: PureYAML's present behavior (parse-error | value-mismatch | accepted)
cases:
- id: "2G84/00"
name: "Literal modifers"
localPath: yaml-test-suite/2G84/00/in.yaml
category: accepted-invalid
expected: reject
oracle: none
current: accepted
byteCount: 7
lineCount: 1
- id: "2G84/01"
name: "Literal modifers"
localPath: yaml-test-suite/2G84/01/in.yaml
category: accepted-invalid
expected: reject
oracle: none
current: accepted
byteCount: 8
lineCount: 1
- id: "2SXE"
name: "Anchors With Colon in Name"
localPath: yaml-test-suite/2SXE/in.yaml
category: json-mismatch
expected: parse-ok
oracle: json
current: value-mismatch
byteCount: 29
lineCount: 3
- id: "3HFZ"
name: "Invalid content after document end marker"
localPath: yaml-test-suite/3HFZ/in.yaml
category: accepted-invalid
expected: reject
oracle: none
current: accepted
byteCount: 27
lineCount: 3
- id: "4JVG"
name: "Scalar value with two anchors"
localPath: yaml-test-suite/4JVG/in.yaml
category: accepted-invalid
expected: reject
oracle: none
current: accepted
byteCount: 54
lineCount: 4
- id: "55WF"
name: "Invalid escape in double quoted string"
localPath: yaml-test-suite/55WF/in.yaml
category: accepted-invalid
expected: reject
oracle: none
current: accepted
byteCount: 9
lineCount: 2
- id: "57H4"
name: "Spec Example 8.22. Block Collection Nodes"
localPath: yaml-test-suite/57H4/in.yaml
category: false-reject
expected: parse-ok
oracle: json
current: parse-error
byteCount: 67
lineCount: 6
- id: "5U3A"
name: "Sequence on same Line as Mapping Key"
localPath: yaml-test-suite/5U3A/in.yaml
category: accepted-invalid
expected: reject
oracle: none
current: accepted
byteCount: 18
lineCount: 2
- id: "62EZ"
name: "Invalid block mapping key on same line as previous key"
localPath: yaml-test-suite/62EZ/in.yaml
category: accepted-invalid
expected: reject
oracle: none
current: accepted
byteCount: 25
lineCount: 2
- id: "6BFJ"
name: "Mapping, key and flow sequence item anchors"
localPath: yaml-test-suite/6BFJ/in.yaml
category: false-reject
expected: parse-ok
oracle: none
current: parse-error
byteCount: 43
lineCount: 3
- id: "7LBH"
name: "Multiline double quoted implicit keys"
localPath: yaml-test-suite/7LBH/in.yaml
category: accepted-invalid
expected: reject
oracle: none
current: accepted
byteCount: 20
lineCount: 3
- id: "7ZZ5"
name: "Empty flow collections"
localPath: yaml-test-suite/7ZZ5/in.yaml
category: json-mismatch
expected: parse-ok
oracle: json
current: value-mismatch
byteCount: 58
lineCount: 6
- id: "8XDJ"
name: "Comment in plain multiline value"
localPath: yaml-test-suite/8XDJ/in.yaml
category: accepted-invalid
expected: reject
oracle: none
current: accepted
byteCount: 26
lineCount: 3
- id: "9C9N"
name: "Wrong indented flow sequence"
localPath: yaml-test-suite/9C9N/in.yaml
category: accepted-invalid
expected: reject
oracle: none
current: accepted
byteCount: 20
lineCount: 4
- id: "9JBA"
name: "Invalid comment after end of flow sequence"
localPath: yaml-test-suite/9JBA/in.yaml
category: accepted-invalid
expected: reject
oracle: none
current: accepted
byteCount: 25
lineCount: 2
- id: "9MAG"
name: "Flow sequence with invalid comma at the beginning"
localPath: yaml-test-suite/9MAG/in.yaml
category: accepted-invalid
expected: reject
oracle: none
current: accepted
byteCount: 18
lineCount: 2
- id: "BF9H"
name: "Trailing comment in multiline plain scalar"
localPath: yaml-test-suite/BF9H/in.yaml
category: accepted-invalid
expected: reject
oracle: none
current: accepted
byteCount: 47
lineCount: 4
- id: "CTN5"
name: "Flow sequence with invalid extra comma"
localPath: yaml-test-suite/CTN5/in.yaml
category: accepted-invalid
expected: reject
oracle: none
current: accepted
byteCount: 19
lineCount: 2
- id: "CVW2"
name: "Invalid comment after comma"
localPath: yaml-test-suite/CVW2/in.yaml
category: accepted-invalid
expected: reject
oracle: none
current: accepted
byteCount: 25
lineCount: 3
- id: "CXX2"
name: "Mapping with anchor on document start line"
localPath: yaml-test-suite/CXX2/in.yaml
category: accepted-invalid
expected: reject
oracle: none
current: accepted
byteCount: 17
lineCount: 1
- id: "D49Q"
name: "Multiline single quoted implicit keys"
localPath: yaml-test-suite/D49Q/in.yaml
category: accepted-invalid
expected: reject
oracle: none
current: accepted
byteCount: 20
lineCount: 3
- id: "DC7X"
name: "Various trailing tabs"
localPath: yaml-test-suite/DC7X/in.yaml
category: json-mismatch
expected: parse-ok
oracle: json
current: value-mismatch
byteCount: 26
lineCount: 4
- id: "DK95/01"
name: "Tabs that look like indentation"
localPath: yaml-test-suite/DK95/01/in.yaml
category: accepted-invalid
expected: reject
oracle: json
current: accepted
byteCount: 16
lineCount: 2
- id: "FH7J"
name: "Tags on Empty Scalars"
localPath: yaml-test-suite/FH7J/in.yaml
category: false-reject
expected: parse-ok
oracle: none
current: parse-error
byteCount: 51
lineCount: 5
- id: "G5U8"
name: "Plain dashes in flow sequence"
localPath: yaml-test-suite/G5U8/in.yaml
category: accepted-invalid
expected: reject
oracle: none
current: accepted
byteCount: 13
lineCount: 2
- id: "H7J7"
name: "Node anchor not indented"
localPath: yaml-test-suite/H7J7/in.yaml
category: accepted-invalid
expected: reject
oracle: none
current: accepted
byteCount: 21
lineCount: 3
- id: "HRE5"
name: "Double quoted scalar with escaped single quote"
localPath: yaml-test-suite/HRE5/in.yaml
category: accepted-invalid
expected: reject
oracle: none
current: accepted
byteCount: 31
lineCount: 2
- id: "HU3P"
name: "Invalid Mapping in plain scalar"
localPath: yaml-test-suite/HU3P/in.yaml
category: accepted-invalid
expected: reject
oracle: none
current: accepted
byteCount: 29
lineCount: 3
- id: "J3BT"
name: "Spec Example 5.12. Tabs and Spaces"
localPath: yaml-test-suite/J3BT/in.yaml
category: json-mismatch
expected: parse-ok
oracle: json
current: value-mismatch
byteCount: 96
lineCount: 6
- id: "JEF9/02"
name: "Trailing whitespace in streams"
localPath: yaml-test-suite/JEF9/02/in.yaml
category: json-mismatch
expected: parse-ok
oracle: json
current: value-mismatch
byteCount: 8
lineCount: 1
- id: "JKF3"
name: "Multiline unidented double quoted block key"
localPath: yaml-test-suite/JKF3/in.yaml
category: accepted-invalid
expected: reject
oracle: none
current: accepted
byteCount: 17
lineCount: 2
- id: "JY7Z"
name: "Trailing content that looks like a mapping"
localPath: yaml-test-suite/JY7Z/in.yaml
category: accepted-invalid
expected: reject
oracle: none
current: accepted
byteCount: 66
lineCount: 3
- id: "LX3P"
name: "Implicit Flow Mapping Key on one line"
localPath: yaml-test-suite/LX3P/in.yaml
category: false-reject
expected: parse-ok
oracle: none
current: parse-error
byteCount: 14
lineCount: 1
- id: "M5C3"
name: "Spec Example 8.21. Block Scalar Nodes"
localPath: yaml-test-suite/M5C3/in.yaml
category: false-reject
expected: parse-ok
oracle: json
current: parse-error
byteCount: 48
lineCount: 6
- id: "M7A3"
name: "Spec Example 9.3. Bare Documents"
localPath: yaml-test-suite/M7A3/in.yaml
category: json-mismatch
expected: parse-ok
oracle: json
current: value-mismatch
byteCount: 74
lineCount: 7
- id: "NB6Z"
name: "Multiline plain value with tabs on empty lines"
localPath: yaml-test-suite/NB6Z/in.yaml
category: json-mismatch
expected: parse-ok
oracle: json
current: value-mismatch
byteCount: 31
lineCount: 5
- id: "P2EQ"
name: "Invalid sequene item on same line as previous item"
localPath: yaml-test-suite/P2EQ/in.yaml
category: accepted-invalid
expected: reject
oracle: none
current: accepted
byteCount: 24
lineCount: 2
- id: "Q9WF"
name: "Spec Example 6.12. Separation Spaces"
localPath: yaml-test-suite/Q9WF/in.yaml
category: false-reject
expected: parse-ok
oracle: none
current: parse-error
byteCount: 97
lineCount: 6
- id: "QB6E"
name: "Wrong indented multiline quoted scalar"
localPath: yaml-test-suite/QB6E/in.yaml
category: accepted-invalid
expected: reject
oracle: none
current: accepted
byteCount: 20
lineCount: 4
- id: "QLJ7"
name: "Tag shorthand used in documents but only defined in the first"
localPath: yaml-test-suite/QLJ7/in.yaml
category: accepted-invalid
expected: reject
oracle: none
current: accepted
byteCount: 93
lineCount: 7
- id: "S4JQ"
name: "Spec Example 6.28. Non-Specific Tags"
localPath: yaml-test-suite/S4JQ/in.yaml
category: json-mismatch
expected: parse-ok
oracle: json
current: value-mismatch
byteCount: 55
lineCount: 4
- id: "S98Z"
name: "Block scalar with more spaces than first content line"
localPath: yaml-test-suite/S98Z/in.yaml
category: accepted-invalid
expected: reject
oracle: none
current: accepted
byteCount: 42
lineCount: 5
- id: "SKE5"
name: "Anchor before zero indented sequence"
localPath: yaml-test-suite/SKE5/in.yaml
category: false-reject
expected: parse-ok
oracle: json
current: parse-error
byteCount: 26
lineCount: 5
- id: "SU5Z"
name: "Comment without whitespace after doublequoted scalar"
localPath: yaml-test-suite/SU5Z/in.yaml
category: accepted-invalid
expected: reject
oracle: none
current: accepted
byteCount: 30
lineCount: 1
- id: "SY6V"
name: "Anchor before sequence entry on same line"
localPath: yaml-test-suite/SY6V/in.yaml
category: accepted-invalid
expected: reject
oracle: none
current: accepted
byteCount: 25
lineCount: 1
- id: "UKK6/00"
name: "Syntax character edge cases"
localPath: yaml-test-suite/UKK6/00/in.yaml
category: false-reject
expected: parse-ok
oracle: none
current: parse-error
byteCount: 4
lineCount: 1
- id: "UV7Q"
name: "Legal tab after indentation"
localPath: yaml-test-suite/UV7Q/in.yaml
category: json-mismatch
expected: parse-ok
oracle: json
current: value-mismatch
byteCount: 13
lineCount: 3
- id: "V9D5"
name: "Spec Example 8.19. Compact Block Mappings"
localPath: yaml-test-suite/V9D5/in.yaml
category: false-reject
expected: parse-ok
oracle: none
current: parse-error
byteCount: 46
lineCount: 3
- id: "VJP3/00"
name: "Flow collections over many lines"
localPath: yaml-test-suite/VJP3/00/in.yaml
category: accepted-invalid
expected: reject
oracle: none
current: accepted
byteCount: 13
lineCount: 5
- id: "X4QW"
name: "Comment without whitespace after block scalar indicator"
localPath: yaml-test-suite/X4QW/in.yaml
category: accepted-invalid
expected: reject
oracle: none
current: accepted
byteCount: 27
lineCount: 2
- id: "Y79Y/003"
name: "Tabs in various contexts"
localPath: yaml-test-suite/Y79Y/003/in.yaml
category: accepted-invalid
expected: reject
oracle: none
current: accepted
byteCount: 18
lineCount: 4
- id: "YJV2"
name: "Dash in flow sequence"
localPath: yaml-test-suite/YJV2/in.yaml
category: accepted-invalid
expected: reject
oracle: none
current: accepted
byteCount: 4
lineCount: 1
- id: "ZCZ6"
name: "Invalid mapping in plain single line value"
localPath: yaml-test-suite/ZCZ6/in.yaml
category: accepted-invalid
expected: reject
oracle: none
current: accepted
byteCount: 11
lineCount: 1
- id: "ZL4Z"
name: "Invalid nested mapping"
localPath: yaml-test-suite/ZL4Z/in.yaml
category: accepted-invalid
expected: reject
oracle: none
current: accepted
byteCount: 14
lineCount: 2

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,12 @@
[
{
"name": "Mark McGwire",
"hr": 65,
"avg": 0.278
},
{
"name": "Sammy Sosa",
"hr": 63,
"avg": 0.288
}
]

View File

@ -0,0 +1,8 @@
-
name: Mark McGwire
hr: 65
avg: 0.278
-
name: Sammy Sosa
hr: 63
avg: 0.288

View File

@ -0,0 +1,3 @@
foo:
bar
invalid

View File

@ -0,0 +1,18 @@
{
"top1": {
"key1": "scalar1"
},
"top2": {
"key2": "scalar2"
},
"top3": {
"scalar1": "scalar3"
},
"top4": {
"scalar2": "scalar4"
},
"top5": "scalar5",
"top6": {
"key6": "scalar6"
}
}

View File

@ -0,0 +1,12 @@
"top1" :
"key1" : &alias1 scalar1
'top2' :
'key2' : &alias2 scalar2
top3: &node3
*alias1 : scalar3
top4:
*alias2 : scalar4
top5 :
scalar5
top6:
&anchor6 'key6' : scalar6

View File

@ -0,0 +1 @@
"text"

View File

@ -0,0 +1,2 @@
%YAML 1.2
--- text

View File

@ -0,0 +1,6 @@
[
"a",
"b",
42,
"d"
]

View File

@ -0,0 +1,4 @@
- !!str a
- b
- !!int 42
- d

View File

@ -0,0 +1,3 @@
this
is
invalid: x

View File

@ -0,0 +1,7 @@
{
"a!\"#$%&'()*+,-./09:;<=>?@AZ[\\]^_`az{|}~": "safe",
"?foo": "safe question mark",
":foo": "safe colon",
"-foo": "safe dash",
"this is#not": "a comment"
}

View File

@ -0,0 +1,5 @@
a!"#$%&'()*+,-./09:;<=>?@AZ[\]^_`az{|}~: safe
?foo: safe question mark
:foo: safe colon
-foo: safe dash
this is#not: a comment

View File

@ -0,0 +1 @@
""

View File

@ -0,0 +1 @@
--- |1-

View File

@ -0,0 +1 @@
""

View File

@ -0,0 +1 @@
--- |1+

View File

@ -0,0 +1,2 @@
: a
: b

View File

@ -0,0 +1 @@
"foo"

View File

@ -0,0 +1,4 @@
%FOO bar baz # Should be ignored
# with a warning.
---
"foo"

View File

@ -0,0 +1,5 @@
{
"Mark McGwire": null,
"Sammy Sosa": null,
"Ken Griff": null
}

View File

@ -0,0 +1,7 @@
# Sets are represented as a
# Mapping where each key is
# associated with a null value
--- !!set
? Mark McGwire
? Sammy Sosa
? Ken Griff

View File

@ -0,0 +1,5 @@
[
1,
-2,
33
]

View File

@ -0,0 +1,4 @@
---
- !!int 1
- !!int -2
- !!int 33

View File

@ -0,0 +1,7 @@
{
"a": "b"
}
[
"c"
]
"d e"

View File

@ -0,0 +1,8 @@
--- !!map
? a
: b
--- !!seq
- !!str c
--- !!str
d
e

View File

@ -0,0 +1,3 @@
{
"plain": "a b\nc"
}

View File

@ -0,0 +1,5 @@
---
plain: a
b
c

View File

@ -0,0 +1,7 @@
[
[
"s1_i1",
"s1_i2"
],
"s2"
]

View File

@ -0,0 +1,3 @@
- - s1_i1
- s1_i2
- s2

View File

@ -0,0 +1,6 @@
{
"First occurrence": "Foo",
"Second occurrence": "Foo",
"Override anchor": "Bar",
"Reuse anchor": "Bar"
}

View File

@ -0,0 +1,4 @@
First occurrence: &anchor Foo
Second occurrence: *anchor
Override anchor: &anchor Bar
Reuse anchor: *anchor

View File

@ -0,0 +1 @@
"k:#foo &a !t s"

View File

@ -0,0 +1,3 @@
---
k:#foo
&a !t s

View File

@ -0,0 +1,3 @@
[
"a"
]

View File

@ -0,0 +1,2 @@
&sequence
- a

View File

@ -0,0 +1 @@
"1 leading \ttab"

View File

@ -0,0 +1,2 @@
"1 leading
\ttab"

View File

@ -0,0 +1 @@
"2 leading \ttab"

View File

@ -0,0 +1,2 @@
"2 leading
\ tab"

View File

@ -0,0 +1 @@
"3 leading tab"

View File

@ -0,0 +1,2 @@
"3 leading
tab"

View File

@ -0,0 +1 @@
"4 leading \t tab"

View File

@ -0,0 +1,2 @@
"4 leading
\t tab"

View File

@ -0,0 +1 @@
"5 leading \t tab"

View File

@ -0,0 +1,2 @@
"5 leading
\ tab"

View File

@ -0,0 +1 @@
"6 leading tab"

View File

@ -0,0 +1,2 @@
"6 leading
tab"

View File

@ -0,0 +1,3 @@
{
"escaped slash": "a/b"
}

View File

@ -0,0 +1 @@
escaped slash: "a\/b"

View File

@ -0,0 +1,5 @@
{
unquoted : "separate",
http://foo.com,
omitted value:,
}

View File

@ -0,0 +1,4 @@
{
"plain": "This unquoted scalar spans many lines.",
"quoted": "So does this quoted scalar.\n"
}

View File

@ -0,0 +1,6 @@
plain:
This unquoted scalar
spans many lines.
quoted: "So does this
quoted scalar.\n"

View File

@ -0,0 +1,4 @@
---
a:
b:
c: value

View File

@ -0,0 +1,4 @@
---
[
[ a, [ [[b,c]]: d, e]]: 23
]

View File

@ -0,0 +1 @@
"here's to \"quotes\""

View File

@ -0,0 +1 @@
'here''s to "quotes"'

View File

@ -0,0 +1,2 @@
---
[ a, b, c ] ]

View File

@ -0,0 +1,4 @@
key:
- ok
- also ok
- wrong

View File

@ -0,0 +1,3 @@
{
"foo": "bar"
}

View File

@ -0,0 +1,2 @@
{"foo"
: "bar"}

View File

@ -0,0 +1,3 @@
{
"foo": "bar"
}

View File

@ -0,0 +1,2 @@
{"foo"
: bar}

View File

@ -0,0 +1,3 @@
{
"foo": "bar"
}

View File

@ -0,0 +1,2 @@
{foo
: bar}

View File

@ -0,0 +1 @@
"ab cd\nef\n\ngh\n"

View File

@ -0,0 +1,8 @@
--- >
ab
cd
ef
gh

View File

@ -0,0 +1,6 @@
[
"detected\n",
"\n\n# detected\n",
" explicit\n",
"detected\n"
]

View File

@ -0,0 +1,10 @@
- |
detected
- >
# detected
- |1
explicit
- >
detected

View File

@ -0,0 +1,5 @@
[
1,
2,
3
]

View File

@ -0,0 +1,2 @@
[1, 2, 3]

View File

@ -0,0 +1 @@
"foo: bar\": baz"

View File

@ -0,0 +1 @@
"foo: bar\": baz"

View File

@ -0,0 +1 @@
"plain\\value\\with\\backslashes"

View File

@ -0,0 +1,2 @@
---
plain\value\with\backslashes

View File

@ -0,0 +1,6 @@
[
{
"aaa" : "xxx\n",
"bbb" : "xxx\n"
}
]

View File

@ -0,0 +1,4 @@
- aaa: |2
xxx
bbb: |
xxx

View File

@ -0,0 +1,5 @@
{
"plain": "text lines",
"quoted": "text lines",
"block": "text\n \tlines\n"
}

View File

@ -0,0 +1,7 @@
plain: text
lines
quoted: "text
lines"
block: |
text
lines

View File

@ -0,0 +1 @@
"a"

View File

@ -0,0 +1,2 @@
---
! a

View File

@ -0,0 +1,4 @@
{
"foo": "you",
"bar": "far"
}

View File

@ -0,0 +1 @@
{foo: you, bar: far}

View File

@ -0,0 +1,5 @@
{
"canonical": "R0lGODlhDAAMAIQAAP//9/X17unp5WZmZgAAAOfn515eXvPz7Y6OjuDg4J+fn5OTk6enp56enmlpaWNjY6Ojo4SEhP/++f/++f/++f/++f/++f/++f/++f/++f/++f/++f/++f/++f/++f/++SH+Dk1hZGUgd2l0aCBHSU1QACwAAAAADAAMAAAFLCAgjoEwnuNAFOhpEMTRiggcz4BNJHrv/zCFcLiwMWYNG84BwwEeECcgggoBADs=",
"generic": "R0lGODlhDAAMAIQAAP//9/X17unp5WZmZgAAAOfn515eXvPz7Y6OjuDg4J+fn5\nOTk6enp56enmlpaWNjY6Ojo4SEhP/++f/++f/++f/++f/++f/++f/++f/++f/+\n+f/++f/++f/++f/++f/++SH+Dk1hZGUgd2l0aCBHSU1QACwAAAAADAAMAAAFLC\nAgjoEwnuNAFOhpEMTRiggcz4BNJHrv/zCFcLiwMWYNG84BwwEeECcgggoBADs=\n",
"description": "The binary value above is a tiny arrow encoded as a gif image."
}

Some files were not shown because too many files have changed in this diff Show More