XSD 1.0 cos-all-limited: a reference to a model group whose content is an `all` group is itself an all-group particle, so its maxOccurs must be 1 and its minOccurs 0 or 1. The direct `<all>` element was already checked by allGroupLimitedErrors, but a `<group ref>` resolving to an all group was not, so corpus particlesEa025 (`<group ref="x:G" maxOccurs="2">` to an all group) was accepted. Add allGroupReferenceMaxOccursErrors: collect the names of group definitions whose content is an all group, then flag a group reference to one whose maxOccurs is not 1 or whose minOccurs is not 0/1. The check runs over a single schema document tree, where group names are unique, so the by-local-name match cannot collide; a cross-document reference lives in a separate container and is under-rejected (never falsely rejected). XSTS invalid-schemas-accepted 36 -> 35; valid-schemas-rejected held at 0.
44 lines
1.9 KiB
Swift
44 lines
1.9 KiB
Swift
import Testing
|
|
@testable import PureXML
|
|
|
|
/// XSD 1.0 cos-all-limited (#158): a reference to a model group whose content is an
|
|
/// `all` group is itself an all-group particle, so its `maxOccurs` must be 1 (and
|
|
/// `minOccurs` 0 or 1). Mirrors corpus particlesEa025 (a group ref to an all group
|
|
/// with maxOccurs="2").
|
|
@Suite("XSD cos-all-limited group reference (#158)")
|
|
struct SchemaAllGroupReferenceTests {
|
|
private func allGroupRef(maxOccurs: String) -> String {
|
|
"""
|
|
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="urn:t" xmlns:t="urn:t">
|
|
<xs:group name="G"><xs:all><xs:element name="a1" type="xs:string"/><xs:element name="a2" type="xs:string"/></xs:all></xs:group>
|
|
<xs:element name="doc"><xs:complexType><xs:group ref="t:G" maxOccurs="\(maxOccurs)"/></xs:complexType></xs:element>
|
|
</xs:schema>
|
|
"""
|
|
}
|
|
|
|
private func compiles(_ schema: String) -> Bool {
|
|
(try? PureXML.Schema.Document(schema)) != nil
|
|
}
|
|
|
|
@Test("a group reference to an all group with maxOccurs>1 is rejected (particlesEa025)")
|
|
func test_allGroupRefMaxOccursTwoRejected() {
|
|
#expect(!compiles(allGroupRef(maxOccurs: "2")))
|
|
}
|
|
|
|
@Test("a group reference to an all group with maxOccurs=1 is accepted")
|
|
func test_allGroupRefMaxOccursOneAccepted() {
|
|
#expect(compiles(allGroupRef(maxOccurs: "1")))
|
|
}
|
|
|
|
@Test("a group reference to a non-all (sequence) group with maxOccurs>1 is accepted")
|
|
func test_sequenceGroupRefMaxOccursTwoAccepted() {
|
|
let schema = """
|
|
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="urn:t" xmlns:t="urn:t">
|
|
<xs:group name="G"><xs:sequence><xs:element name="a1" type="xs:string"/></xs:sequence></xs:group>
|
|
<xs:element name="doc"><xs:complexType><xs:group ref="t:G" maxOccurs="2"/></xs:complexType></xs:element>
|
|
</xs:schema>
|
|
"""
|
|
#expect(compiles(schema))
|
|
}
|
|
}
|