# frozen_string_literal: true RSpec.describe FiniteMachine, 'handlers' do before(:each) { stub_const("DummyLogger", Class.new do attr_reader :result def log_error(exception) @result = "log_error(#{exception})" end def raise_error raise FiniteMachine::TransitionError end end) } it "allows to customise error handling" do called = [] fsm = FiniteMachine.new do initial :green event :slow, :green => :yellow event :stop, :yellow => :red handle FiniteMachine::InvalidStateError do |exception| called << 'invalidstate' end end expect(fsm.current).to eql(:green) fsm.stop expect(fsm.current).to eql(:green) expect(called).to eql([ 'invalidstate' ]) end it 'allows for :with to be symbol' do logger = DummyLogger.new fsm = FiniteMachine.new(logger) do initial :green event :slow, :green => :yellow event :stop, :yellow => :red handle FiniteMachine::InvalidStateError, with: :log_error end expect(fsm.current).to eql(:green) fsm.stop expect(fsm.current).to eql(:green) expect(logger.result).to eql('log_error(FiniteMachine::InvalidStateError)') end it 'allows for error type as string' do logger = DummyLogger.new called = [] fsm = FiniteMachine.new(target: logger) do initial :green event :slow, :green => :yellow event :stop, :yellow => :red on_enter_yellow do |event| raise_error end handle 'InvalidStateError' do |exception| called << 'invalid_state_error' end end expect(fsm.current).to eql(:green) fsm.stop expect(fsm.current).to eql(:green) expect(called).to eql(['invalid_state_error']) end it 'allows for empty block handler' do called = [] fsm = FiniteMachine.new do initial :green event :slow, :green => :yellow event :stop, :yellow => :red handle FiniteMachine::InvalidStateError do called << 'invalidstate' end end expect(fsm.current).to eql(:green) fsm.stop expect(fsm.current).to eql(:green) expect(called).to eql([ 'invalidstate' ]) end it 'requires error handler' do expect { FiniteMachine.new do initial :green event :slow, :green => :yellow handle 'UnknownErrorType' end }.to raise_error(ArgumentError, /error handler/) end it 'checks handler class to be Exception' do expect { FiniteMachine.new do initial :green event :slow, :green => :yellow handle Object do end end }.to raise_error(ArgumentError, /Object isn't an Exception/) end end