Class: Statecraft::RSpec::Transition

Inherits:
Object
  • Object
show all
Defined in:
lib/statecraft/rspec/transition.rb

Overview

expect { order.fire!(:pay) }.to transition(order) .from(:pending).to(:paid).via_event(:pay).with_metadata("k" => "v")

The transition through the eyes of a test: the state column moved to the target AND exactly one log row was appended with the matching from/to/event/metadata. A non-bang call that returned false leaves both untouched — the matcher fails and explains why, from the same introspection the pipeline consulted. Exceptions of the bang forms fly through, like with the change matcher: refusals are asserted with refuse_event or raise_error, not here.

Instance Method Summary collapse

Constructor Details

#initialize(record) ⇒ Transition

Returns a new instance of Transition.



16
17
18
19
# File 'lib/statecraft/rspec/transition.rb', line 16

def initialize(record)
  @record = record
  @failures = []
end

Instance Method Details

#descriptionObject



71
72
73
# File 'lib/statecraft/rspec/transition.rb', line 71

def description
  "transition #{@record.class.name} to #{@to_state.inspect}"
end

#failure_messageObject



57
58
59
60
61
62
# File 'lib/statecraft/rspec/transition.rb', line 57

def failure_message
  expected_event = " via event #{@event_name.inspect}" if @event_name
  header = "expected the block to transition #{@record.class.name} " \
           "#{@before_state.inspect} -> #{@to_state.inspect}#{expected_event}"
  ([header] + @failures).join("\n  ")
end

#failure_message_when_negatedObject



64
65
66
67
68
69
# File 'lib/statecraft/rspec/transition.rb', line 64

def failure_message_when_negated
  row = @appended.last
  written_by = " by event #{row.event.inspect}" if row.event
  "expected the block not to transition #{@record.class.name} to #{@to_state.inspect}, " \
    "but it did: #{row.from_state.inspect} -> #{row.to_state.inspect}#{written_by}"
end

#from(state_name) ⇒ Object



21
22
23
24
# File 'lib/statecraft/rspec/transition.rb', line 21

def from(state_name)
  @from_state = state_name.to_sym
  self
end

#matches?(block) ⇒ Boolean

Returns:

  • (Boolean)

Raises:

  • (ArgumentError)


45
46
47
48
49
50
51
52
53
54
55
# File 'lib/statecraft/rspec/transition.rb', line 45

def matches?(block)
  raise ArgumentError, "transition(record).to(:state) — the .to target is required" unless @to_state

  @before_state = StateReport.current_state(@record)
  appended_before = @record.history.count
  block.call
  @after_state = StateReport.current_state(@record)
  @appended = @record.history.offset(appended_before).to_a
  collect_failures
  @failures.empty?
end

#supports_block_expectations?Boolean

Returns:

  • (Boolean)


41
42
43
# File 'lib/statecraft/rspec/transition.rb', line 41

def supports_block_expectations?
  true
end

#to(state_name) ⇒ Object



26
27
28
29
# File 'lib/statecraft/rspec/transition.rb', line 26

def to(state_name)
  @to_state = state_name.to_sym
  self
end

#via_event(event_name) ⇒ Object



31
32
33
34
# File 'lib/statecraft/rspec/transition.rb', line 31

def via_event(event_name)
  @event_name = event_name.to_sym
  self
end

#with_metadata(metadata) ⇒ Object



36
37
38
39
# File 'lib/statecraft/rspec/transition.rb', line 36

def ()
  @metadata = 
  self
end