# `Statifier.Validator.Checks.Cancel`
[🔗](https://github.com/riddler/statifier-ex/blob/v2.0.0/lib/statifier/validator/checks/cancel.ex#L1)

Spec 6.3.1's single constraint on `<cancel>`: "A conformant SCXML document
MUST specify exactly one of sendid or sendidexpr." Reports
`{:cancel_sendid_and_sendidexpr}` when both are present and
`{:cancel_no_sendid}` when neither is, both at the `<cancel>` element's
own `location`.

`lib/statifier/document/cancel.ex` makes both `sendid` and `sendidexpr`
simultaneously representable, and both absent representable too,
precisely so this check can report the shape rather than lowering
refusing to build it - the same division of labour `Checks.Send` has for
its own mutually exclusive pairs. `<cancel>` gets its own file per the
house pattern (`Checks.Invoke`, `Checks.Assign`, `Checks.Param`): one
constraint is enough to justify one file at this repo's granularity.

The walk reaches every block a `<cancel>` can appear in: a state's
`onentry`/`onexit`, its own (and its `<initial>` element's) transitions,
`<if>`/`<foreach>` bodies nested in any of those, and every `<invoke>`'s
`<finalize>` block - the same reach `Checks.Send` needs, since both
elements are executable content that can occur wherever the other can.

# `check`

```elixir
@spec check(
  document :: Statifier.Document.t(),
  context :: Statifier.Validator.Context.t()
) :: [
  Statifier.Validator.Error.t()
]
```

Walks every `<cancel>` in the document and returns a
`:cancel_sendid_and_sendidexpr` or `:cancel_no_sendid` error for each one
whose `sendid`/`sendidexpr` attributes violate 6.3.1's exactly-one rule.
Returns `[]` when every `<cancel>` in the document specifies exactly one.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
