PureYAML/Tests/YAMLDirectiveTests.swift
Mihaela M 7879818ce5 fix(parsing): accept a higher-minor %YAML version
The %YAML version check accepted only 1.1 and 1.2, rejecting anything else,
so `%YAML 1.3` errored. The spec calls for processing a document whose minor
version is higher than the processor's, with a warning, rather than refusing
it: only a different major version is incompatible.

Accept any well-formed `1.minor` version and reject only a different major
(`2.0`) or a malformed version. Three tests that asserted `%YAML 1.3` was an
error are corrected to use `2.0`, the genuinely incompatible case, and a test
covers that 1.3 now parses.

Raises yaml-test-suite parse-level conformance to 305/333 (91.6%) with the
value-level (100%) and should-error rejection rates unchanged. 486 tests pass.
2026-06-29 02:34:55 +02:00

46 lines
1.9 KiB
Swift

@testable import PureYAML
import Testing
@Suite("%YAML directive validation")
struct YAMLDirectiveTests {
@Test("A malformed or repeated %YAML directive is rejected", arguments: [
"%YAML 1.2 foo\n---\nx\n", // an extra parameter after the version
"%YAML 1.2\n%YAML 1.2\n---\nx\n", // a second %YAML directive
"%YAML 2.0\n---\nx\n", // an incompatible major version
])
func test_invalidYAMLDirectiveIsRejected(_ yaml: String) throws {
#expect(throws: PureYAML.Parsing.ParseError.self) {
try PureYAML.parse(yaml)
}
}
@Test("A higher minor version is accepted, since the spec calls for processing it with a warning")
func test_higherMinorVersionAccepted() throws {
#expect(try PureYAML.parse("%YAML 1.3\n---\nx\n") == .string("x"))
}
@Test("A well-formed %YAML directive, with an optional trailing comment, is accepted")
func test_validYAMLDirectiveAccepted() throws {
let expected = PureYAML.Model.Value.string("x")
#expect(try PureYAML.parse("%YAML 1.2\n---\nx\n") == expected)
#expect(try PureYAML.parse("%YAML 1.2 # version\n---\nx\n") == expected)
}
@Test("A directive with no following document is rejected", arguments: [
"%YAML 1.2\n", // directive then end of stream
"%YAML 1.2\n...\n", // directive then a document-end marker
"%TAG !e! tag:example,0:\n", // any directive, not just %YAML
])
func test_directiveWithoutDocumentRejected(_ yaml: String) throws {
#expect(throws: PureYAML.Parsing.ParseError.self) {
try PureYAML.parse(yaml)
}
}
@Test("A directive followed by an explicit document start is accepted")
func test_directiveWithDocumentAccepted() throws {
#expect(try PureYAML.parse("%YAML 1.2\n---\n") == .null)
#expect(try PureYAML.parse("%TAG !e! tag:example,0:\n---\nx\n") == .string("x"))
}
}