Check 13: <datamodel> and <data> structural rules that lowering leaves
representable on purpose (lib/statifier/document/data.ex,
lib/statifier/document/datamodel.ex), following the same division of
labour Checks.Content and Checks.Donedata already have with their own
document nodes.
Four reasons, over every <datamodel> the document holds - the root's own
document.datamodel_element and every state's:
{:data_expr_and_src, id}- a<data>written with bothexprandsrc(5.3.2: "MAY have either a 'src' or an 'expr' attribute, but MUST NOT have both").{:data_value_and_children, id}- a<data>withexprorsrcwritten and non-blank child text (5.3.2: "if either attribute is present, the element MUST NOT have any children"). Whitespace-only text is not text - sameblank?/1shape and reasoning asChecks.Content.blank?/1(lib/statifier/validator/checks/content.ex:66-67): pretty-printed XML leaves formatting text nodes that are not payload.{:data_reserved_id, id}- a<data id="...">beginning with_(5.10: "A conformant SCXML document MUST NOT contain ids beginning with '_' in the<data>element").{:datamodel_bad_parent, kind}- a<datamodel>on a:finalor:historystate.<datamodel>is legal under<scxml>,<state>, and<parallel>only (3.2.2 / 3.3.2 / 3.4.2); lowering cannot catch this because all four state kinds share one%Document.State{}struct (lib/statifier/document/state.ex's kind-scoped fields table). FollowsChecks.Donedata.offending?/1's shape.
Each <data>-level reason is reported at the offending <data>'s own
span: attribute_locations[:id] when written, its own location
otherwise (mirroring Checks.Ids.id_location/1 - id is required to
build a Data struct at all, so attribute_locations[:id] is always
present in practice, but the fallback keeps the two checks' shape
identical). :datamodel_bad_parent is reported at the <datamodel>'s own
location.
Summary
Functions
Returns :data_expr_and_src, :data_value_and_children, and
:data_reserved_id errors for every offending <data> in the document,
and a :datamodel_bad_parent error for every <datamodel> on a :final
or :history state. Returns [] when every <datamodel>/<data> in the
document is well-formed and correctly placed.
Functions
@spec check( document :: Statifier.Document.t(), context :: Statifier.Validator.Context.t() ) :: [ Statifier.Validator.Error.t() ]
Returns :data_expr_and_src, :data_value_and_children, and
:data_reserved_id errors for every offending <data> in the document,
and a :datamodel_bad_parent error for every <datamodel> on a :final
or :history state. Returns [] when every <datamodel>/<data> in the
document is well-formed and correctly placed.