Statifier.Validator.Checks.DefaultTransition (Statifier v2.0.0)

Copy Markdown View Source

The sub-check checks 4 and 5 share: an <initial> element's and a :history state's whole content model is one constrained <transition> - required, exactly one, a non-null target, no event, no cond. Spec 3.6 states this for <initial>; spec 3.10 states it for <history>'s default transition, more strictly than a looser "when present" reading - the spec's stricter wording wins.

Statifier.Document.Initial.transitions and a :history state's own transitions share the same [Transition.t()] shape (lib/statifier/document/initial.ex), so one function serves both - check/3 never needs to know which element it is looking at beyond the owner tag it is handed.

This module is not itself one of Statifier.Validator's @checks - it has no standalone entry, only a check/3 consumed by Statifier.Validator.Checks.InitialElement and Statifier.Validator.Checks.History.

The event oracle is Map.has_key?(transition.attribute_locations, :event), because Statifier.Lowering.Attributes.list/2 returns [] for both an absent event and event="" - the list alone cannot tell the two apart. This inherits a narrowing already accepted for Statifier.Lowering.Attributes.put_location/4: a written attribute whose value_location is nil (the parser handler's short-scan tolerance) never gets an attribute_locations entry either, so a document that trips both that tolerance and writes event="" slips past this check unreported. Accepted: it is the only oracle available at this layer, and closing it means changing what lowering records, which belongs to Statifier.Lowering.Attributes, not this check. cond needs no such oracle - it is nil when absent and "" when written empty, so != nil is exact.

Summary

Functions

owner identifies which element's content model is being checked ({:initial, id} or {:history, id}); transitions is that element's transition list; owner_location is where a wrong count is reported - the element itself has no transition to point at when the count is zero.

Functions

check(owner, transitions, owner_location)

@spec check(
  owner :: Statifier.Validator.Error.owner(),
  transitions :: [Statifier.Document.Transition.t()],
  owner_location :: Statifier.Parser.Location.t()
) :: [Statifier.Validator.Error.t()]

owner identifies which element's content model is being checked ({:initial, id} or {:history, id}); transitions is that element's transition list; owner_location is where a wrong count is reported - the element itself has no transition to point at when the count is zero.