From 88b67ff0b2a3cfed0f5dce9d44ba24a52dac05d1 Mon Sep 17 00:00:00 2001 From: Mihaela Mihaljevic Date: Tue, 23 Jun 2026 20:17:56 +0200 Subject: [PATCH] fix(parsing): apply flow folding to quoted scalars Single (') and double (") quoted multi-line scalars now apply YAML 1.2 flow folding (sections 6.5, 7.3.1, 7.3.2): trailing whitespace before a break is stripped, leading whitespace on continuation lines is stripped, a single break between non-empty lines folds to one space, and N consecutive breaks yield N-1 literal line feeds (first and last lines keep their own leading/trailing spaces as content). A double-quoted backslash at end of line suppresses the break entirely. Complete the double-quoted escape set: add \xXX and \UXXXXXXXX hex escapes plus the previously missing \0 \a \v \e, literal backslash-space, and named breaks \N \_ \L \P (existing \uXXXX surrogate-pair handling kept). The folding state machine mirrors scanner.c yaml_parser_scan_flow_scalar; implemented in Sources/Parsing/Scalar.swift. Flips 30 official YAML test suite cases to passing (250/402). Updates the gap manifest, fixtures, count assertions, and roadmap. --- CHANGELOG.md | 16 + Sources/Parsing/Scalar.swift | 313 +++++++++++++----- Tests/Fixtures/yaml-test-suite-gaps.yaml | 270 --------------- .../Fixtures/yaml-test-suite/3RLN/00/in.json | 1 - .../Fixtures/yaml-test-suite/3RLN/00/in.yaml | 2 - .../Fixtures/yaml-test-suite/3RLN/01/in.json | 1 - .../Fixtures/yaml-test-suite/3RLN/01/in.yaml | 2 - .../Fixtures/yaml-test-suite/3RLN/02/in.json | 1 - .../Fixtures/yaml-test-suite/3RLN/02/in.yaml | 2 - .../Fixtures/yaml-test-suite/3RLN/03/in.json | 1 - .../Fixtures/yaml-test-suite/3RLN/03/in.yaml | 2 - .../Fixtures/yaml-test-suite/3RLN/04/in.json | 1 - .../Fixtures/yaml-test-suite/3RLN/04/in.yaml | 2 - .../Fixtures/yaml-test-suite/3RLN/05/in.json | 1 - .../Fixtures/yaml-test-suite/3RLN/05/in.yaml | 2 - Tests/Fixtures/yaml-test-suite/4ZYM/in.json | 5 - Tests/Fixtures/yaml-test-suite/4ZYM/in.yaml | 7 - Tests/Fixtures/yaml-test-suite/565N/in.json | 5 - Tests/Fixtures/yaml-test-suite/565N/in.yaml | 12 - Tests/Fixtures/yaml-test-suite/5GBF/in.json | 4 - Tests/Fixtures/yaml-test-suite/5GBF/in.yaml | 8 - Tests/Fixtures/yaml-test-suite/6WPF/in.json | 1 - Tests/Fixtures/yaml-test-suite/6WPF/in.yaml | 8 - Tests/Fixtures/yaml-test-suite/7A4E/in.json | 1 - Tests/Fixtures/yaml-test-suite/7A4E/in.yaml | 4 - Tests/Fixtures/yaml-test-suite/8UDB/in.json | 11 - Tests/Fixtures/yaml-test-suite/8UDB/in.yaml | 8 - Tests/Fixtures/yaml-test-suite/9SA2/in.json | 8 - Tests/Fixtures/yaml-test-suite/9SA2/in.yaml | 4 - Tests/Fixtures/yaml-test-suite/9TFX/in.json | 1 - Tests/Fixtures/yaml-test-suite/9TFX/in.yaml | 5 - .../Fixtures/yaml-test-suite/DE56/00/in.json | 1 - .../Fixtures/yaml-test-suite/DE56/00/in.yaml | 2 - .../Fixtures/yaml-test-suite/DE56/01/in.json | 1 - .../Fixtures/yaml-test-suite/DE56/01/in.yaml | 2 - .../Fixtures/yaml-test-suite/DE56/02/in.json | 1 - .../Fixtures/yaml-test-suite/DE56/02/in.yaml | 2 - .../Fixtures/yaml-test-suite/DE56/03/in.json | 1 - .../Fixtures/yaml-test-suite/DE56/03/in.yaml | 2 - .../Fixtures/yaml-test-suite/DE56/04/in.json | 1 - .../Fixtures/yaml-test-suite/DE56/04/in.yaml | 2 - .../Fixtures/yaml-test-suite/DE56/05/in.json | 1 - .../Fixtures/yaml-test-suite/DE56/05/in.yaml | 2 - .../Fixtures/yaml-test-suite/DK95/02/in.json | 3 - .../Fixtures/yaml-test-suite/DK95/02/in.yaml | 2 - .../Fixtures/yaml-test-suite/DK95/08/in.json | 3 - .../Fixtures/yaml-test-suite/DK95/08/in.yaml | 2 - Tests/Fixtures/yaml-test-suite/G4RS/in.json | 8 - Tests/Fixtures/yaml-test-suite/G4RS/in.yaml | 7 - Tests/Fixtures/yaml-test-suite/NAT4/in.json | 10 - Tests/Fixtures/yaml-test-suite/NAT4/in.yaml | 23 -- Tests/Fixtures/yaml-test-suite/NP9H/in.json | 1 - Tests/Fixtures/yaml-test-suite/NP9H/in.yaml | 5 - Tests/Fixtures/yaml-test-suite/PRH3/in.json | 1 - Tests/Fixtures/yaml-test-suite/PRH3/in.yaml | 4 - Tests/Fixtures/yaml-test-suite/Q8AD/in.json | 1 - Tests/Fixtures/yaml-test-suite/Q8AD/in.yaml | 6 - Tests/Fixtures/yaml-test-suite/T4YY/in.json | 1 - Tests/Fixtures/yaml-test-suite/T4YY/in.yaml | 5 - Tests/Fixtures/yaml-test-suite/TL85/in.json | 1 - Tests/Fixtures/yaml-test-suite/TL85/in.yaml | 7 - Tests/Fixtures/yaml-test-suite/XV9V/in.json | 4 - Tests/Fixtures/yaml-test-suite/XV9V/in.yaml | 8 - Tests/YAMLTestSuiteGapsTests.swift | 4 +- docs/YAML_TEST_SUITE_CONFORMANCE.md | 31 +- 65 files changed, 263 insertions(+), 601 deletions(-) delete mode 100644 Tests/Fixtures/yaml-test-suite/3RLN/00/in.json delete mode 100644 Tests/Fixtures/yaml-test-suite/3RLN/00/in.yaml delete mode 100644 Tests/Fixtures/yaml-test-suite/3RLN/01/in.json delete mode 100644 Tests/Fixtures/yaml-test-suite/3RLN/01/in.yaml delete mode 100644 Tests/Fixtures/yaml-test-suite/3RLN/02/in.json delete mode 100644 Tests/Fixtures/yaml-test-suite/3RLN/02/in.yaml delete mode 100644 Tests/Fixtures/yaml-test-suite/3RLN/03/in.json delete mode 100644 Tests/Fixtures/yaml-test-suite/3RLN/03/in.yaml delete mode 100644 Tests/Fixtures/yaml-test-suite/3RLN/04/in.json delete mode 100644 Tests/Fixtures/yaml-test-suite/3RLN/04/in.yaml delete mode 100644 Tests/Fixtures/yaml-test-suite/3RLN/05/in.json delete mode 100644 Tests/Fixtures/yaml-test-suite/3RLN/05/in.yaml delete mode 100644 Tests/Fixtures/yaml-test-suite/4ZYM/in.json delete mode 100644 Tests/Fixtures/yaml-test-suite/4ZYM/in.yaml delete mode 100644 Tests/Fixtures/yaml-test-suite/565N/in.json delete mode 100644 Tests/Fixtures/yaml-test-suite/565N/in.yaml delete mode 100644 Tests/Fixtures/yaml-test-suite/5GBF/in.json delete mode 100644 Tests/Fixtures/yaml-test-suite/5GBF/in.yaml delete mode 100644 Tests/Fixtures/yaml-test-suite/6WPF/in.json delete mode 100644 Tests/Fixtures/yaml-test-suite/6WPF/in.yaml delete mode 100644 Tests/Fixtures/yaml-test-suite/7A4E/in.json delete mode 100644 Tests/Fixtures/yaml-test-suite/7A4E/in.yaml delete mode 100644 Tests/Fixtures/yaml-test-suite/8UDB/in.json delete mode 100644 Tests/Fixtures/yaml-test-suite/8UDB/in.yaml delete mode 100644 Tests/Fixtures/yaml-test-suite/9SA2/in.json delete mode 100644 Tests/Fixtures/yaml-test-suite/9SA2/in.yaml delete mode 100644 Tests/Fixtures/yaml-test-suite/9TFX/in.json delete mode 100644 Tests/Fixtures/yaml-test-suite/9TFX/in.yaml delete mode 100644 Tests/Fixtures/yaml-test-suite/DE56/00/in.json delete mode 100644 Tests/Fixtures/yaml-test-suite/DE56/00/in.yaml delete mode 100644 Tests/Fixtures/yaml-test-suite/DE56/01/in.json delete mode 100644 Tests/Fixtures/yaml-test-suite/DE56/01/in.yaml delete mode 100644 Tests/Fixtures/yaml-test-suite/DE56/02/in.json delete mode 100644 Tests/Fixtures/yaml-test-suite/DE56/02/in.yaml delete mode 100644 Tests/Fixtures/yaml-test-suite/DE56/03/in.json delete mode 100644 Tests/Fixtures/yaml-test-suite/DE56/03/in.yaml delete mode 100644 Tests/Fixtures/yaml-test-suite/DE56/04/in.json delete mode 100644 Tests/Fixtures/yaml-test-suite/DE56/04/in.yaml delete mode 100644 Tests/Fixtures/yaml-test-suite/DE56/05/in.json delete mode 100644 Tests/Fixtures/yaml-test-suite/DE56/05/in.yaml delete mode 100644 Tests/Fixtures/yaml-test-suite/DK95/02/in.json delete mode 100644 Tests/Fixtures/yaml-test-suite/DK95/02/in.yaml delete mode 100644 Tests/Fixtures/yaml-test-suite/DK95/08/in.json delete mode 100644 Tests/Fixtures/yaml-test-suite/DK95/08/in.yaml delete mode 100644 Tests/Fixtures/yaml-test-suite/G4RS/in.json delete mode 100644 Tests/Fixtures/yaml-test-suite/G4RS/in.yaml delete mode 100644 Tests/Fixtures/yaml-test-suite/NAT4/in.json delete mode 100644 Tests/Fixtures/yaml-test-suite/NAT4/in.yaml delete mode 100644 Tests/Fixtures/yaml-test-suite/NP9H/in.json delete mode 100644 Tests/Fixtures/yaml-test-suite/NP9H/in.yaml delete mode 100644 Tests/Fixtures/yaml-test-suite/PRH3/in.json delete mode 100644 Tests/Fixtures/yaml-test-suite/PRH3/in.yaml delete mode 100644 Tests/Fixtures/yaml-test-suite/Q8AD/in.json delete mode 100644 Tests/Fixtures/yaml-test-suite/Q8AD/in.yaml delete mode 100644 Tests/Fixtures/yaml-test-suite/T4YY/in.json delete mode 100644 Tests/Fixtures/yaml-test-suite/T4YY/in.yaml delete mode 100644 Tests/Fixtures/yaml-test-suite/TL85/in.json delete mode 100644 Tests/Fixtures/yaml-test-suite/TL85/in.yaml delete mode 100644 Tests/Fixtures/yaml-test-suite/XV9V/in.json delete mode 100644 Tests/Fixtures/yaml-test-suite/XV9V/in.yaml diff --git a/CHANGELOG.md b/CHANGELOG.md index c304a34..726b9b6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 cases pass: 4QFQ, 5LLU, 6VJK, 7T8X, 96NN/00, 96NN/01, DWX9, F6MC, F8F9, H2RW, JEF9/00, JEF9/01, K527, K858, L24T/00, L24T/01, M29M, M9B4, MJS9, P2AD, R4YG, TS54, W9L4, and Y79Y/001. +- Implemented YAML 1.2 flow (quoted) scalar line folding for both single (`'`) + and double (`"`) quoted scalars, mirroring the reference scanner's + `yaml_parser_scan_flow_scalar`. Multi-line quoted scalars now fold correctly: + trailing whitespace before a break is stripped, leading whitespace on a + continuation line is stripped, a single break between non-empty lines folds to + one space, and N consecutive breaks yield N-1 literal line feeds (the first and + last lines keep their own leading and trailing spaces as content). A double + quoted backslash at end of line now suppresses the break entirely (no space, no + newline). Completed the double quoted escape set with `\xXX` (2 hex digits) and + `\UXXXXXXXX` (8 hex digits), and added the previously missing `\0 \a \v \e`, + literal `\`, and the named breaks `\N \_ \L \P`, alongside the existing + `\uXXXX` (including surrogate pairs). This makes 30 additional official YAML + test suite cases pass: 3RLN/00, 3RLN/01, 3RLN/02, 3RLN/03, 3RLN/04, 3RLN/05, + 4ZYM, 565N, 5GBF, 6WPF, 7A4E, 8UDB, 9SA2, 9TFX, DE56/00, DE56/01, DE56/02, + DE56/03, DE56/04, DE56/05, DK95/02, DK95/08, G4RS, NAT4, NP9H, PRH3, Q8AD, + T4YY, TL85, and XV9V. ### Added diff --git a/Sources/Parsing/Scalar.swift b/Sources/Parsing/Scalar.swift index 8d83522..2823967 100644 --- a/Sources/Parsing/Scalar.swift +++ b/Sources/Parsing/Scalar.swift @@ -110,22 +110,8 @@ extension PureYAML.Parsing.Parser { guard text.count >= 2, text.last == "'" else { throw PureYAML.Parsing.ParseError.unterminatedQuotedString(line: line) } - let inner = text.dropFirst().dropLast() - var output = "" - var iterator = inner.makeIterator() - while let character = iterator.next() { - if character == "'", let next = iterator.next() { - if next == "'" { - output.append("'") - } else { - output.append(character) - output.append(next) - } - } else { - output.append(character) - } - } - return output + let inner = Array(text.dropFirst().dropLast()) + return foldFlowScalar(inner, single: true) } func parseDoubleQuoted( @@ -135,94 +121,238 @@ extension PureYAML.Parsing.Parser { guard text.count >= 2, text.last == "\"" else { throw PureYAML.Parsing.ParseError.unterminatedQuotedString(line: line) } - let inner = text.dropFirst().dropLast() + let inner = Array(text.dropFirst().dropLast()) + return foldFlowScalar(inner, single: false) + } + + /// Flow (quoted) scalar line folding, mirroring libyaml's + /// yaml_parser_scan_flow_scalar (single and double quoted). Trailing + /// whitespace before a break is dropped, leading whitespace on a + /// continuation line is dropped, a single break between non-empty lines + /// folds to one space, and N consecutive breaks yield N-1 line feeds. + /// For double quoted scalars a backslash at end of line suppresses the + /// break entirely. + func foldFlowScalar( + _ inner: [Character], + single: Bool, + ) -> String { + var state = FlowFoldState() + let count = inner.count + while state.index < count { + state.leadingBlanks = false + consumeFlowContent(inner, single: single, state: &state) + consumeFlowBlanks(inner, state: &state) + joinFlowFold(state: &state) + } + return state.output + } + + /// Mutable accumulators for flow scalar folding, matching the C reference's + /// string / leading_break / trailing_breaks / whitespaces buffers. + struct FlowFoldState { var output = "" - var index = inner.startIndex - while index < inner.endIndex { - let character = inner[index] - if character == "\\" { - inner.formIndex(after: &index) - guard index < inner.endIndex else { - output.append("\\") + var whitespaces = "" + var leadingBreak = "" + var trailingBreaks = "" + var leadingBlanks = false + var index = 0 + } + + /// Consume the run of non-blank characters at `state.index`, decoding + /// escapes. A double quoted backslash at end of line sets `leadingBlanks` + /// and stops, so the following break is suppressed during folding. + func consumeFlowContent( + _ inner: [Character], + single: Bool, + state: inout FlowFoldState, + ) { + let count = inner.count + while state.index < count, !isFlowBlank(inner[state.index]), !isFlowBreak(inner[state.index]) { + if single, inner[state.index] == "'" { + state.output.append("'") + let isEscapedQuote = state.index + 1 < count && inner[state.index + 1] == "'" + state.index += isEscapedQuote ? 2 : 1 + continue + } + if !single, inner[state.index] == "\\" { + if state.index + 1 < count, isFlowBreak(inner[state.index + 1]) { + state.index += 2 + state.leadingBlanks = true break } - appendDoubleQuotedEscape(in: inner, index: &index, to: &output) - } else { - output.append(character) - inner.formIndex(after: &index) + state.index += 1 + appendDoubleQuotedEscape(inner, index: &state.index, to: &state.output) + continue } + state.output.append(inner[state.index]) + state.index += 1 } - return output } - func appendDoubleQuotedEscape( - in text: Substring, - index: inout Substring.Index, - to output: inout String, + /// Consume the run of blanks and line breaks at `state.index`, sorting them + /// into the whitespace / leading-break / trailing-break buffers. + func consumeFlowBlanks( + _ inner: [Character], + state: inout FlowFoldState, ) { - let character = text[index] - switch character { - case "\"": output.append("\"") - case "\\": output.append("\\") - case "/": output.append("/") - case "b": output.append("\u{08}") - case "f": output.append("\u{0C}") - case "n": output.append("\n") - case "r": output.append("\r") - case "t": output.append("\t") - case "u": - appendUnicodeEscape(in: text, index: &index, to: &output) - default: output.append(character) + let count = inner.count + while state.index < count, isFlowBlank(inner[state.index]) || isFlowBreak(inner[state.index]) { + if isFlowBlank(inner[state.index]) { + if !state.leadingBlanks { + state.whitespaces.append(inner[state.index]) + } + } else if !state.leadingBlanks { + state.whitespaces = "" + state.leadingBreak = "\n" + state.leadingBlanks = true + } else { + state.trailingBreaks.append("\n") + } + state.index += 1 } - text.formIndex(after: &index) } - func appendUnicodeEscape( - in text: Substring, - index: inout Substring.Index, - to output: inout String, - ) { - let escapeStart = index - guard let codeUnit = readUnicodeEscapeCodeUnit(in: text, index: &index) else { - output.append("u") + /// Join the captured whitespace or fold the captured line breaks into the + /// output, per YAML 1.2 flow folding. + func joinFlowFold(state: inout FlowFoldState) { + guard state.leadingBlanks else { + state.output.append(state.whitespaces) + state.whitespaces = "" return } - let surrogatePair = readSurrogatePairIfNeeded(high: codeUnit, in: text, index: &index) - if let scalar = surrogatePair { + if state.leadingBreak.first == "\n" { + if state.trailingBreaks.isEmpty { + state.output.append(" ") + } else { + state.output.append(state.trailingBreaks) + state.trailingBreaks = "" + } + state.leadingBreak = "" + } else { + state.output.append(state.leadingBreak) + state.output.append(state.trailingBreaks) + state.leadingBreak = "" + state.trailingBreaks = "" + } + } + + func isFlowBlank(_ character: Character) -> Bool { + character == " " || character == "\t" + } + + func isFlowBreak(_ character: Character) -> Bool { + character == "\n" || character == "\r" || character == "\r\n" + } + + /// Decode a double quoted escape. On entry index points at the escape + /// character (the position just after the backslash). On return index has + /// advanced past every character the escape consumed. The escape set + /// mirrors libyaml's yaml_parser_scan_flow_scalar. + func appendDoubleQuotedEscape( + _ text: [Character], + index: inout Int, + to output: inout String, + ) { + guard index < text.count else { + output.append("\\") + return + } + let character = text[index] + if let simple = Self.simpleDoubleQuotedEscapes[character] { + output.append(simple) + index += 1 + return + } + switch character { + case "x": + index += 1 + appendHexEscape(text, index: &index, digits: 2, marker: "x", to: &output) + case "u": + index += 1 + appendUnicodeEscape(text, index: &index, to: &output) + case "U": + index += 1 + appendHexEscape(text, index: &index, digits: 8, marker: "U", to: &output) + default: + output.append(character) + index += 1 + } + } + + /// Single character double quoted escapes, matching libyaml's escape table. + static let simpleDoubleQuotedEscapes: [Character: Character] = [ + "0": "\u{00}", + "a": "\u{07}", + "b": "\u{08}", + "t": "\t", + "\t": "\t", + "n": "\n", + "v": "\u{0B}", + "f": "\u{0C}", + "r": "\r", + "e": "\u{1B}", + " ": " ", + "\"": "\"", + "/": "/", + "\\": "\\", + "N": "\u{85}", + "_": "\u{A0}", + "L": "\u{2028}", + "P": "\u{2029}", + ] + + /// Decode \xXX or \UXXXXXXXX. On entry index points at the first hex digit. + func appendHexEscape( + _ text: [Character], + index: inout Int, + digits: Int, + marker: Character, + to output: inout String, + ) { + guard let value = readHex(text, index: &index, digits: digits) else { + output.append(marker) + return + } + if let scalar = UnicodeScalar(value) { + output.unicodeScalars.append(scalar) + } else { + output.append(marker) + } + } + + /// Decode \uXXXX, including surrogate pairs. On entry index points at the + /// first hex digit. + func appendUnicodeEscape( + _ text: [Character], + index: inout Int, + to output: inout String, + ) { + let start = index + guard let codeUnit = readHex(text, index: &index, digits: 4) else { + output.append("u") + index = start + return + } + if isHighSurrogate(codeUnit), let scalar = readSurrogatePair(high: codeUnit, text: text, index: &index) { output.unicodeScalars.append(scalar) } else if let scalar = UnicodeScalar(codeUnit) { output.unicodeScalars.append(scalar) } else { - output += text[escapeStart ... index] + output.append("u") } } - func readSurrogatePairIfNeeded( - high: UInt32, - in text: Substring, - index: inout Substring.Index, - ) -> UnicodeScalar? { - guard isHighSurrogate(high) else { - return nil - } - return readSurrogatePair(high: high, in: text, index: &index) - } - func readSurrogatePair( high: UInt32, - in text: Substring, - index: inout Substring.Index, + text: [Character], + index: inout Int, ) -> UnicodeScalar? { var probe = index - text.formIndex(after: &probe) - guard probe < text.endIndex, text[probe] == "\\" else { + guard probe + 1 < text.count, text[probe] == "\\", text[probe + 1] == "u" else { return nil } - text.formIndex(after: &probe) - guard probe < text.endIndex, text[probe] == "u", - let low = readUnicodeEscapeCodeUnit(in: text, index: &probe), - isLowSurrogate(low) - else { + probe += 2 + guard let low = readHex(text, index: &probe, digits: 4), isLowSurrogate(low) else { return nil } index = probe @@ -230,22 +360,25 @@ extension PureYAML.Parsing.Parser { return UnicodeScalar(value) } - func readUnicodeEscapeCodeUnit( - in text: Substring, - index: inout Substring.Index, + /// Read exactly `digits` hex characters starting at index. On success index + /// advances past them, otherwise index is left unchanged. + func readHex( + _ text: [Character], + index: inout Int, + digits: Int, ) -> UInt32? { - var probe = index - text.formIndex(after: &probe) - var hex = "" - for _ in 0 ..< 4 { - guard probe < text.endIndex, text[probe].isHexDigit else { + guard index + digits <= text.count else { + return nil + } + var value: UInt32 = 0 + for offset in 0 ..< digits { + guard let digit = text[index + offset].hexDigitValue else { return nil } - hex.append(text[probe]) - text.formIndex(after: &probe) + value = (value << 4) + UInt32(digit) } - index = text.index(before: probe) - return UInt32(hex, radix: 16) + index += digits + return value } func isHighSurrogate(_ value: UInt32) -> Bool { diff --git a/Tests/Fixtures/yaml-test-suite-gaps.yaml b/Tests/Fixtures/yaml-test-suite-gaps.yaml index 13d19d7..b90af43 100644 --- a/Tests/Fixtures/yaml-test-suite-gaps.yaml +++ b/Tests/Fixtures/yaml-test-suite-gaps.yaml @@ -118,60 +118,6 @@ cases: current: accepted byteCount: 27 lineCount: 3 - - id: "3RLN/00" - name: "Leading tabs in double quoted" - localPath: yaml-test-suite/3RLN/00/in.yaml - category: json-mismatch - expected: parse-ok - oracle: json - current: value-mismatch - byteCount: 22 - lineCount: 2 - - id: "3RLN/01" - name: "Leading tabs in double quoted" - localPath: yaml-test-suite/3RLN/01/in.yaml - category: json-mismatch - expected: parse-ok - oracle: json - current: value-mismatch - byteCount: 22 - lineCount: 2 - - id: "3RLN/02" - name: "Leading tabs in double quoted" - localPath: yaml-test-suite/3RLN/02/in.yaml - category: json-mismatch - expected: parse-ok - oracle: json - current: value-mismatch - byteCount: 21 - lineCount: 2 - - id: "3RLN/03" - name: "Leading tabs in double quoted" - localPath: yaml-test-suite/3RLN/03/in.yaml - category: json-mismatch - expected: parse-ok - oracle: json - current: value-mismatch - byteCount: 24 - lineCount: 2 - - id: "3RLN/04" - name: "Leading tabs in double quoted" - localPath: yaml-test-suite/3RLN/04/in.yaml - category: json-mismatch - expected: parse-ok - oracle: json - current: value-mismatch - byteCount: 24 - lineCount: 2 - - id: "3RLN/05" - name: "Leading tabs in double quoted" - localPath: yaml-test-suite/3RLN/05/in.yaml - category: json-mismatch - expected: parse-ok - oracle: json - current: value-mismatch - byteCount: 23 - lineCount: 2 - id: "4CQQ" name: "Spec Example 2.18. Multi-line Flow Scalars" localPath: yaml-test-suite/4CQQ/in.yaml @@ -226,15 +172,6 @@ cases: current: value-mismatch byteCount: 35 lineCount: 4 - - id: "4ZYM" - name: "Spec Example 6.4. Line Prefixes" - localPath: yaml-test-suite/4ZYM/in.yaml - category: json-mismatch - expected: parse-ok - oracle: json - current: value-mismatch - byteCount: 70 - lineCount: 7 - id: "55WF" name: "Invalid escape in double quoted string" localPath: yaml-test-suite/55WF/in.yaml @@ -244,15 +181,6 @@ cases: current: accepted byteCount: 9 lineCount: 2 - - id: "565N" - name: "Construct Binary" - localPath: yaml-test-suite/565N/in.yaml - category: json-mismatch - expected: parse-ok - oracle: json - current: value-mismatch - byteCount: 636 - lineCount: 12 - id: "57H4" name: "Spec Example 8.22. Block Collection Nodes" localPath: yaml-test-suite/57H4/in.yaml @@ -262,15 +190,6 @@ cases: current: parse-error byteCount: 67 lineCount: 6 - - id: "5GBF" - name: "Spec Example 6.5. Empty Lines" - localPath: yaml-test-suite/5GBF/in.yaml - category: json-mismatch - expected: parse-ok - oracle: json - current: value-mismatch - byteCount: 83 - lineCount: 8 - id: "5TRB" name: "Invalid document-start marker in doublequoted tring" localPath: yaml-test-suite/5TRB/in.yaml @@ -388,15 +307,6 @@ cases: current: parse-error byteCount: 86 lineCount: 8 - - id: "6WPF" - name: "Spec Example 6.8. Flow Folding [1.3]" - localPath: yaml-test-suite/6WPF/in.yaml - category: json-mismatch - expected: parse-ok - oracle: json - current: value-mismatch - byteCount: 32 - lineCount: 8 - id: "6ZKB" name: "Spec Example 9.6. Stream" localPath: yaml-test-suite/6ZKB/in.yaml @@ -415,15 +325,6 @@ cases: current: parse-error byteCount: 62 lineCount: 5 - - id: "7A4E" - name: "Spec Example 7.6. Double Quoted Lines" - localPath: yaml-test-suite/7A4E/in.yaml - category: json-mismatch - expected: parse-ok - oracle: json - current: value-mismatch - byteCount: 50 - lineCount: 4 - id: "7LBH" name: "Multiline double quoted implicit keys" localPath: yaml-test-suite/7LBH/in.yaml @@ -487,15 +388,6 @@ cases: current: parse-error byteCount: 51 lineCount: 4 - - id: "8UDB" - name: "Spec Example 7.14. Flow Sequence Entries" - localPath: yaml-test-suite/8UDB/in.yaml - category: json-mismatch - expected: parse-ok - oracle: json - current: value-mismatch - byteCount: 89 - lineCount: 8 - id: "8XDJ" name: "Comment in plain multiline value" localPath: yaml-test-suite/8XDJ/in.yaml @@ -613,24 +505,6 @@ cases: current: parse-error byteCount: 15 lineCount: 3 - - id: "9SA2" - name: "Multiline double quoted flow mapping key" - localPath: yaml-test-suite/9SA2/in.yaml - category: json-mismatch - expected: parse-ok - oracle: json - current: value-mismatch - byteCount: 57 - lineCount: 4 - - id: "9TFX" - name: "Spec Example 7.6. Double Quoted Lines [1.3]" - localPath: yaml-test-suite/9TFX/in.yaml - category: json-mismatch - expected: parse-ok - oracle: json - current: value-mismatch - byteCount: 54 - lineCount: 5 - id: "9WXW" name: "Spec Example 6.18. Primary Tag Handle" localPath: yaml-test-suite/9WXW/in.yaml @@ -775,60 +649,6 @@ cases: current: parse-error byteCount: 26 lineCount: 4 - - id: "DE56/00" - name: "Trailing tabs in double quoted" - localPath: yaml-test-suite/DE56/00/in.yaml - category: json-mismatch - expected: parse-ok - oracle: json - current: value-mismatch - byteCount: 23 - lineCount: 2 - - id: "DE56/01" - name: "Trailing tabs in double quoted" - localPath: yaml-test-suite/DE56/01/in.yaml - category: json-mismatch - expected: parse-ok - oracle: json - current: value-mismatch - byteCount: 25 - lineCount: 2 - - id: "DE56/02" - name: "Trailing tabs in double quoted" - localPath: yaml-test-suite/DE56/02/in.yaml - category: json-mismatch - expected: parse-ok - oracle: json - current: value-mismatch - byteCount: 23 - lineCount: 2 - - id: "DE56/03" - name: "Trailing tabs in double quoted" - localPath: yaml-test-suite/DE56/03/in.yaml - category: json-mismatch - expected: parse-ok - oracle: json - current: value-mismatch - byteCount: 25 - lineCount: 2 - - id: "DE56/04" - name: "Trailing tabs in double quoted" - localPath: yaml-test-suite/DE56/04/in.yaml - category: json-mismatch - expected: parse-ok - oracle: json - current: value-mismatch - byteCount: 22 - lineCount: 2 - - id: "DE56/05" - name: "Trailing tabs in double quoted" - localPath: yaml-test-suite/DE56/05/in.yaml - category: json-mismatch - expected: parse-ok - oracle: json - current: value-mismatch - byteCount: 24 - lineCount: 2 - id: "DFF7" name: "Spec Example 7.16. Flow Mapping Entries" localPath: yaml-test-suite/DFF7/in.yaml @@ -856,24 +676,6 @@ cases: current: accepted byteCount: 16 lineCount: 2 - - id: "DK95/02" - name: "Tabs that look like indentation" - localPath: yaml-test-suite/DK95/02/in.yaml - category: json-mismatch - expected: parse-ok - oracle: json - current: value-mismatch - byteCount: 18 - lineCount: 2 - - id: "DK95/08" - name: "Tabs that look like indentation" - localPath: yaml-test-suite/DK95/08/in.yaml - category: json-mismatch - expected: parse-ok - oracle: json - current: value-mismatch - byteCount: 25 - lineCount: 2 - id: "E76Z" name: "Aliases in Implicit Block Mapping" localPath: yaml-test-suite/E76Z/in.yaml @@ -928,15 +730,6 @@ cases: current: parse-error byteCount: 24 lineCount: 4 - - id: "G4RS" - name: "Spec Example 2.17. Quoted Scalars" - localPath: yaml-test-suite/G4RS/in.yaml - category: json-mismatch - expected: parse-ok - oracle: json - current: value-mismatch - byteCount: 177 - lineCount: 7 - id: "G5U8" name: "Plain dashes in flow sequence" localPath: yaml-test-suite/G5U8/in.yaml @@ -1162,15 +955,6 @@ cases: current: parse-error byteCount: 15 lineCount: 2 - - id: "NAT4" - name: "Various empty or newline only quoted strings" - localPath: yaml-test-suite/NAT4/in.yaml - category: json-mismatch - expected: parse-ok - oracle: json - current: value-mismatch - byteCount: 86 - lineCount: 23 - id: "NB6Z" name: "Multiline plain value with tabs on empty lines" localPath: yaml-test-suite/NB6Z/in.yaml @@ -1207,15 +991,6 @@ cases: current: parse-error byteCount: 120 lineCount: 13 - - id: "NP9H" - name: "Spec Example 7.5. Double Quoted Line Breaks" - localPath: yaml-test-suite/NP9H/in.yaml - category: json-mismatch - expected: parse-ok - oracle: json - current: value-mismatch - byteCount: 63 - lineCount: 5 - id: "P2EQ" name: "Invalid sequene item on same line as previous item" localPath: yaml-test-suite/P2EQ/in.yaml @@ -1225,15 +1000,6 @@ cases: current: accepted byteCount: 24 lineCount: 2 - - id: "PRH3" - name: "Spec Example 7.9. Single Quoted Lines" - localPath: yaml-test-suite/PRH3/in.yaml - category: json-mismatch - expected: parse-ok - oracle: json - current: value-mismatch - byteCount: 50 - lineCount: 4 - id: "PW8X" name: "Anchors on Empty Scalars" localPath: yaml-test-suite/PW8X/in.yaml @@ -1243,15 +1009,6 @@ cases: current: parse-error byteCount: 65 lineCount: 12 - - id: "Q8AD" - name: "Spec Example 7.5. Double Quoted Line Breaks [1.3]" - localPath: yaml-test-suite/Q8AD/in.yaml - category: json-mismatch - expected: parse-ok - oracle: json - current: value-mismatch - byteCount: 66 - lineCount: 6 - id: "Q9WF" name: "Spec Example 6.12. Separation Spaces" localPath: yaml-test-suite/Q9WF/in.yaml @@ -1396,15 +1153,6 @@ cases: current: parse-error byteCount: 47 lineCount: 9 - - id: "T4YY" - name: "Spec Example 7.9. Single Quoted Lines [1.3]" - localPath: yaml-test-suite/T4YY/in.yaml - category: json-mismatch - expected: parse-ok - oracle: json - current: value-mismatch - byteCount: 54 - lineCount: 5 - id: "T5N4" name: "Spec Example 8.7. Literal Scalar [1.3]" localPath: yaml-test-suite/T5N4/in.yaml @@ -1414,15 +1162,6 @@ cases: current: value-mismatch byteCount: 24 lineCount: 5 - - id: "TL85" - name: "Spec Example 6.8. Flow Folding" - localPath: yaml-test-suite/TL85/in.yaml - category: json-mismatch - expected: parse-ok - oracle: json - current: value-mismatch - byteCount: 28 - lineCount: 7 - id: "UGM3" name: "Spec Example 2.27. Invoice" localPath: yaml-test-suite/UGM3/in.yaml @@ -1522,15 +1261,6 @@ cases: current: parse-error byteCount: 21 lineCount: 3 - - id: "XV9V" - name: "Spec Example 6.5. Empty Lines [1.3]" - localPath: yaml-test-suite/XV9V/in.yaml - category: json-mismatch - expected: parse-ok - oracle: json - current: value-mismatch - byteCount: 79 - lineCount: 8 - id: "XW4D" name: "Various Trailing Comments" localPath: yaml-test-suite/XW4D/in.yaml diff --git a/Tests/Fixtures/yaml-test-suite/3RLN/00/in.json b/Tests/Fixtures/yaml-test-suite/3RLN/00/in.json deleted file mode 100644 index 821166a..0000000 --- a/Tests/Fixtures/yaml-test-suite/3RLN/00/in.json +++ /dev/null @@ -1 +0,0 @@ -"1 leading \ttab" diff --git a/Tests/Fixtures/yaml-test-suite/3RLN/00/in.yaml b/Tests/Fixtures/yaml-test-suite/3RLN/00/in.yaml deleted file mode 100644 index a6a23a8..0000000 --- a/Tests/Fixtures/yaml-test-suite/3RLN/00/in.yaml +++ /dev/null @@ -1,2 +0,0 @@ -"1 leading - \ttab" diff --git a/Tests/Fixtures/yaml-test-suite/3RLN/01/in.json b/Tests/Fixtures/yaml-test-suite/3RLN/01/in.json deleted file mode 100644 index 29133b1..0000000 --- a/Tests/Fixtures/yaml-test-suite/3RLN/01/in.json +++ /dev/null @@ -1 +0,0 @@ -"2 leading \ttab" diff --git a/Tests/Fixtures/yaml-test-suite/3RLN/01/in.yaml b/Tests/Fixtures/yaml-test-suite/3RLN/01/in.yaml deleted file mode 100644 index 64057a8..0000000 --- a/Tests/Fixtures/yaml-test-suite/3RLN/01/in.yaml +++ /dev/null @@ -1,2 +0,0 @@ -"2 leading - \ tab" diff --git a/Tests/Fixtures/yaml-test-suite/3RLN/02/in.json b/Tests/Fixtures/yaml-test-suite/3RLN/02/in.json deleted file mode 100644 index 9f23c05..0000000 --- a/Tests/Fixtures/yaml-test-suite/3RLN/02/in.json +++ /dev/null @@ -1 +0,0 @@ -"3 leading tab" diff --git a/Tests/Fixtures/yaml-test-suite/3RLN/02/in.yaml b/Tests/Fixtures/yaml-test-suite/3RLN/02/in.yaml deleted file mode 100644 index 3b18adc..0000000 --- a/Tests/Fixtures/yaml-test-suite/3RLN/02/in.yaml +++ /dev/null @@ -1,2 +0,0 @@ -"3 leading - tab" diff --git a/Tests/Fixtures/yaml-test-suite/3RLN/03/in.json b/Tests/Fixtures/yaml-test-suite/3RLN/03/in.json deleted file mode 100644 index 75b57d9..0000000 --- a/Tests/Fixtures/yaml-test-suite/3RLN/03/in.json +++ /dev/null @@ -1 +0,0 @@ -"4 leading \t tab" diff --git a/Tests/Fixtures/yaml-test-suite/3RLN/03/in.yaml b/Tests/Fixtures/yaml-test-suite/3RLN/03/in.yaml deleted file mode 100644 index 815c713..0000000 --- a/Tests/Fixtures/yaml-test-suite/3RLN/03/in.yaml +++ /dev/null @@ -1,2 +0,0 @@ -"4 leading - \t tab" diff --git a/Tests/Fixtures/yaml-test-suite/3RLN/04/in.json b/Tests/Fixtures/yaml-test-suite/3RLN/04/in.json deleted file mode 100644 index f73076a..0000000 --- a/Tests/Fixtures/yaml-test-suite/3RLN/04/in.json +++ /dev/null @@ -1 +0,0 @@ -"5 leading \t tab" diff --git a/Tests/Fixtures/yaml-test-suite/3RLN/04/in.yaml b/Tests/Fixtures/yaml-test-suite/3RLN/04/in.yaml deleted file mode 100644 index 07e14f5..0000000 --- a/Tests/Fixtures/yaml-test-suite/3RLN/04/in.yaml +++ /dev/null @@ -1,2 +0,0 @@ -"5 leading - \ tab" diff --git a/Tests/Fixtures/yaml-test-suite/3RLN/05/in.json b/Tests/Fixtures/yaml-test-suite/3RLN/05/in.json deleted file mode 100644 index 46d1f8c..0000000 --- a/Tests/Fixtures/yaml-test-suite/3RLN/05/in.json +++ /dev/null @@ -1 +0,0 @@ -"6 leading tab" diff --git a/Tests/Fixtures/yaml-test-suite/3RLN/05/in.yaml b/Tests/Fixtures/yaml-test-suite/3RLN/05/in.yaml deleted file mode 100644 index 75222d3..0000000 --- a/Tests/Fixtures/yaml-test-suite/3RLN/05/in.yaml +++ /dev/null @@ -1,2 +0,0 @@ -"6 leading - tab" diff --git a/Tests/Fixtures/yaml-test-suite/4ZYM/in.json b/Tests/Fixtures/yaml-test-suite/4ZYM/in.json deleted file mode 100644 index b90f107..0000000 --- a/Tests/Fixtures/yaml-test-suite/4ZYM/in.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "plain": "text lines", - "quoted": "text lines", - "block": "text\n \tlines\n" -} diff --git a/Tests/Fixtures/yaml-test-suite/4ZYM/in.yaml b/Tests/Fixtures/yaml-test-suite/4ZYM/in.yaml deleted file mode 100644 index 2f62d08..0000000 --- a/Tests/Fixtures/yaml-test-suite/4ZYM/in.yaml +++ /dev/null @@ -1,7 +0,0 @@ -plain: text - lines -quoted: "text - lines" -block: | - text - lines diff --git a/Tests/Fixtures/yaml-test-suite/565N/in.json b/Tests/Fixtures/yaml-test-suite/565N/in.json deleted file mode 100644 index 4b6d817..0000000 --- a/Tests/Fixtures/yaml-test-suite/565N/in.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "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." -} diff --git a/Tests/Fixtures/yaml-test-suite/565N/in.yaml b/Tests/Fixtures/yaml-test-suite/565N/in.yaml deleted file mode 100644 index dcdb16f..0000000 --- a/Tests/Fixtures/yaml-test-suite/565N/in.yaml +++ /dev/null @@ -1,12 +0,0 @@ -canonical: !!binary "\ - R0lGODlhDAAMAIQAAP//9/X17unp5WZmZgAAAOfn515eXvPz7Y6OjuDg4J+fn5\ - OTk6enp56enmlpaWNjY6Ojo4SEhP/++f/++f/++f/++f/++f/++f/++f/++f/+\ - +f/++f/++f/++f/++f/++SH+Dk1hZGUgd2l0aCBHSU1QACwAAAAADAAMAAAFLC\ - AgjoEwnuNAFOhpEMTRiggcz4BNJHrv/zCFcLiwMWYNG84BwwEeECcgggoBADs=" -generic: !!binary | - R0lGODlhDAAMAIQAAP//9/X17unp5WZmZgAAAOfn515eXvPz7Y6OjuDg4J+fn5 - OTk6enp56enmlpaWNjY6Ojo4SEhP/++f/++f/++f/++f/++f/++f/++f/++f/+ - +f/++f/++f/++f/++f/++SH+Dk1hZGUgd2l0aCBHSU1QACwAAAAADAAMAAAFLC - AgjoEwnuNAFOhpEMTRiggcz4BNJHrv/zCFcLiwMWYNG84BwwEeECcgggoBADs= -description: - The binary value above is a tiny arrow encoded as a gif image. diff --git a/Tests/Fixtures/yaml-test-suite/5GBF/in.json b/Tests/Fixtures/yaml-test-suite/5GBF/in.json deleted file mode 100644 index 41a96a1..0000000 --- a/Tests/Fixtures/yaml-test-suite/5GBF/in.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "Folding": "Empty line\nas a line feed", - "Chomping": "Clipped empty lines\n" -} diff --git a/Tests/Fixtures/yaml-test-suite/5GBF/in.yaml b/Tests/Fixtures/yaml-test-suite/5GBF/in.yaml deleted file mode 100644 index 60958d5..0000000 --- a/Tests/Fixtures/yaml-test-suite/5GBF/in.yaml +++ /dev/null @@ -1,8 +0,0 @@ -Folding: - "Empty line - - as a line feed" -Chomping: | - Clipped empty lines - - diff --git a/Tests/Fixtures/yaml-test-suite/6WPF/in.json b/Tests/Fixtures/yaml-test-suite/6WPF/in.json deleted file mode 100644 index 0fcc9db..0000000 --- a/Tests/Fixtures/yaml-test-suite/6WPF/in.json +++ /dev/null @@ -1 +0,0 @@ -" foo\nbar\nbaz " diff --git a/Tests/Fixtures/yaml-test-suite/6WPF/in.yaml b/Tests/Fixtures/yaml-test-suite/6WPF/in.yaml deleted file mode 100644 index aed6e4b..0000000 --- a/Tests/Fixtures/yaml-test-suite/6WPF/in.yaml +++ /dev/null @@ -1,8 +0,0 @@ ---- -" - foo - - bar - - baz -" diff --git a/Tests/Fixtures/yaml-test-suite/7A4E/in.json b/Tests/Fixtures/yaml-test-suite/7A4E/in.json deleted file mode 100644 index 2dfab84..0000000 --- a/Tests/Fixtures/yaml-test-suite/7A4E/in.json +++ /dev/null @@ -1 +0,0 @@ -" 1st non-empty\n2nd non-empty 3rd non-empty " diff --git a/Tests/Fixtures/yaml-test-suite/7A4E/in.yaml b/Tests/Fixtures/yaml-test-suite/7A4E/in.yaml deleted file mode 100644 index 3d8b76d..0000000 --- a/Tests/Fixtures/yaml-test-suite/7A4E/in.yaml +++ /dev/null @@ -1,4 +0,0 @@ -" 1st non-empty - - 2nd non-empty - 3rd non-empty " diff --git a/Tests/Fixtures/yaml-test-suite/8UDB/in.json b/Tests/Fixtures/yaml-test-suite/8UDB/in.json deleted file mode 100644 index 763236f..0000000 --- a/Tests/Fixtures/yaml-test-suite/8UDB/in.json +++ /dev/null @@ -1,11 +0,0 @@ -[ - "double quoted", - "single quoted", - "plain text", - [ - "nested" - ], - { - "single": "pair" - } -] diff --git a/Tests/Fixtures/yaml-test-suite/8UDB/in.yaml b/Tests/Fixtures/yaml-test-suite/8UDB/in.yaml deleted file mode 100644 index 6327116..0000000 --- a/Tests/Fixtures/yaml-test-suite/8UDB/in.yaml +++ /dev/null @@ -1,8 +0,0 @@ -[ -"double - quoted", 'single - quoted', -plain - text, [ nested ], -single: pair, -] diff --git a/Tests/Fixtures/yaml-test-suite/9SA2/in.json b/Tests/Fixtures/yaml-test-suite/9SA2/in.json deleted file mode 100644 index d214d88..0000000 --- a/Tests/Fixtures/yaml-test-suite/9SA2/in.json +++ /dev/null @@ -1,8 +0,0 @@ -[ - { - "single line": "value" - }, - { - "multi line": "value" - } -] diff --git a/Tests/Fixtures/yaml-test-suite/9SA2/in.yaml b/Tests/Fixtures/yaml-test-suite/9SA2/in.yaml deleted file mode 100644 index b79124b..0000000 --- a/Tests/Fixtures/yaml-test-suite/9SA2/in.yaml +++ /dev/null @@ -1,4 +0,0 @@ ---- -- { "single line": value} -- { "multi - line": value} diff --git a/Tests/Fixtures/yaml-test-suite/9TFX/in.json b/Tests/Fixtures/yaml-test-suite/9TFX/in.json deleted file mode 100644 index 2dfab84..0000000 --- a/Tests/Fixtures/yaml-test-suite/9TFX/in.json +++ /dev/null @@ -1 +0,0 @@ -" 1st non-empty\n2nd non-empty 3rd non-empty " diff --git a/Tests/Fixtures/yaml-test-suite/9TFX/in.yaml b/Tests/Fixtures/yaml-test-suite/9TFX/in.yaml deleted file mode 100644 index 5afb3f4..0000000 --- a/Tests/Fixtures/yaml-test-suite/9TFX/in.yaml +++ /dev/null @@ -1,5 +0,0 @@ ---- -" 1st non-empty - - 2nd non-empty - 3rd non-empty " diff --git a/Tests/Fixtures/yaml-test-suite/DE56/00/in.json b/Tests/Fixtures/yaml-test-suite/DE56/00/in.json deleted file mode 100644 index 03179cd..0000000 --- a/Tests/Fixtures/yaml-test-suite/DE56/00/in.json +++ /dev/null @@ -1 +0,0 @@ -"1 trailing\t tab" diff --git a/Tests/Fixtures/yaml-test-suite/DE56/00/in.yaml b/Tests/Fixtures/yaml-test-suite/DE56/00/in.yaml deleted file mode 100644 index a235094..0000000 --- a/Tests/Fixtures/yaml-test-suite/DE56/00/in.yaml +++ /dev/null @@ -1,2 +0,0 @@ -"1 trailing\t - tab" diff --git a/Tests/Fixtures/yaml-test-suite/DE56/01/in.json b/Tests/Fixtures/yaml-test-suite/DE56/01/in.json deleted file mode 100644 index ade6481..0000000 --- a/Tests/Fixtures/yaml-test-suite/DE56/01/in.json +++ /dev/null @@ -1 +0,0 @@ -"2 trailing\t tab" diff --git a/Tests/Fixtures/yaml-test-suite/DE56/01/in.yaml b/Tests/Fixtures/yaml-test-suite/DE56/01/in.yaml deleted file mode 100644 index 006f12a..0000000 --- a/Tests/Fixtures/yaml-test-suite/DE56/01/in.yaml +++ /dev/null @@ -1,2 +0,0 @@ -"2 trailing\t - tab" diff --git a/Tests/Fixtures/yaml-test-suite/DE56/02/in.json b/Tests/Fixtures/yaml-test-suite/DE56/02/in.json deleted file mode 100644 index 611058e..0000000 --- a/Tests/Fixtures/yaml-test-suite/DE56/02/in.json +++ /dev/null @@ -1 +0,0 @@ -"3 trailing\t tab" diff --git a/Tests/Fixtures/yaml-test-suite/DE56/02/in.yaml b/Tests/Fixtures/yaml-test-suite/DE56/02/in.yaml deleted file mode 100644 index b06a045..0000000 --- a/Tests/Fixtures/yaml-test-suite/DE56/02/in.yaml +++ /dev/null @@ -1,2 +0,0 @@ -"3 trailing\ - tab" diff --git a/Tests/Fixtures/yaml-test-suite/DE56/03/in.json b/Tests/Fixtures/yaml-test-suite/DE56/03/in.json deleted file mode 100644 index 388f4e4..0000000 --- a/Tests/Fixtures/yaml-test-suite/DE56/03/in.json +++ /dev/null @@ -1 +0,0 @@ -"4 trailing\t tab" diff --git a/Tests/Fixtures/yaml-test-suite/DE56/03/in.yaml b/Tests/Fixtures/yaml-test-suite/DE56/03/in.yaml deleted file mode 100644 index 13694b0..0000000 --- a/Tests/Fixtures/yaml-test-suite/DE56/03/in.yaml +++ /dev/null @@ -1,2 +0,0 @@ -"4 trailing\ - tab" diff --git a/Tests/Fixtures/yaml-test-suite/DE56/04/in.json b/Tests/Fixtures/yaml-test-suite/DE56/04/in.json deleted file mode 100644 index c83327d..0000000 --- a/Tests/Fixtures/yaml-test-suite/DE56/04/in.json +++ /dev/null @@ -1 +0,0 @@ -"5 trailing tab" diff --git a/Tests/Fixtures/yaml-test-suite/DE56/04/in.yaml b/Tests/Fixtures/yaml-test-suite/DE56/04/in.yaml deleted file mode 100644 index 5f8ff1c..0000000 --- a/Tests/Fixtures/yaml-test-suite/DE56/04/in.yaml +++ /dev/null @@ -1,2 +0,0 @@ -"5 trailing - tab" diff --git a/Tests/Fixtures/yaml-test-suite/DE56/05/in.json b/Tests/Fixtures/yaml-test-suite/DE56/05/in.json deleted file mode 100644 index 56138d1..0000000 --- a/Tests/Fixtures/yaml-test-suite/DE56/05/in.json +++ /dev/null @@ -1 +0,0 @@ -"6 trailing tab" diff --git a/Tests/Fixtures/yaml-test-suite/DE56/05/in.yaml b/Tests/Fixtures/yaml-test-suite/DE56/05/in.yaml deleted file mode 100644 index f25a33a..0000000 --- a/Tests/Fixtures/yaml-test-suite/DE56/05/in.yaml +++ /dev/null @@ -1,2 +0,0 @@ -"6 trailing - tab" diff --git a/Tests/Fixtures/yaml-test-suite/DK95/02/in.json b/Tests/Fixtures/yaml-test-suite/DK95/02/in.json deleted file mode 100644 index f86c8d6..0000000 --- a/Tests/Fixtures/yaml-test-suite/DK95/02/in.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "foo" : "bar baz" -} diff --git a/Tests/Fixtures/yaml-test-suite/DK95/02/in.yaml b/Tests/Fixtures/yaml-test-suite/DK95/02/in.yaml deleted file mode 100644 index 422933c..0000000 --- a/Tests/Fixtures/yaml-test-suite/DK95/02/in.yaml +++ /dev/null @@ -1,2 +0,0 @@ -foo: "bar - baz" diff --git a/Tests/Fixtures/yaml-test-suite/DK95/08/in.json b/Tests/Fixtures/yaml-test-suite/DK95/08/in.json deleted file mode 100644 index 0dc83aa..0000000 --- a/Tests/Fixtures/yaml-test-suite/DK95/08/in.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "foo" : "bar baz \t \t " -} diff --git a/Tests/Fixtures/yaml-test-suite/DK95/08/in.yaml b/Tests/Fixtures/yaml-test-suite/DK95/08/in.yaml deleted file mode 100644 index 1ae7eca..0000000 --- a/Tests/Fixtures/yaml-test-suite/DK95/08/in.yaml +++ /dev/null @@ -1,2 +0,0 @@ -foo: "bar - baz " diff --git a/Tests/Fixtures/yaml-test-suite/G4RS/in.json b/Tests/Fixtures/yaml-test-suite/G4RS/in.json deleted file mode 100644 index 9b2b73a..0000000 --- a/Tests/Fixtures/yaml-test-suite/G4RS/in.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "unicode": "Sosa did fine.☺", - "control": "\b1998\t1999\t2000\n", - "hex esc": "\r\n is \r\n", - "single": "\"Howdy!\" he cried.", - "quoted": " # Not a 'comment'.", - "tie-fighter": "|\\-*-/|" -} diff --git a/Tests/Fixtures/yaml-test-suite/G4RS/in.yaml b/Tests/Fixtures/yaml-test-suite/G4RS/in.yaml deleted file mode 100644 index c5c2a18..0000000 --- a/Tests/Fixtures/yaml-test-suite/G4RS/in.yaml +++ /dev/null @@ -1,7 +0,0 @@ -unicode: "Sosa did fine.\u263A" -control: "\b1998\t1999\t2000\n" -hex esc: "\x0d\x0a is \r\n" - -single: '"Howdy!" he cried.' -quoted: ' # Not a ''comment''.' -tie-fighter: '|\-*-/|' diff --git a/Tests/Fixtures/yaml-test-suite/NAT4/in.json b/Tests/Fixtures/yaml-test-suite/NAT4/in.json deleted file mode 100644 index f2cc7e8..0000000 --- a/Tests/Fixtures/yaml-test-suite/NAT4/in.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "a": " ", - "b": " ", - "c": " ", - "d": " ", - "e": "\n", - "f": "\n", - "g": "\n\n", - "h": "\n\n" -} diff --git a/Tests/Fixtures/yaml-test-suite/NAT4/in.yaml b/Tests/Fixtures/yaml-test-suite/NAT4/in.yaml deleted file mode 100644 index 10d58e2..0000000 --- a/Tests/Fixtures/yaml-test-suite/NAT4/in.yaml +++ /dev/null @@ -1,23 +0,0 @@ ---- -a: ' - ' -b: ' - ' -c: " - " -d: " - " -e: ' - - ' -f: " - - " -g: ' - - - ' -h: " - - - " diff --git a/Tests/Fixtures/yaml-test-suite/NP9H/in.json b/Tests/Fixtures/yaml-test-suite/NP9H/in.json deleted file mode 100644 index 6ab3718..0000000 --- a/Tests/Fixtures/yaml-test-suite/NP9H/in.json +++ /dev/null @@ -1 +0,0 @@ -"folded to a space,\nto a line feed, or \t \tnon-content" diff --git a/Tests/Fixtures/yaml-test-suite/NP9H/in.yaml b/Tests/Fixtures/yaml-test-suite/NP9H/in.yaml deleted file mode 100644 index eda4b49..0000000 --- a/Tests/Fixtures/yaml-test-suite/NP9H/in.yaml +++ /dev/null @@ -1,5 +0,0 @@ -"folded -to a space, - -to a line feed, or \ - \ non-content" diff --git a/Tests/Fixtures/yaml-test-suite/PRH3/in.json b/Tests/Fixtures/yaml-test-suite/PRH3/in.json deleted file mode 100644 index 2dfab84..0000000 --- a/Tests/Fixtures/yaml-test-suite/PRH3/in.json +++ /dev/null @@ -1 +0,0 @@ -" 1st non-empty\n2nd non-empty 3rd non-empty " diff --git a/Tests/Fixtures/yaml-test-suite/PRH3/in.yaml b/Tests/Fixtures/yaml-test-suite/PRH3/in.yaml deleted file mode 100644 index 6dd946e..0000000 --- a/Tests/Fixtures/yaml-test-suite/PRH3/in.yaml +++ /dev/null @@ -1,4 +0,0 @@ -' 1st non-empty - - 2nd non-empty - 3rd non-empty ' diff --git a/Tests/Fixtures/yaml-test-suite/Q8AD/in.json b/Tests/Fixtures/yaml-test-suite/Q8AD/in.json deleted file mode 100644 index 6ab3718..0000000 --- a/Tests/Fixtures/yaml-test-suite/Q8AD/in.json +++ /dev/null @@ -1 +0,0 @@ -"folded to a space,\nto a line feed, or \t \tnon-content" diff --git a/Tests/Fixtures/yaml-test-suite/Q8AD/in.yaml b/Tests/Fixtures/yaml-test-suite/Q8AD/in.yaml deleted file mode 100644 index bf14c53..0000000 --- a/Tests/Fixtures/yaml-test-suite/Q8AD/in.yaml +++ /dev/null @@ -1,6 +0,0 @@ ---- -"folded -to a space, - -to a line feed, or \ - \ non-content" diff --git a/Tests/Fixtures/yaml-test-suite/T4YY/in.json b/Tests/Fixtures/yaml-test-suite/T4YY/in.json deleted file mode 100644 index 2dfab84..0000000 --- a/Tests/Fixtures/yaml-test-suite/T4YY/in.json +++ /dev/null @@ -1 +0,0 @@ -" 1st non-empty\n2nd non-empty 3rd non-empty " diff --git a/Tests/Fixtures/yaml-test-suite/T4YY/in.yaml b/Tests/Fixtures/yaml-test-suite/T4YY/in.yaml deleted file mode 100644 index 6cba7f1..0000000 --- a/Tests/Fixtures/yaml-test-suite/T4YY/in.yaml +++ /dev/null @@ -1,5 +0,0 @@ ---- -' 1st non-empty - - 2nd non-empty - 3rd non-empty ' diff --git a/Tests/Fixtures/yaml-test-suite/TL85/in.json b/Tests/Fixtures/yaml-test-suite/TL85/in.json deleted file mode 100644 index 0fcc9db..0000000 --- a/Tests/Fixtures/yaml-test-suite/TL85/in.json +++ /dev/null @@ -1 +0,0 @@ -" foo\nbar\nbaz " diff --git a/Tests/Fixtures/yaml-test-suite/TL85/in.yaml b/Tests/Fixtures/yaml-test-suite/TL85/in.yaml deleted file mode 100644 index d6af812..0000000 --- a/Tests/Fixtures/yaml-test-suite/TL85/in.yaml +++ /dev/null @@ -1,7 +0,0 @@ -" - foo - - bar - - baz -" diff --git a/Tests/Fixtures/yaml-test-suite/XV9V/in.json b/Tests/Fixtures/yaml-test-suite/XV9V/in.json deleted file mode 100644 index 41a96a1..0000000 --- a/Tests/Fixtures/yaml-test-suite/XV9V/in.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "Folding": "Empty line\nas a line feed", - "Chomping": "Clipped empty lines\n" -} diff --git a/Tests/Fixtures/yaml-test-suite/XV9V/in.yaml b/Tests/Fixtures/yaml-test-suite/XV9V/in.yaml deleted file mode 100644 index c7775c4..0000000 --- a/Tests/Fixtures/yaml-test-suite/XV9V/in.yaml +++ /dev/null @@ -1,8 +0,0 @@ -Folding: - "Empty line - - as a line feed" -Chomping: | - Clipped empty lines - - diff --git a/Tests/YAMLTestSuiteGapsTests.swift b/Tests/YAMLTestSuiteGapsTests.swift index a1c8cc0..20dc0e0 100644 --- a/Tests/YAMLTestSuiteGapsTests.swift +++ b/Tests/YAMLTestSuiteGapsTests.swift @@ -18,9 +18,9 @@ struct YAMLTestSuiteGapsTests { let manifest = try YAMLTestSuiteManifest.load() #expect(manifest.version == 1) - #expect(manifest.cases.count == 182) + #expect(manifest.cases.count == 152) #expect(manifest.cases.count(where: { $0.category == "false-reject" }) == 84) - #expect(manifest.cases.count(where: { $0.category == "json-mismatch" }) == 46) + #expect(manifest.cases.count(where: { $0.category == "json-mismatch" }) == 16) #expect(manifest.cases.count(where: { $0.category == "accepted-invalid" }) == 52) #expect(Set(manifest.cases.map(\.id)).count == manifest.cases.count) diff --git a/docs/YAML_TEST_SUITE_CONFORMANCE.md b/docs/YAML_TEST_SUITE_CONFORMANCE.md index b389cd3..4719522 100644 --- a/docs/YAML_TEST_SUITE_CONFORMANCE.md +++ b/docs/YAML_TEST_SUITE_CONFORMANCE.md @@ -3,7 +3,7 @@ This document tracks PureYAML against the official [YAML test suite](https://github.com/yaml/yaml-test-suite) and lays out the ordered plan for closing the gaps. It is a living document: bucket 1 (block -scalars) has landed; buckets 2-6 remain. +scalars) and bucket 2 (quoted-scalar folding) have landed; buckets 3-6 remain. ## How conformance is measured @@ -19,7 +19,8 @@ its own oracle: ### Result at the pinned commit 402 cases (including numbered sub-cases). First measurement was 196 pass / 206 -fail; after bucket 1 (block scalars) it is now **220 pass, 182 fail.** The 182 +fail; after bucket 1 (block scalars, +24) and bucket 2 (quoted-scalar folding, ++30) it is now **250 pass, 152 fail.** The 152 remaining failing cases are vendored under `Tests/Fixtures/yaml-test-suite/` and recorded in `Tests/Fixtures/yaml-test-suite-gaps.yaml`. Run the opt-in sweep with: @@ -38,7 +39,7 @@ updated, the deliberate forcing function for keeping this document honest. | Category | Count | Meaning | |---|---|---| | `false-reject` | 84 | Well-formed YAML that PureYAML wrongly rejects at parse time. | -| `json-mismatch` | 46 | Parses, but produces a value that disagrees with the expected JSON. | +| `json-mismatch` | 16 | Parses, but produces a value that disagrees with the expected JSON. | | `accepted-invalid` | 52 | Malformed YAML that PureYAML wrongly accepts. | ## Root-cause buckets and fix order @@ -65,14 +66,26 @@ Flipped 24 cases to passing: `4QFQ`, `5LLU`, `6VJK`, `7T8X`, `96NN/00`, `96NN/01 (`T5N4` looks like a block-scalar case but is blocked by document-start handling, bucket 5.) -### 2. Quoted-scalar line breaks and empty-line folding (subset of `json-mismatch`) +### 2. Quoted-scalar line breaks and empty-line folding (DONE) -Double- and single-quoted multi-line scalars fold line breaks and collapse blank -lines incorrectly. Examples: `NP9H`, `Q8AD`, `PRH3`, `T4YY`, `TL85`, `NAT4`. +Single (`'`) and double (`"`) quoted multi-line scalars now apply YAML 1.2 flow +folding (§6.5, §7.3.1, §7.3.2): trailing whitespace before a break is stripped, +leading whitespace on a continuation line is stripped, a single break between +non-empty lines folds to one space, and N consecutive breaks yield N-1 literal +line feeds (the first and last lines keep their own leading and trailing spaces as +content). A double quoted backslash at end of line suppresses the break entirely. +The double quoted escape set is completed with `\xXX` and `\UXXXXXXXX`, plus the +previously missing `\0 \a \v \e`, literal `\`, and named breaks +`\N \_ \L \P` (the existing `\uXXXX` surrogate-pair handling is kept). The folding +state machine mirrors `scanner.c` `yaml_parser_scan_flow_scalar`; implemented in +`Sources/Parsing/Scalar.swift` (`foldFlowScalar` and the escape decoder). -- **Reference:** `scanner.c` `yaml_parser_scan_flow_scalar` (line-join, leading/ - trailing whitespace, escape handling). -- **Why second:** same scanner area as bucket 1, shares the line-folding helper. +Flipped 30 cases to passing: `3RLN/00`, `3RLN/01`, `3RLN/02`, `3RLN/03`, +`3RLN/04`, `3RLN/05`, `4ZYM`, `565N`, `5GBF`, `6WPF`, `7A4E`, `8UDB`, `9SA2`, +`9TFX`, `DE56/00`, `DE56/01`, `DE56/02`, `DE56/03`, `DE56/04`, `DE56/05`, +`DK95/02`, `DK95/08`, `G4RS`, `NAT4`, `NP9H`, `PRH3`, `Q8AD`, `T4YY`, `TL85`, +`XV9V`. (`DK95/01` looks similar but is blocked by tab-as-indentation handling, +bucket 6.) ### 3. Empty nodes and empty keys (≈15 cases, `false-reject`)