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
- .version_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
34 35 36 37 38 39 40 41 42 43 44 45 46 |
# File 'lib/statecraft/rspec/state_report.rb', line 34 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
48 49 50 |
# File 'lib/statecraft/rspec/state_report.rb', line 48 def declared_shape_of(record) declared_shape(machine(record), current_state(record)) end |
.event_declared?(record, event_name) ⇒ Boolean
29 30 31 32 |
# File 'lib/statecraft/rspec/state_report.rb', line 29 def event_declared?(record, event_name) machine(record).transitions_from(current_state(record)) .any? { |descriptor| descriptor[:events].include?(event_name) } end |
.machine(record) ⇒ Object
25 26 27 |
# File 'lib/statecraft/rspec/state_report.rb', line 25 def machine(record) record.class.statecraft_mounting.machine_class end |
.reachable(record, metadata) ⇒ Object
52 53 54 55 56 57 58 59 |
# File 'lib/statecraft/rspec/state_report.rb', line 52 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
61 62 63 64 65 66 67 68 69 |
# File 'lib/statecraft/rspec/state_report.rb', line 61 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}#{version_standing(record)}" end |
.version_standing(record) ⇒ Object
20 21 22 23 |
# File 'lib/statecraft/rspec/state_report.rb', line 20 def version_standing(record) column = record.class.statecraft_mounting.version_column column ? " (#{column} #{record[column]})" : "" end |