The two monolithic XSD content/identity rules only satisfied the OpenAPIKit validation idiom at the wrong granularity: no per-constraint removability, no isolable failing/near-miss tests. Split them into 32 named rules, each finding tagged at its origin and cached per XSDContext so the walk still runs once per document (the #101 decision against duplicating XSD's recursive type resolution still holds). Wired the streaming path's ID/IDREF and identity checks through the same framework instead of calling the validators imperatively, and added the unwrapAndLookup combinator the rule already named as required. Also includes the mandated repo-wide swiftformat/swiftlint pass.
84 lines
7.1 KiB
Swift
84 lines
7.1 KiB
Swift
import Testing
|
|
@testable import PureXML
|
|
|
|
/// Meta-tests for validation-rules.md exhaustive coverage: every shipped builtin
|
|
/// rule must have a fail and a near-miss succeed isolation test in
|
|
/// ``ValidationRule*Tests`` suites (update ``pairs`` when adding a rule or test).
|
|
@Suite("Validation rule registry")
|
|
struct ValidationRuleRegistryTests {
|
|
private typealias RuleTestPair = (fail: String, succeed: String)
|
|
|
|
/// Maps each ``BuiltinValidation/allRuleIDs`` entry to its isolation test names.
|
|
private static let pairs: [String: RuleTestPair] = [
|
|
"uniqueAttributes": ("test_uniqueAttributes", "test_uniqueAttributes_succeeds"),
|
|
"dtdContentModel": ("test_contentModel", "test_dtdContentModel_succeeds"),
|
|
"dtdRequiredAttributes": ("test_requiredAttributes", "test_dtdRequiredAttributes_succeeds"),
|
|
"dtdFixedAttributeValues": ("test_fixedAttributeValues", "test_dtdFixedAttributeValues_succeeds"),
|
|
"dtdEnumeratedAttributeValues": ("test_enumeratedAttributeValues", "test_dtdEnumeratedAttributeValues_succeeds"),
|
|
"dtdTokenizedAttributeTypes": ("test_tokenizedAttributeTypes", "test_dtdTokenizedAttributeTypes_succeeds"),
|
|
"dtdNotationAttributes": ("test_notationAttributes", "test_dtdNotationAttributes_succeeds"),
|
|
"dtdUndeclaredElement": ("test_undeclaredElement", "test_dtdUndeclaredElement_succeeds"),
|
|
"dtdUndeclaredAttributes": ("test_dtdUndeclaredAttributes", "test_dtdUndeclaredAttributes_succeeds"),
|
|
"dtdDeclarationValidity": ("test_dtdDeclarationValidity", "test_dtdDeclarationValidity_succeeds"),
|
|
"dtdRootElementType": ("test_dtdRootElementType", "test_dtdRootElementType_succeeds"),
|
|
"dtdIdentifierIntegrity": ("test_identifierIntegrity", "test_dtdIdentifierIntegrity_succeeds"),
|
|
"dtdStandaloneAttributes": ("test_dtdStandaloneAttributes", "test_dtdStandaloneAttributes_succeeds"),
|
|
"dtdStandaloneElementWhitespace": ("test_dtdStandaloneElementWhitespace", "test_dtdStandaloneElementWhitespace_succeeds"),
|
|
"dtdParseAdvisories": ("test_dtdParseAdvisories", "test_dtdParseAdvisories_succeeds"),
|
|
"htmlVoidElementsAreEmpty": ("test_htmlVoidElementsAreEmpty", "test_htmlVoidElementsAreEmpty_succeeds"),
|
|
"htmlRequiredParent": ("test_htmlRequiredParent", "test_htmlRequiredParent_succeeds"),
|
|
"htmlUniqueIdentifiers": ("test_htmlUniqueIdentifiers", "test_htmlUniqueIdentifiers_succeeds"),
|
|
"xsdNilAttributeRequiresNillable": ("test_nilAttributeRequiresNillable", "test_nilAttributeRequiresNillable_succeeds"),
|
|
"xsdNilElementMustBeEmpty": ("test_nilElementMustBeEmpty", "test_nilElementMustBeEmpty_succeeds"),
|
|
"xsdNilElementNoFixedConstraint": ("test_nilElementNoFixedConstraint", "test_nilElementNoFixedConstraint_succeeds"),
|
|
"xsdFixedElementNoChildren": ("test_fixedElementNoChildren", "test_fixedElementNoChildren_succeeds"),
|
|
"xsdFixedElementValueMatches": ("test_fixedElementValueMatches", "test_fixedElementValueMatches_succeeds"),
|
|
"xsdEmptyContentForbidsChildren": ("test_emptyContentForbidsChildren", "test_emptyContentForbidsChildren_succeeds"),
|
|
"xsdSimpleContentForbidsChildren": ("test_simpleContentForbidsChildren", "test_simpleContentForbidsChildren_succeeds"),
|
|
"xsdSimpleContentTypeValid": ("test_simpleContentTypeValid", "test_simpleContentTypeValid_succeeds"),
|
|
"xsdTextForbidden": ("test_textForbidden", "test_textForbidden_succeeds"),
|
|
"xsdWildcardElementUndeclared": ("test_wildcardElementUndeclared", "test_wildcardElementUndeclared_succeeds"),
|
|
"xsdSimpleTypeDisallowedAttribute": ("test_simpleTypeDisallowedAttribute", "test_simpleTypeDisallowedAttribute_succeeds"),
|
|
"xsdSimpleTypeForbidsChildren": ("test_simpleTypeForbidsChildren", "test_simpleTypeForbidsChildren_succeeds"),
|
|
"xsdSimpleTypeValueValid": ("test_simpleTypeValueValid", "test_simpleTypeValueValid_succeeds"),
|
|
"xsdTypeReferenceResolves": ("test_typeReferenceResolves", "test_typeReferenceResolves_succeeds"),
|
|
"xsdContentModelStructure": ("test_contentModelStructure", "test_contentModelStructure_succeeds"),
|
|
"xsdAttributeTypeValid": ("test_attributeTypeValid", "test_attributeTypeValid_succeeds"),
|
|
"xsdAttributeFixedMatches": ("test_attributeFixedMatches", "test_attributeFixedMatches_succeeds"),
|
|
"xsdAttributeRequiredPresent": ("test_attributeRequiredPresent", "test_attributeRequiredPresent_succeeds"),
|
|
"xsdAttributeSingleID": ("test_attributeSingleID", "test_attributeSingleID_succeeds"),
|
|
"xsdAttributeDeclaredOrPermitted": ("test_attributeDeclaredOrPermitted", "test_attributeDeclaredOrPermitted_succeeds"),
|
|
"xsdWildcardAttributeUndeclared": ("test_wildcardAttributeUndeclared", "test_wildcardAttributeUndeclared_succeeds"),
|
|
"xsdWildcardAttributeTypeValid": ("test_wildcardAttributeTypeValid", "test_wildcardAttributeTypeValid_succeeds"),
|
|
"xsdWildcardAttributeFixedMatches": ("test_wildcardAttributeFixedMatches", "test_wildcardAttributeFixedMatches_succeeds"),
|
|
"xsdXsiTypeSubstitutionValid": ("test_xsiTypeSubstitutionValid", "test_xsiTypeSubstitutionValid_succeeds"),
|
|
"xsdXsiTypeOverrideResolves": ("test_xsiTypeOverrideResolves", "test_xsiTypeOverrideResolves_succeeds"),
|
|
"xsdIdIdrefConsistent": ("test_idIdrefConsistent", "test_idIdrefConsistent_succeeds"),
|
|
"xsdIdentityConstraintXPathsValid": ("test_identityConstraintXPathsValid", "test_identityConstraintXPathsValid_succeeds"),
|
|
"xsdIdentityKeyFieldPresent": ("test_identityKeyFieldPresent", "test_identityKeyFieldPresent_succeeds"),
|
|
"xsdIdentityValueUnique": ("test_identityValueUnique", "test_identityValueUnique_succeeds"),
|
|
"xsdIdentityKeyrefResolves": ("test_identityKeyrefResolves", "test_identityKeyrefResolves_succeeds"),
|
|
"xsdIdentityFieldCardinality": ("test_identityFieldCardinality", "test_identityFieldCardinality_succeeds"),
|
|
"xsdIdentityFieldMustBeSimple": ("test_identityFieldMustBeSimple", "test_identityFieldMustBeSimple_succeeds"),
|
|
"xsdFinalRespected": ("test_xsdFinalRespected", "test_xsdFinalRespected_succeeds"),
|
|
"xsdRestrictionsAreSubsets": ("test_xsdRestrictionsAreSubsets", "test_xsdRestrictionsAreSubsets_succeeds"),
|
|
"conformanceMatchesExpected": ("test_conformanceMatchesExpected", "test_conformanceMatchesExpected_succeeds"),
|
|
"xsdStreamingShallowValidity": ("test_xsdStreamingShallowValidity", "test_xsdStreamingShallowValidity_succeeds"),
|
|
"xsdStreamingIdConsistency": ("test_xsdStreamingIdConsistency", "test_xsdStreamingIdConsistency_succeeds"),
|
|
]
|
|
|
|
@Test("Every builtin rule id has a fail and succeed test registered")
|
|
func test_allRulesPaired() {
|
|
let ids = PureXML.Validation.BuiltinValidation.allRuleIDs
|
|
#expect(Set(Self.pairs.keys) == Set(ids), "pairs keys must match allRuleIDs")
|
|
#expect(ids.count == 55)
|
|
}
|
|
|
|
@Test("Builtin descriptions stay unique")
|
|
func test_descriptionsUnique() {
|
|
let all = PureXML.Validation.BuiltinValidation.allDescriptions
|
|
#expect(all.count == Set(all).count)
|
|
#expect(all.count == PureXML.Validation.BuiltinValidation.allRuleIDs.count)
|
|
}
|
|
}
|