The validation module already implemented the composable-rule idiom under its own names (Check/Issue/SubjectContext) and a value-type Validator with duplicated traversal machinery per layer. Renamed the core types to the canonical names (Validation/ValidationError/ValidationErrorCollection/ ValidationContext/BuiltinValidation/AnyValidation), converted Validator to a reference-type class with the two-tier default-rule split, and genericized it over both Subject and Document via a new Traversable protocol so the model and tagged layers share one walk engine instead of two copies. Wired the JSON-representability rule set into the same shape and closed the two missing pieces (unwrap combinator, JSON coverage/config-pin tests).
76 lines
2.2 KiB
Swift
76 lines
2.2 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.ValidationError]
|
|
|
|
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.Validation<PureYAML.Model.Value, PureYAML.Model.Value> {
|
|
PureYAML.Validation.Validation<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.ValidationError(
|
|
severity: severity,
|
|
reason: "Legacy mode is not allowed",
|
|
path: context.path,
|
|
),
|
|
]
|
|
}
|
|
}
|
|
|
|
func traceRule(label: String) -> PureYAML.Validation.Validation<PureYAML.Model.Value, PureYAML.Model.Value> {
|
|
PureYAML.Validation.Validation<PureYAML.Model.Value, PureYAML.Model.Value>(description: "Trace \(label)") { context in
|
|
[
|
|
PureYAML.Validation.ValidationError(
|
|
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<PureYAML.Model.Value, PureYAML.Model.Value> = .init(),
|
|
strict: Bool = true,
|
|
check: (PureYAML.Validation.ValidationErrorCollection) -> Void,
|
|
) {
|
|
do {
|
|
try PureYAML.validate(value, using: validator, strict: strict)
|
|
recordIssue("expected validation failure")
|
|
} catch let collection as PureYAML.Validation.ValidationErrorCollection {
|
|
check(collection)
|
|
} catch {
|
|
recordIssue("unexpected error \(error)")
|
|
}
|
|
}
|