-- Parsing SCXML into states and transitions.
-- Error CONTEXT carries plpgsql line numbers, which would make this
-- expected output break on every unrelated edit.
\set SHOW_CONTEXT never
-- Quiet, so that the expected output is the same whether or not an earlier
-- test in the same database already created the extension.
set client_min_messages to warning;
create extension if not exists pg_statecharts_dev cascade;
reset client_min_messages;
\set chart ''
-- States come out in document order, with parent_id and is_initial resolved
-- from the enclosing element. Every child of a is initial.
select id, name, parent_id, is_initial, is_final, on_entry::text, on_exit::text
from fsm.scxml_states(:'chart'::xml);
id | name | parent_id | is_initial | is_final | on_entry | on_exit
-------------+-------------+------------+------------+----------+-------------------------------------------------------+----------------------------
pending | Pending | | t | f | {"(billing,reserve_stock)","(public,notify_pending)"} | {"(billing,release_hold)"}
paying | Paying | | f | f | {} | {}
authorizing | Authorizing | paying | t | f | {} | {}
capturing | Capturing | paying | f | f | {} | {}
fulfilling | Fulfilling | | f | f | {} | {}
packing | Packing | fulfilling | t | f | {} | {}
invoicing | Invoicing | fulfilling | t | f | {} | {}
drafting | Drafting | invoicing | t | f | {} | {}
sent | Sent | invoicing | f | f | {} | {}
complete | Complete | | f | t | {"(audit,log_complete)"} | {}
cancelled | Cancelled | | f | t | {} | {}
(11 rows)
-- Transitions belong to the state that encloses them. The
-- transitions and anything under a must not appear here.
select event, source_state, target_state from fsm.scxml_transitions(:'chart'::xml);
event | source_state | target_state
--------------+--------------+--------------
order.pay | pending | paying
order.cancel | pending | cancelled
order.paid | paying | fulfilling
auth.ok | authorizing | capturing
order.done | fulfilling | complete
(5 rows)
-- A dotted src is split on the first dot, an undotted one defaults to public
select (fsm.scxml_states(
'
'::xml)).on_entry::text as callbacks;
callbacks
--------------------------------------
{"(public,plain)","(a,b)","(a,b.c)"}
(1 row)
-- XML entities in attributes have to be decoded, not passed through escaped
select id, name from fsm.scxml_states(
'
'::xml);
id | name
----+--------------------
s | Pick & Pack
(1 row)
-- Namespaceless documents are accepted too
select id from fsm.scxml_states(
''::xml);
id
----
s
(1 row)
-- An unnamed state gets an empty name rather than being rejected
select id, name = '' as name_is_empty from fsm.scxml_states(
''::xml);
id | name_is_empty
----+---------------
s | t
(1 row)
--
-- Error cases
--
-- compound state without an
select fsm.scxml_states(
'
'::xml);
ERROR: state "p" has child states but no initial state
HINT: add inside
-- pointing at a state that is not a child
select fsm.scxml_states(
'
'::xml);
ERROR: state "p" declares "nope" as its initial state, but has no such child
DETAIL: child states are: c1
-- root initial pointing at nothing
select fsm.scxml_states(
''::xml);
ERROR: the statechart declares "nope" as its initial state, but has no such top level state
DETAIL: top level states are: s
-- state without an id
select fsm.scxml_states(
''::xml);
ERROR: found a element without an id attribute
HINT: every state, final and parallel element needs a unique id
-- no states at all
select fsm.scxml_states(''::xml);
ERROR: the statechart has no states
-- no initial attribute
select fsm.scxml_states(''::xml);
ERROR: the element has no initial attribute
HINT: add initial="" to
-- A transition without an event, or without a target, is rejected by name.
-- fsm.transition has NOT NULL on both, and a NULL here used to make the
-- generator's string_agg silently drop the row from the migration.
select fsm.scxml_transitions(
'
'::xml);
ERROR: a transition out of state "a" has no event attribute
HINT: every needs event="..." and target="..."; eventless transitions are not supported
select fsm.scxml_transitions(
'
'::xml);
ERROR: the transition on event "stop" out of state "b" has no target attribute
HINT: every needs event="..." and target="..."; targetless (internal) transitions are not supported
-- A transition inside used to be silently excluded by the xpath; the
-- runtime would refuse the chart at insert time, so the generator has to too.
select fsm.scxml_transitions(
'
'::xml);
ERROR: final state "b" has a transition, but a final state cannot be left
HINT: remove the from , or make it a