lib/metanorma/modspec/validate.rb in mn-requirements-0.1.8 vs lib/metanorma/modspec/validate.rb in mn-requirements-0.1.9
- old
+ new
@@ -6,11 +6,11 @@
@ids ||= reqt_links(reqt.document)
reqt_link_validate(reqt)
end
def nested_reqt?(reqt)
- reqt.at("./ancestor::requirement | ./ancestor::recommendation | "\
+ reqt.at("./ancestor::requirement | ./ancestor::recommendation | " \
"./ancestor::permission")
end
def reqt_link_validate(reqt)
return if nested_reqt?(reqt)
@@ -20,10 +20,11 @@
conformance_to_reqt(reqt, "general", "verification")
conformance_to_reqt(reqt, "class", "conformanceclass")
class_to_children(reqt, "class", "general")
class_to_children(reqt, "conformanceclass", "verification")
children_to_class(reqt, "verification", "conformanceclass")
+ reqt_to_dependency(reqt)
end
def type2validate(reqt)
type = reqt["type"]
type = "general" if type.nil? || type.empty?
@@ -34,18 +35,39 @@
CLASS2LABEL = {
general: "Requirement",
verification: "Conformance test",
class: "Requirement class",
conformanceclass: "Conformance class",
+ provision: "Provision",
+ dependency: "Prerequisite",
+ indirect_dependency: "Indirect prerequisite",
+ implements: "Implemented provision",
}.freeze
def log_reqt(reqt, leftclass, rightclass)
- @log.add("Requirements", reqt[:elem],
- "#{CLASS2LABEL[leftclass.to_sym]} #{reqt[:label] || reqt[:id]} "\
- "has no corresponding #{CLASS2LABEL[rightclass.to_sym]}")
+ @log.add("Requirements", reqt[:elem], <<~MSG
+ #{CLASS2LABEL[leftclass.to_sym]} #{reqt[:label] || reqt[:id]} has no corresponding #{CLASS2LABEL[rightclass.to_sym]}
+ MSG
+ )
end
+ def log_reqt2(reqt, leftclass, target, rightclass)
+ @log.add("Requirements", reqt[:elem], <<~MSG
+ #{CLASS2LABEL[leftclass]} #{reqt[:label] || reqt[:id]} points to #{CLASS2LABEL[rightclass]} #{target} outside this document
+ MSG
+ )
+ end
+
+ def reqt_to_dependency(reqt)
+ r = @ids[:id][reqt["id"]]
+ %i(dependency indirect_dependency implements).each do |x|
+ r[x].each do |d|
+ @ids[:label][d] or log_reqt2(r, :provision, d, x)
+ end
+ end
+ end
+
def reqt_to_conformance(reqt, reqtclass, confclass)
return unless type2validate(reqt) == reqtclass
r = @ids[:id][reqt["id"]]
(r[:label] && @ids[:class][confclass]&.any? do |x|
@@ -82,32 +104,42 @@
log_reqt(r, childclass, parentclass)
end
def reqt_links(docxml)
docxml.xpath("//requirement | //recommendation | //permission")
- .each_with_object({ id: {}, class: {} }) do |r, m|
+ .each_with_object({ id: {}, class: {}, label: {} }) do |r, m|
next if nested_reqt?(r)
reqt_links1(r, m)
end
end
def reqt_links1(reqt, hash)
type = type2validate(reqt)
- hash[:id][reqt["id"]] = reqt_links_struct(reqt)
+ a = reqt_links_struct(reqt)
+ hash[:id][reqt["id"]] = a
hash[:class][type] ||= []
- hash[:class][type] << hash[:id][reqt["id"]]
+ hash[:class][type] << a
+ hash[:label][a[:label]] = reqt["id"]
hash
end
+ def classif_tag(reqt, tag)
+ reqt.xpath("./classification[tag][value]")
+ .each_with_object([]) do |c, m|
+ c.at("./tag").text.casecmp(tag).zero? or next
+ m << c.at("./value").text
+ end
+ end
+
def reqt_links_struct(reqt)
{ id: reqt["id"], elem: reqt, label: reqt.at("./identifier")&.text,
- subject: reqt.xpath("./classification[tag = 'target']/value")
- .map(&:text),
+ subject: classif_tag(reqt, "target"),
child: reqt.xpath("./requirement | ./recommendation | ./permission")
- .map do |r|
- r.at("./identifier")&.text
- end }
+ .map { |r| r.at("./identifier")&.text },
+ dependency: reqt.xpath("./inherit").map(&:text),
+ indirect_dependency: classif_tag(reqt, "indirect-dependency"),
+ implements: classif_tag(reqt, "implements") }
end
end
end
end