module FiniteMachine::Safety

Module responsible for safety checks against known methods

Constants

CALLBACK_INVALID_MESSAGE
EVENT_CALLBACK_CONFLICT_MESSAGE
EVENT_CONFLICT_MESSAGE
STATE_CALLBACK_CONFLICT_MESSAGE

Public Instance Methods

detect_event_conflict!(event_name, method_name = event_name) click to toggle source

Raise error when the method is already defined

@example

detect_event_conflict!(:test, "test=")

@raise [FiniteMachine::AlreadyDefinedError]

@return [nil]

@api public

# File lib/finite_machine/safety.rb, line 36
def detect_event_conflict!(event_name, method_name = event_name)
  if method_already_implemented?(method_name)
    raise FiniteMachine::AlreadyDefinedError, EVENT_CONFLICT_MESSAGE % {
      name: event_name,
      type: :instance,
      method: method_name,
      source: "FiniteMachine"
    }
  end
end
ensure_valid_callback_name!(event_type, name) click to toggle source

Raise error when the callback name is not valid

@example

ensure_valid_callback_name!(HookEvent::Enter, ":state_name")

@raise [FiniteMachine::InvalidCallbackNameError]

@return [nil]

@api public

# File lib/finite_machine/safety.rb, line 57
def ensure_valid_callback_name!(event_type, name)
  message = if wrong_event_name?(name, event_type)
    EVENT_CALLBACK_CONFLICT_MESSAGE % {
      type: "on_#{event_type}",
      name: name
    }
  elsif wrong_state_name?(name, event_type)
    STATE_CALLBACK_CONFLICT_MESSAGE % {
      type: "on_#{event_type}",
      name: name
    }
  elsif !callback_names.include?(name)
    CALLBACK_INVALID_MESSAGE % {
      name: name,
      callbacks: callback_names.to_a.inspect
    }
  else
    nil
  end
  message && raise_invalid_callback_error(message)
end

Private Instance Methods

method_already_implemented?(name) click to toggle source

Check if method is already implemented inside StateMachine

@param [String] name

the method name

@return [Boolean]

@api private

# File lib/finite_machine/safety.rb, line 124
def method_already_implemented?(name)
  method_defined_within?(name, FiniteMachine::StateMachine)
end
method_defined_within?(name, klass) click to toggle source

Check if method is defined within a given class

@param [String] name

the method name

@param [Object] klass

@return [Boolean]

@api private

# File lib/finite_machine/safety.rb, line 138
def method_defined_within?(name, klass)
  klass.method_defined?(name) || klass.private_method_defined?(name)
end
raise_invalid_callback_error(message) click to toggle source
# File lib/finite_machine/safety.rb, line 111
def raise_invalid_callback_error(message)
  exception = InvalidCallbackNameError
  machine.catch_error(exception) || raise(exception, message)
end
wrong_event_name?(name, event_type) click to toggle source

Check if event name exists

@param [Symbol] name

@param [FiniteMachine::HookEvent] event_type

@return [Boolean]

@api private

# File lib/finite_machine/safety.rb, line 90
def wrong_event_name?(name, event_type)
  machine.states.include?(name) &&
    !machine.events.include?(name) &&
    event_type < HookEvent::Anyaction
end
wrong_state_name?(name, event_type) click to toggle source

Check if state name exists

@param [Symbol] name

@param [FiniteMachine::HookEvent] event_type

@return [Boolean]

@api private

# File lib/finite_machine/safety.rb, line 105
def wrong_state_name?(name, event_type)
  machine.events.include?(name) &&
    !machine.states.include?(name) &&
    event_type < HookEvent::Anystate
end