Module: StateGate::Assertions

Defined in:
lib/state_gate/assertions.rb

Overview

Description

Minitest assertions to verify StateGate defined states and transitions.

The Minitest equivalent of the StateGate RSpec have_states and allow_transitions_on matchers.

[:source_obj] The Class or Instance to be tested.

[:attribute] The attribute being tested.

[:states] The expected states as Symbols or Strings.

[:from] The state being transitioned from.

[:to] The states being transitioned to, as a Symbol, String or Array.

assert_has_states Sysop, :status, :pending, :active
refute_has_states Sysop, :status, :deleted

assert_allows_transitions Sysop, :status, from: :active, to: [:locked, :archived]
refute_allows_transitions Sysop, :status, from: :active, to: :pending

assert_has_states fails if an existing state is missing, or if given states are not defined for the attribute.

refute_has_states fails if any of the given states are defined for the attribute.

assert_allows_transitions fails if an allowed transition is missing, or if a given transition is not allowed.

refute_allows_transitions fails if any of the given transitions are allowed for the state.

Instance Method Summary collapse

Instance Method Details

#assert_allows_transitions(source_obj, attribute, from: nil, to: nil) ⇒ Object

Asserts the given states are exactly the transitions allowed from the :from state.

assert_allows_transitions Sysop, :status, from: :active,
                                        to: [:locked, :suspended, :archived]
assert_allows_transitions sysop, :status, from: :pending, to: :active


107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
# File 'lib/state_gate/assertions.rb', line 107

def assert_allows_transitions(source_obj, attribute, from: nil, to: nil)
  key, engine, state, expected = state_gate_transition_setup(source_obj, attribute, from, to)
  
  allowed = engine.transitions_for_state(state)
  missing = allowed  - expected
  extra   = expected - allowed
  
  return pass if missing.empty? && extra.empty?
  
  messages = []
  if missing.any?
    messages << "##{key} also transitions from :#{state} to #{state_gate_list(missing)}."
  end
  if extra.any?
    messages << "##{key} does not transition from :#{state} to #{state_gate_list(extra)}."
  end
  
  flunk messages.join(' ')
end

#assert_has_states(source_obj, attribute, *states) ⇒ Object

Asserts the given states are exactly the states defined for the attribute.

assert_has_states Sysop, :status, :pending, :active, :locked
assert_has_states sysop, :status, %w[pending active locked]


56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/state_gate/assertions.rb', line 56

def assert_has_states(source_obj, attribute, *states)
  engine   = state_gate_engine(source_obj, attribute)
  key      = StateGate.symbolize(attribute)
  expected = state_gate_symbolize_states(states)
  
  missing  = engine.states - expected
  extra    = expected      - engine.states
  
  return pass if missing.empty? && extra.empty?
  
  messages = []
  messages << state_gate_also_valid_message(missing, key) if missing.any?
  messages << state_gate_not_valid_message(extra, key)    if extra.any?
  
  flunk messages.join(' ')
end

#refute_allows_transitions(source_obj, attribute, from: nil, to: nil) ⇒ Object

Asserts none of the given states are transitions allowed from the :from state.

refute_allows_transitions Sysop, :status, from: :archived, to: [:locked, :suspended]


134
135
136
137
138
139
140
141
142
# File 'lib/state_gate/assertions.rb', line 134

def refute_allows_transitions(source_obj, attribute, from: nil, to: nil)
  _key, engine, state, expected = state_gate_transition_setup(source_obj, attribute, from, to)
  
  found = expected & engine.transitions_for_state(state)
  
  return pass if found.empty?
  
  flunk ":#{state} is allowed to transition to #{state_gate_list(found)}."
end

#refute_has_states(source_obj, attribute, *states) ⇒ Object

Asserts none of the given states are defined for the attribute.

refute_has_states Sysop, :status, :deleted, :banned


79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/state_gate/assertions.rb', line 79

def refute_has_states(source_obj, attribute, *states)
  engine   = state_gate_engine(source_obj, attribute)
  key      = StateGate.symbolize(attribute)
  expected = state_gate_symbolize_states(states)
  
  found    = expected.select { |s| engine.states.include?(s) }
  
  return pass if found.empty?
  
  if found.one?
    flunk "#{state_gate_list(found)} is a valid state for ##{key}."
  else
    flunk "#{state_gate_list(found)} are valid states for ##{key}."
  end
end