import Testing @testable import PureXML @Suite("Schematron abstract patterns (is-a / param)") struct SchematronAbstractPatternTests { private func validate(_ schema: String, _ xml: String) throws -> [PureXML.Validation.ValidationError] { try PureXML.Validation.Schematron(schema: schema).validate(xml) } private func reasons(_ schema: String, _ xml: String) throws -> [String] { try validate(schema, xml).map(\.reason) } @Test("An is-a pattern substitutes $params into context and test") func test_paramSubstitution() throws { let schema = """ missing """ #expect(try validate(schema, "").isEmpty) let failed = try reasons(schema, "") #expect(failed.count == 1) #expect(failed.first?.contains("missing") == true) } @Test("The abstract template itself is not evaluated") func test_abstractTemplateInert() throws { // $ctx as a raw context would select nothing useful if evaluated; the // template must contribute no rules of its own. let schema = """ x """ #expect(try validate(schema, "").isEmpty) } @Test("One template instantiates for two different concrete patterns") func test_reuseTemplate() throws { let schema = """ absent """ #expect(try validate(schema, "").isEmpty) } @Test("A longer param name is not captured by a shorter one") func test_noPrefixCapture() throws { let schema = """ bad """ // $nm must map to "status", not be eaten by $n -> "item" + "m". #expect(try validate(schema, "").isEmpty) #expect(try !validate(schema, "").isEmpty) } @Test("A $name that is not a param (an ordinary let variable) is preserved") func test_letVariablePreserved() throws { let schema = """ wrong count """ #expect(try validate(schema, "").isEmpty) #expect(try !validate(schema, "").isEmpty) } }