Module: Statecraft::RSpec::StateReport
- Defined in:
- lib/statecraft/rspec/state_report.rb
Overview
The shared sentences of every failure message: where the record stands, what the graph declares from there, what is reachable right now, and which guards refused. Built strictly on the public introspection surface — the matchers add words, never new answers.
Class Method Summary collapse
- .current_state(record) ⇒ Object
- .declared_shape(machine_class, state) ⇒ Object
- .declared_shape_of(record) ⇒ Object
- .event_declared?(record, event_name) ⇒ Boolean
- .machine(record) ⇒ Object
- .reachable(record, metadata) ⇒ Object
- .refusal(record, event_name, metadata) ⇒ Object
- .standing(record) ⇒ Object
Class Method Details
.current_state(record) ⇒ Object
12 13 14 |
# File 'lib/statecraft/rspec/state_report.rb', line 12 def current_state(record) record[record.class.statecraft_mounting.column]&.to_sym end |
.declared_shape(machine_class, state) ⇒ Object
29 30 31 32 33 34 35 36 37 38 39 40 41 |
# File 'lib/statecraft/rspec/state_report.rb', line 29 def declared_shape(machine_class, state) descriptors = machine_class.transitions_from(state) return "no edges are declared from #{state.inspect}" if descriptors.empty? rendered = descriptors.map do |descriptor| if descriptor[:events].empty? "to #{descriptor[:to].inspect} (direct)" else "to #{descriptor[:to].inspect} via #{descriptor[:events].inspect}" end end "declared from #{state.inspect}: #{rendered.join("; ")}" end |
.declared_shape_of(record) ⇒ Object
43 44 45 |
# File 'lib/statecraft/rspec/state_report.rb', line 43 def declared_shape_of(record) declared_shape(machine(record), current_state(record)) end |
.event_declared?(record, event_name) ⇒ Boolean
24 25 26 27 |
# File 'lib/statecraft/rspec/state_report.rb', line 24 def event_declared?(record, event_name) machine(record).transitions_from(current_state(record)) .any? { |descriptor| descriptor[:events].include?(event_name) } end |
.machine(record) ⇒ Object
20 21 22 |
# File 'lib/statecraft/rspec/state_report.rb', line 20 def machine(record) record.class.statecraft_mounting.machine_class end |
.reachable(record, metadata) ⇒ Object
47 48 49 50 51 52 53 54 |
# File 'lib/statecraft/rspec/state_report.rb', line 47 def reachable(record, ) transitions = record.available_transitions(metadata: ) state = current_state(record).inspect return "nothing is reachable from #{state} right now" if transitions.empty? rendered = transitions.map { |availability| "to #{availability.to.inspect} via #{availability.via.inspect}" } "reachable from #{state}: #{rendered.join("; ")}" end |
.refusal(record, event_name, metadata) ⇒ Object
56 57 58 59 60 61 62 63 64 |
# File 'lib/statecraft/rspec/state_report.rb', line 56 def refusal(record, event_name, ) refusals = record.refusals_for(event_name) if refusals.empty? "no record-layer guard refused — an input-reading guard: said no to metadata #{.inspect}" else named = refusals.map { |entry| "#{entry.guard.inspect} (#{entry.layer})" } "refused by record-layer guards: #{named.join(", ")}" end end |
.standing(record) ⇒ Object
16 17 18 |
# File 'lib/statecraft/rspec/state_report.rb', line 16 def standing(record) "#{record.class.name} in state #{current_state(record).inspect}" end |