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

Spec 5.4.2: "A conformant SCXML document MUST specify either 'expr' or
children of `<assign>`, but not both." Reports `{:assign_expr_and_text,
expr}` at the `<assign>`'s own element span, whether those children are
text or markup (ADR-0041's 2026-09-02 Note) - same reason, same shape,
regardless of which form the content takes, exactly as `Checks.Content`
treats the two forms under `<content>`.

`lib/statifier/document/assign.ex` makes `expr`, `text` and `markup` all
representable at once precisely so this check can report the shape rather
than lowering refusing to build it - the same division of labour
`Checks.Content` has with `<content>` and `Checks.Data` has with `<data>`.

**Whitespace-only text is not text.** `Statifier.Parser.DOM.text/1`
concatenates `<assign>`'s direct text children verbatim and untrimmed, so
a pretty-printed `<assign expr="1">\n  </assign>` carries a `text` of
`"\n  "`. That is source formatting, not a payload, and firing on it
would reject documents the spec allows - the same rule
`Checks.Content.blank?/1` and `Checks.Data.blank?/1` already follow.
`markup`, when present, is never blank - it is `nil` unless `<assign>` has
at least one element child - so no equivalent whitespace carve-out applies
to it.

This check walks every state's own `onentry`/`onexit` blocks, every
state's own transitions (both plain and a `:history` state's default -
`Statifier.Document.State.transitions` covers both), and every state's
`<initial>` element's own transition - the three places
`Statifier.Document.Assign` can appear as executable content
(`Statifier.Document.Block.t()`'s and `Statifier.Document.Transition.t()`'s
own `content` fields).

# `check`

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

Walks every `<assign>` reachable through a state's `onentry`/`onexit`
blocks or its own (and its `<initial>` element's) transitions, and returns
an `:assign_expr_and_text` error for each one that carries both an `expr`
attribute and non-blank child content - markup, or text. Returns `[]` when
no `<assign>` in the document mixes the two forms.

---

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