mirror of
				https://github.com/aasm/aasm
				synced 2023-03-27 23:22:41 -04:00 
			
		
		
		
	attempt add global before transitions
coverage for not calling the transition callbacks complete rething, support before after all events, error all events, and ensure
This commit is contained in:
		
							parent
							
								
									a31b02cc2b
								
							
						
					
					
						commit
						e64a84f71f
					
				
					 6 changed files with 254 additions and 61 deletions
				
			
		| 
						 | 
				
			
			@ -146,6 +146,7 @@ Here you can see a list of all possible callbacks, together with their order of
 | 
			
		|||
 | 
			
		||||
```ruby
 | 
			
		||||
begin
 | 
			
		||||
  event           before_all_events
 | 
			
		||||
  event           before
 | 
			
		||||
  event           guards
 | 
			
		||||
  transition      guards
 | 
			
		||||
| 
						 | 
				
			
			@ -160,8 +161,13 @@ begin
 | 
			
		|||
  old_state       after_exit
 | 
			
		||||
  new_state       after_enter
 | 
			
		||||
  event           after
 | 
			
		||||
  event           after_all_events
 | 
			
		||||
rescue
 | 
			
		||||
  event           error
 | 
			
		||||
  event           error_on_all_events
 | 
			
		||||
ensure
 | 
			
		||||
  event           ensure
 | 
			
		||||
  event           ensure_on_all_events
 | 
			
		||||
end
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -75,6 +75,12 @@ private
 | 
			
		|||
    begin
 | 
			
		||||
      old_state = aasm(state_machine_name).state_object_for_name(aasm(state_machine_name).current_state)
 | 
			
		||||
 | 
			
		||||
      event.fire_global_callbacks(
 | 
			
		||||
        :before_all_events,
 | 
			
		||||
        self,
 | 
			
		||||
        *process_args(event, aasm(state_machine_name).current_state, *args)
 | 
			
		||||
      )
 | 
			
		||||
 | 
			
		||||
      # new event before callback
 | 
			
		||||
      event.fire_callbacks(
 | 
			
		||||
        :before,
 | 
			
		||||
| 
						 | 
				
			
			@ -97,7 +103,12 @@ private
 | 
			
		|||
        aasm_failed(state_machine_name, event_name, old_state)
 | 
			
		||||
      end
 | 
			
		||||
    rescue StandardError => e
 | 
			
		||||
      event.fire_callbacks(:error, self, e, *process_args(event, aasm(state_machine_name).current_state, *args)) || raise(e)
 | 
			
		||||
      event.fire_callbacks(:error, self, e, *process_args(event, aasm(state_machine_name).current_state, *args)) || 
 | 
			
		||||
      event.fire_global_callbacks(:error_on_all_events, self, e, *process_args(event, aasm(state_machine_name).current_state, *args)) ||
 | 
			
		||||
      raise(e)
 | 
			
		||||
    ensure
 | 
			
		||||
      event.fire_callbacks(:ensure, self, *process_args(event, aasm(state_machine_name).current_state, *args))
 | 
			
		||||
      event.fire_global_callbacks(:ensure_on_all_events, self, *process_args(event, aasm(state_machine_name).current_state, *args)) 
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -134,6 +145,11 @@ private
 | 
			
		|||
        self,
 | 
			
		||||
        *process_args(event, old_state.name, *args)
 | 
			
		||||
      )
 | 
			
		||||
      event.fire_global_callbacks(
 | 
			
		||||
        :after_all_events,
 | 
			
		||||
        self,
 | 
			
		||||
        *process_args(event, old_state.name, *args)
 | 
			
		||||
      )
 | 
			
		||||
 | 
			
		||||
      self.aasm_event_fired(event.name, old_state.name, aasm(state_machine_name).current_state) if self.respond_to?(:aasm_event_fired)
 | 
			
		||||
    else
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -113,6 +113,22 @@ module AASM
 | 
			
		|||
      @state_machine.add_global_callbacks(:after_all_transitions, *callbacks, &block)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def before_all_events(*callbacks, &block)
 | 
			
		||||
      @state_machine.add_global_callbacks(:before_all_events, *callbacks, &block)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def after_all_events(*callbacks, &block)
 | 
			
		||||
      @state_machine.add_global_callbacks(:after_all_events, *callbacks, &block)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def error_on_all_events(*callbacks, &block)
 | 
			
		||||
      @state_machine.add_global_callbacks(:error_on_all_events, *callbacks, &block)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def ensure_on_all_events(*callbacks, &block)
 | 
			
		||||
      @state_machine.add_global_callbacks(:ensure_on_all_events, *callbacks, &block)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def states
 | 
			
		||||
      @state_machine.states
 | 
			
		||||
    end
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -13,7 +13,7 @@ module AASM::Core
 | 
			
		|||
 | 
			
		||||
      # from aasm4
 | 
			
		||||
      @options = options # QUESTION: .dup ?
 | 
			
		||||
      add_options_from_dsl(@options, [:after, :before, :error, :success, :after_commit], &block) if block
 | 
			
		||||
      add_options_from_dsl(@options, [:after, :before, :error, :success, :after_commit, :ensure], &block) if block
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # a neutered version of fire - it doesn't actually fire the event, it just
 | 
			
		||||
| 
						 | 
				
			
			@ -43,6 +43,10 @@ module AASM::Core
 | 
			
		|||
      @transitions.select { |t| t.to == state }
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def fire_global_callbacks(callback_name, record, *args)
 | 
			
		||||
      invoke_callbacks(state_machine.global_callbacks[callback_name], record, args)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def fire_callbacks(callback_name, record, *args)
 | 
			
		||||
      # strip out the first element in args if it's a valid to_state
 | 
			
		||||
      # #given where we're coming from, this condition implies args not empty
 | 
			
		||||
| 
						 | 
				
			
			@ -145,6 +149,5 @@ module AASM::Core
 | 
			
		|||
          false
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
  end
 | 
			
		||||
end # AASM
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -18,7 +18,10 @@ module Callbacks
 | 
			
		|||
    end
 | 
			
		||||
 | 
			
		||||
    aasm do
 | 
			
		||||
      after_all_transitions :after_all_transitions
 | 
			
		||||
      before_all_events       :before_all_events
 | 
			
		||||
      after_all_events        :after_all_events
 | 
			
		||||
      ensure_on_all_events    :ensure_on_all_events
 | 
			
		||||
      after_all_transitions   :after_all_transitions
 | 
			
		||||
 | 
			
		||||
      state :open, :initial => true,
 | 
			
		||||
        :before_enter => :before_enter_open,
 | 
			
		||||
| 
						 | 
				
			
			@ -36,11 +39,11 @@ module Callbacks
 | 
			
		|||
        :exit         => :exit_closed,
 | 
			
		||||
        :after_exit   => :after_exit_closed
 | 
			
		||||
 | 
			
		||||
      event :close, :before => :before_event, :after => :after_event, :guard => :event_guard do
 | 
			
		||||
      event :close, :before => :before_event, :after => :after_event, :guard => :event_guard, :ensure => :ensure_event do
 | 
			
		||||
        transitions :to => :closed, :from => [:open], :guard => :transition_guard, :after => :after_transition
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      event :open, :before => :before_event, :after => :after_event do
 | 
			
		||||
      event :open, :before => :before_event, :after => :after_event  do
 | 
			
		||||
        transitions :to => :open, :from => :closed
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
| 
						 | 
				
			
			@ -50,29 +53,33 @@ module Callbacks
 | 
			
		|||
      puts text if @log
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def aasm_write_state(*args); log('aasm_write_state'); true; end
 | 
			
		||||
    def aasm_write_state(*args);  log('aasm_write_state'); true;  end
 | 
			
		||||
    def before_enter_open;        log('before_enter_open');       end
 | 
			
		||||
    def enter_open;               log('enter_open');              end
 | 
			
		||||
    def before_exit_open;         log('before_exit_open');        end
 | 
			
		||||
    def after_enter_open;         log('after_enter_open');        end
 | 
			
		||||
    def exit_open;                log('exit_open');               end
 | 
			
		||||
    def after_exit_open;          log('after_exit_open');         end
 | 
			
		||||
 | 
			
		||||
    def before_enter_open;    log('before_enter_open');   end
 | 
			
		||||
    def enter_open;           log('enter_open');          end
 | 
			
		||||
    def before_exit_open;     log('before_exit_open');    end
 | 
			
		||||
    def after_enter_open;     log('after_enter_open');    end
 | 
			
		||||
    def exit_open;            log('exit_open');           end
 | 
			
		||||
    def after_exit_open;      log('after_exit_open');     end
 | 
			
		||||
    def before_enter_closed;      log('before_enter_closed'); end
 | 
			
		||||
    def enter_closed;             log('enter_closed');        end
 | 
			
		||||
    def before_exit_closed;       log('before_exit_closed');  end
 | 
			
		||||
    def exit_closed;              log('exit_closed');         end
 | 
			
		||||
    def after_enter_closed;       log('after_enter_closed');  end
 | 
			
		||||
    def after_exit_closed;        log('after_exit_closed');   end
 | 
			
		||||
 | 
			
		||||
    def before_enter_closed;  log('before_enter_closed'); end
 | 
			
		||||
    def enter_closed;         log('enter_closed');        end
 | 
			
		||||
    def before_exit_closed;   log('before_exit_closed');  end
 | 
			
		||||
    def exit_closed;          log('exit_closed');         end
 | 
			
		||||
    def after_enter_closed;   log('after_enter_closed');  end
 | 
			
		||||
    def after_exit_closed;    log('after_exit_closed');   end
 | 
			
		||||
    def event_guard;              log('event_guard');         !@fail_event_guard;      end
 | 
			
		||||
    def transition_guard;         log('transition_guard');    !@fail_transition_guard; end
 | 
			
		||||
 | 
			
		||||
    def event_guard;          log('event_guard');         !@fail_event_guard;      end
 | 
			
		||||
    def transition_guard;     log('transition_guard');    !@fail_transition_guard; end
 | 
			
		||||
    def after_transition;         log('after_transition');        end
 | 
			
		||||
    def after_all_transitions;    log('after_all_transitions');   end
 | 
			
		||||
 | 
			
		||||
    def after_transition;     log('after_transition');    end
 | 
			
		||||
    def after_all_transitions;log('after_all_transitions');end
 | 
			
		||||
    def before_all_events;        log('before_all_events')    end
 | 
			
		||||
    def before_event;             log('before_event');        end
 | 
			
		||||
    def after_event;              log('after_event');         end
 | 
			
		||||
    def after_all_events;         log('after_all_events');    end
 | 
			
		||||
 | 
			
		||||
    def before_event;         log('before_event');        end
 | 
			
		||||
    def after_event;          log('after_event');         end
 | 
			
		||||
    def ensure_event;             log('ensure');              end
 | 
			
		||||
    def ensure_on_all_events;     log('ensure');              end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,65 @@
 | 
			
		|||
require 'spec_helper'
 | 
			
		||||
Dir[File.dirname(__FILE__) + "/../models/callbacks/*.rb"].sort.each { |f| require File.expand_path(f) }
 | 
			
		||||
 | 
			
		||||
shared_examples 'an implemented callback that accepts error' do
 | 
			
		||||
  context 'with callback defined' do
 | 
			
		||||
    it "should run error_callback if an exception is raised" do
 | 
			
		||||
      aasm_model.class.send(:define_method, callback_name) do |e|
 | 
			
		||||
        @data = [e]
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      allow(aasm_model).to receive(:before_enter).and_raise(e = StandardError.new)
 | 
			
		||||
 | 
			
		||||
      aasm_model.safe_close!
 | 
			
		||||
      expect(aasm_model.data).to eql [e]
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "should run error_callback without parameters if callback does not support any" do
 | 
			
		||||
      aasm_model.class.send(:define_method, callback_name) do |e|
 | 
			
		||||
        @data = []
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      allow(aasm_model).to receive(:before_enter).and_raise(e = StandardError.new)
 | 
			
		||||
 | 
			
		||||
      aasm_model.safe_close!('arg1', 'arg2')
 | 
			
		||||
      expect(aasm_model.data).to eql []
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "should run error_callback with parameters if callback supports them" do
 | 
			
		||||
      aasm_model.class.send(:define_method, callback_name) do |e, arg1, arg2|
 | 
			
		||||
        @data = [arg1, arg2]
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      allow(aasm_model).to receive(:before_enter).and_raise(e = StandardError.new)
 | 
			
		||||
 | 
			
		||||
      aasm_model.safe_close!('arg1', 'arg2')
 | 
			
		||||
      expect(aasm_model.data).to eql ['arg1', 'arg2']
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
shared_examples 'an implemented callback' do
 | 
			
		||||
  context 'with callback defined' do
 | 
			
		||||
    it 'should run callback without parameters if callback does not support any' do
 | 
			
		||||
      aasm_model.class.send(:define_method, callback_name) do
 | 
			
		||||
        @data = ['callback-was-called']
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      aasm_model.safe_close!
 | 
			
		||||
      expect(aasm_model.data).to eql ['callback-was-called']
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it 'should run callback with parameters if callback supports them' do
 | 
			
		||||
      aasm_model.class.send(:define_method, callback_name) do |arg1, arg2|
 | 
			
		||||
        @data = [arg1, arg2]
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      aasm_model.safe_close!('arg1', 'arg2')
 | 
			
		||||
      expect(aasm_model.data).to eql ['arg1', 'arg2']
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
describe 'callbacks for the new DSL' do
 | 
			
		||||
 | 
			
		||||
  it "be called in order" do
 | 
			
		||||
| 
						 | 
				
			
			@ -10,6 +69,7 @@ describe 'callbacks for the new DSL' do
 | 
			
		|||
    callback.aasm.current_state
 | 
			
		||||
 | 
			
		||||
    unless show_debug_log
 | 
			
		||||
      expect(callback).to receive(:before_all_events).once.ordered
 | 
			
		||||
      expect(callback).to receive(:before_event).once.ordered
 | 
			
		||||
      expect(callback).to receive(:event_guard).once.ordered.and_return(true)
 | 
			
		||||
      expect(callback).to receive(:transition_guard).once.ordered.and_return(true)
 | 
			
		||||
| 
						 | 
				
			
			@ -25,6 +85,9 @@ describe 'callbacks for the new DSL' do
 | 
			
		|||
      expect(callback).to receive(:after_exit_open).once.ordered                    # these should be after the state changes
 | 
			
		||||
      expect(callback).to receive(:after_enter_closed).once.ordered
 | 
			
		||||
      expect(callback).to receive(:after_event).once.ordered
 | 
			
		||||
      expect(callback).to receive(:after_all_events).once.ordered
 | 
			
		||||
      expect(callback).to receive(:ensure_event).once.ordered
 | 
			
		||||
      expect(callback).to receive(:ensure_on_all_events).once.ordered
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # puts "------- close!"
 | 
			
		||||
| 
						 | 
				
			
			@ -35,11 +98,13 @@ describe 'callbacks for the new DSL' do
 | 
			
		|||
    callback = Callbacks::Basic.new(:log => false)
 | 
			
		||||
    callback.aasm.current_state
 | 
			
		||||
 | 
			
		||||
    expect(callback).to receive(:before_all_events).once.ordered    
 | 
			
		||||
    expect(callback).to receive(:before_event).once.ordered
 | 
			
		||||
    expect(callback).to receive(:event_guard).once.ordered.and_return(false)
 | 
			
		||||
    expect(callback).to_not receive(:transition_guard)
 | 
			
		||||
    expect(callback).to_not receive(:before_exit_open)
 | 
			
		||||
    expect(callback).to_not receive(:exit_open)
 | 
			
		||||
    expect(callback).to_not receive(:after_all_transitions)
 | 
			
		||||
    expect(callback).to_not receive(:after_transition)
 | 
			
		||||
    expect(callback).to_not receive(:before_enter_closed)
 | 
			
		||||
    expect(callback).to_not receive(:enter_closed)
 | 
			
		||||
| 
						 | 
				
			
			@ -47,6 +112,9 @@ describe 'callbacks for the new DSL' do
 | 
			
		|||
    expect(callback).to_not receive(:after_exit_open)
 | 
			
		||||
    expect(callback).to_not receive(:after_enter_closed)
 | 
			
		||||
    expect(callback).to_not receive(:after_event)
 | 
			
		||||
    expect(callback).to_not receive(:after_all_events)
 | 
			
		||||
    expect(callback).to receive(:ensure_event).once.ordered
 | 
			
		||||
    expect(callback).to receive(:ensure_on_all_events).once.ordered
 | 
			
		||||
 | 
			
		||||
    expect {
 | 
			
		||||
      callback.close!
 | 
			
		||||
| 
						 | 
				
			
			@ -72,11 +140,13 @@ describe 'callbacks for the new DSL' do
 | 
			
		|||
      callback.aasm.current_state
 | 
			
		||||
 | 
			
		||||
      unless show_debug_log
 | 
			
		||||
        expect(callback).to receive(:before_all_events).once.ordered
 | 
			
		||||
        expect(callback).to receive(:before_event).once.ordered
 | 
			
		||||
        expect(callback).to receive(:event_guard).once.ordered.and_return(true)
 | 
			
		||||
        expect(callback).to receive(:transition_guard).once.ordered.and_return(false)
 | 
			
		||||
        expect(callback).to_not receive(:before_exit_open)
 | 
			
		||||
        expect(callback).to_not receive(:exit_open)
 | 
			
		||||
        expect(callback).to_not receive(:after_all_transitions)
 | 
			
		||||
        expect(callback).to_not receive(:after_transition)
 | 
			
		||||
        expect(callback).to_not receive(:before_enter_closed)
 | 
			
		||||
        expect(callback).to_not receive(:enter_closed)
 | 
			
		||||
| 
						 | 
				
			
			@ -84,6 +154,9 @@ describe 'callbacks for the new DSL' do
 | 
			
		|||
        expect(callback).to_not receive(:after_exit_open)
 | 
			
		||||
        expect(callback).to_not receive(:after_enter_closed)
 | 
			
		||||
        expect(callback).to_not receive(:after_event)
 | 
			
		||||
        expect(callback).to_not receive(:after_all_events)
 | 
			
		||||
        expect(callback).to receive(:ensure_event).once.ordered
 | 
			
		||||
        expect(callback).to receive(:ensure_on_all_events).once.ordered
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      expect {
 | 
			
		||||
| 
						 | 
				
			
			@ -201,39 +274,9 @@ describe 'event callbacks' do
 | 
			
		|||
      @foo = Foo.new
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    context "error_callback defined" do
 | 
			
		||||
      it "should run error_callback if an exception is raised" do
 | 
			
		||||
        def @foo.error_callback(e)
 | 
			
		||||
          @data = [e]
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        allow(@foo).to receive(:before_enter).and_raise(e = StandardError.new)
 | 
			
		||||
 | 
			
		||||
        @foo.safe_close!
 | 
			
		||||
        expect(@foo.data).to eql [e]
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      it "should run error_callback without parameters if callback does not support any" do
 | 
			
		||||
        def @foo.error_callback(e)
 | 
			
		||||
          @data = []
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        allow(@foo).to receive(:before_enter).and_raise(e = StandardError.new)
 | 
			
		||||
 | 
			
		||||
        @foo.safe_close!('arg1', 'arg2')
 | 
			
		||||
        expect(@foo.data).to eql []
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      it "should run error_callback with parameters if callback supports them" do
 | 
			
		||||
        def @foo.error_callback(e, arg1, arg2)
 | 
			
		||||
          @data = [arg1, arg2]
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        allow(@foo).to receive(:before_enter).and_raise(e = StandardError.new)
 | 
			
		||||
 | 
			
		||||
        @foo.safe_close!('arg1', 'arg2')
 | 
			
		||||
        expect(@foo.data).to eql ['arg1', 'arg2']
 | 
			
		||||
      end
 | 
			
		||||
    it_behaves_like 'an implemented callback that accepts error' do
 | 
			
		||||
      let(:aasm_model) { @foo }
 | 
			
		||||
      let(:callback_name) { :error_callback }
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "should raise NoMethodError if exception is raised and error_callback is declared but not defined" do
 | 
			
		||||
| 
						 | 
				
			
			@ -242,8 +285,39 @@ describe 'event callbacks' do
 | 
			
		|||
    end
 | 
			
		||||
 | 
			
		||||
    it "should propagate an error if no error callback is declared" do
 | 
			
		||||
        allow(@foo).to receive(:before_enter).and_raise("Cannot enter safe")
 | 
			
		||||
        expect{@foo.close!}.to raise_error(StandardError, "Cannot enter safe")
 | 
			
		||||
      allow(@foo).to receive(:before_enter).and_raise("Cannot enter safe")
 | 
			
		||||
      expect{@foo.close!}.to raise_error(StandardError, "Cannot enter safe")
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  describe 'with an ensure callback defined' do
 | 
			
		||||
    before do
 | 
			
		||||
      class Foo
 | 
			
		||||
        # this hack is needed to allow testing of parameters, since RSpec
 | 
			
		||||
        # destroys a method's arity when mocked
 | 
			
		||||
        attr_accessor :data
 | 
			
		||||
 | 
			
		||||
        aasm do
 | 
			
		||||
          event :safe_close, :success => :success_callback, :ensure => :ensure_callback do
 | 
			
		||||
            transitions :to => :closed, :from => [:open]
 | 
			
		||||
          end
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      @foo = Foo.new
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it_behaves_like 'an implemented callback' do
 | 
			
		||||
      let(:aasm_model) { @foo }
 | 
			
		||||
      let(:callback_name) { :ensure_callback }
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "should raise NoMethodError if ensure_callback is declared but not defined" do
 | 
			
		||||
      expect{@foo.safe_close!}.to raise_error(NoMethodError)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "should not raise any error if no ensure_callback is declared" do
 | 
			
		||||
      expect{@foo.close!}.to_not raise_error
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -292,5 +366,76 @@ describe 'event callbacks' do
 | 
			
		|||
      @foo.close!
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
describe 'global error_on_all_events_callback callbacks' do
 | 
			
		||||
  describe "with an error_on_all_events" do
 | 
			
		||||
    before do
 | 
			
		||||
      class Foo
 | 
			
		||||
        # this hack is needed to allow testing of parameters, since RSpec
 | 
			
		||||
        # destroys a method's arity when mocked
 | 
			
		||||
        attr_accessor :data
 | 
			
		||||
 | 
			
		||||
        aasm do
 | 
			
		||||
          error_on_all_events  :error_on_all_events_callback
 | 
			
		||||
 | 
			
		||||
          event :safe_close do
 | 
			
		||||
            transitions :to => :closed, :from => [:open]
 | 
			
		||||
          end
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      @foo = Foo.new
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it_behaves_like 'an implemented callback that accepts error' do
 | 
			
		||||
      let(:aasm_model) { @foo }
 | 
			
		||||
      let(:callback_name) { :error_on_all_events_callback } 
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "should raise NoMethodError if exception is raised and error_callback is declared but not defined" do
 | 
			
		||||
      allow(@foo).to receive(:before_enter).and_raise(StandardError)
 | 
			
		||||
      expect{@foo.safe_close!}.to raise_error(NoMethodError)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "should raise NoMethodError if no error callback is declared" do
 | 
			
		||||
      allow(@foo).to receive(:before_enter).and_raise("Cannot enter safe")
 | 
			
		||||
      expect{@foo.close!}.to raise_error(NoMethodError)
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
describe 'global ensure_on_all_events_callback callbacks' do
 | 
			
		||||
  describe "with an ensure_on_all_events" do
 | 
			
		||||
    before do
 | 
			
		||||
      class Foo
 | 
			
		||||
        # this hack is needed to allow testing of parameters, since RSpec
 | 
			
		||||
        # destroys a method's arity when mocked
 | 
			
		||||
        attr_accessor :data
 | 
			
		||||
 | 
			
		||||
        aasm do
 | 
			
		||||
          ensure_on_all_events  :ensure_on_all_events_callback
 | 
			
		||||
 | 
			
		||||
          event :safe_close do
 | 
			
		||||
            transitions :to => :closed, :from => [:open]
 | 
			
		||||
          end
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      @foo = Foo.new
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it_behaves_like 'an implemented callback' do
 | 
			
		||||
      let(:aasm_model) { @foo }
 | 
			
		||||
      let(:callback_name) { :ensure_on_all_events_callback }
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "should raise NoMethodError if ensure_on_all_events callback is declared but not defined" do
 | 
			
		||||
      expect{@foo.safe_close!}.to raise_error(NoMethodError)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "should raise NoMethodError if no ensure_on_all_events callback is declared" do
 | 
			
		||||
      expect{@foo.close!}.to raise_error(NoMethodError)
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue