PureYAML/Tests/ValidationTestSupport.swift
Mihaela M d195dd3fa1 refactor(validation): retire the legacy Rule for one check type
A Rule was exactly a Check<Model.Value, Model.Value>: it fired on every
node, switched on the value itself, and carried the root. It was therefore a
second copy of the one check machinery, the duplication the validation idiom
exists to prevent (principle 10), now also resolved for the tagged layer.

Remove Rule and its Context. The model validator holds only checks; its
default is the type-directed BuiltinCheck.mappingKeysAreUnique; validating
takes a Check. Custom whole-tree rules become Check<Model.Value, Model.Value>
with the former context.root now context.document.

Behaviour is byte-identical: the mapping-key builtin reports the same issues
at the same paths in the same DFS order, so the public validate/collect/blank
surface is unchanged. All 399 tests pass; the coverage gate reconciles to 60
public types.
2026-06-28 16:43:31 +02:00

76 lines
2.1 KiB
Swift

@testable import PureYAML
import Testing
struct ValidationValidDocumentCase: CustomStringConvertible {
var name: String
var yaml: String
var description: String {
name
}
}
struct ValidationDuplicateKeyCase: CustomStringConvertible {
var name: String
var yaml: String
var expectedIssues: [PureYAML.Validation.Issue]
var description: String {
name
}
}
struct ValidationPathCase: CustomStringConvertible {
var name: String
var path: PureYAML.Validation.Path
var expectedDescription: String
var isRoot: Bool
var description: String {
name
}
}
func legacyModeRule(severity: PureYAML.Validation.Severity) -> PureYAML.Validation.Check<PureYAML.Model.Value, PureYAML.Model.Value> {
PureYAML.Validation.Check<PureYAML.Model.Value, PureYAML.Model.Value>(description: "Mode must not be legacy") { context in
guard case .string("legacy") = context.subject else {
return []
}
return [
PureYAML.Validation.Issue(
severity: severity,
reason: "Legacy mode is not allowed",
path: context.path,
),
]
}
}
func traceRule(label: String) -> PureYAML.Validation.Check<PureYAML.Model.Value, PureYAML.Model.Value> {
PureYAML.Validation.Check<PureYAML.Model.Value, PureYAML.Model.Value>(description: "Trace \(label)") { context in
[
PureYAML.Validation.Issue(
severity: .warning,
reason: "\(label) at \(context.path.isRoot ? "root" : context.path.description)",
path: context.path,
),
]
}
}
func expectValidationError(
_ value: PureYAML.Model.Value,
using validator: PureYAML.Validation.Validator = .init(),
strict: Bool = true,
check: (PureYAML.Validation.Issue.Collection) -> Void,
) {
do {
try PureYAML.validate(value, using: validator, strict: strict)
recordIssue("expected validation failure")
} catch let collection as PureYAML.Validation.Issue.Collection {
check(collection)
} catch {
recordIssue("unexpected error \(error)")
}
}