From 27fc466e4fc7a8e4e151b693b6d1a488698149cc Mon Sep 17 00:00:00 2001 From: Joao Vitor Date: Thu, 9 Apr 2009 01:20:53 -0300 Subject: [PATCH 1/7] Conversation is required to make spec pass --- spec/functional/conversation_spec.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/spec/functional/conversation_spec.rb b/spec/functional/conversation_spec.rb index 8fa5d4a6..e64d7bcc 100644 --- a/spec/functional/conversation_spec.rb +++ b/spec/functional/conversation_spec.rb @@ -1,3 +1,5 @@ +require File.join(File.dirname(__FILE__), 'conversation') + describe Conversation, 'description' do it '.aasm_states should contain all of the states' do Conversation.aasm_states.should == [:needs_attention, :read, :closed, :awaiting_response, :junk] From e593ec20d7ae4e857f8b6a332e303a57fdee7012 Mon Sep 17 00:00:00 2001 From: Joao Vitor Date: Thu, 9 Apr 2009 02:25:16 -0300 Subject: [PATCH 2/7] removing extra spaces --- lib/aasm.rb | 22 +++++++++++----------- lib/event.rb | 2 +- lib/persistence.rb | 4 ++-- lib/state_machine.rb | 4 ++-- lib/state_transition.rb | 2 +- spec/unit/aasm_spec.rb | 16 ++++++++-------- spec/unit/state_spec.rb | 6 +++--- spec/unit/state_transition_spec.rb | 6 +++--- 8 files changed, 31 insertions(+), 31 deletions(-) diff --git a/lib/aasm.rb b/lib/aasm.rb index fdee2ff3..6512ec89 100644 --- a/lib/aasm.rb +++ b/lib/aasm.rb @@ -13,7 +13,7 @@ class InvalidTransition < RuntimeError class UndefinedState < RuntimeError end - + def self.included(base) #:nodoc: # TODO - need to ensure that a machine is being created because # AASM was either included or arrived at via inheritance. It @@ -36,11 +36,11 @@ def aasm_initial_state(set_state=nil) AASM::StateMachine[self].initial_state end end - + def aasm_initial_state=(state) AASM::StateMachine[self].initial_state = state end - + def aasm_state(name, options={}) sm = AASM::StateMachine[self] sm.create_state(name, options) @@ -50,10 +50,10 @@ def aasm_state(name, options={}) aasm_current_state == name end end - + def aasm_event(name, options = {}, &block) sm = AASM::StateMachine[self] - + unless sm.events.has_key?(name) sm.events[name] = AASM::SupportingClasses::Event.new(name, options, &block) end @@ -74,11 +74,11 @@ def aasm_states def aasm_events AASM::StateMachine[self].events end - + def aasm_states_for_select AASM::StateMachine[self].states.map { |state| state.for_select } end - + end # Instance methods @@ -129,10 +129,10 @@ def aasm_fire_event(name, persist, *args) aasm_state_object_for_state(aasm_current_state).call_action(:exit, self) new_state = self.class.aasm_events[name].fire(self, *args) - + unless new_state.nil? aasm_state_object_for_state(new_state).call_action(:enter, self) - + persist_successful = true if persist persist_successful = set_aasm_current_state_with_persistence(new_state) @@ -141,7 +141,7 @@ def aasm_fire_event(name, persist, *args) self.aasm_current_state = new_state end - if persist_successful + if persist_successful self.aasm_event_fired(self.aasm_current_state, new_state) if self.respond_to?(:aasm_event_fired) else self.aasm_event_failed(name) if self.respond_to?(:aasm_event_failed) @@ -152,7 +152,7 @@ def aasm_fire_event(name, persist, *args) if self.respond_to?(:aasm_event_failed) self.aasm_event_failed(name) end - + false end end diff --git a/lib/event.rb b/lib/event.rb index 5589bf96..e5274848 100644 --- a/lib/event.rb +++ b/lib/event.rb @@ -4,7 +4,7 @@ module AASM module SupportingClasses class Event attr_reader :name, :success - + def initialize(name, options = {}, &block) @name = name @success = options[:success] diff --git a/lib/persistence.rb b/lib/persistence.rb index f8969645..36fe24ab 100644 --- a/lib/persistence.rb +++ b/lib/persistence.rb @@ -1,12 +1,12 @@ module AASM module Persistence - + # Checks to see this class or any of it's superclasses inherit from # ActiveRecord::Base and if so includes ActiveRecordPersistence def self.set_persistence(base) # Use a fancier auto-loading thingy, perhaps. When there are more persistence engines. hierarchy = base.ancestors.map {|klass| klass.to_s} - + if hierarchy.include?("ActiveRecord::Base") require File.join(File.dirname(__FILE__), 'persistence', 'active_record_persistence') base.send(:include, AASM::Persistence::ActiveRecordPersistence) diff --git a/lib/state_machine.rb b/lib/state_machine.rb index 672aef5c..35e10047 100644 --- a/lib/state_machine.rb +++ b/lib/state_machine.rb @@ -10,10 +10,10 @@ def self.[]=(*args) val = args.pop (@machines ||= {})[args] = val end - + attr_accessor :states, :events, :initial_state, :config attr_reader :name - + def initialize(name) @name = name @initial_state = nil diff --git a/lib/state_transition.rb b/lib/state_transition.rb index f82f5d48..960f4e30 100644 --- a/lib/state_transition.rb +++ b/lib/state_transition.rb @@ -18,7 +18,7 @@ def perform(obj) true end end - + def execute(obj, *args) case @on_transition when Symbol, String diff --git a/spec/unit/aasm_spec.rb b/spec/unit/aasm_spec.rb index 30cfe87d..6ca181ee 100644 --- a/spec/unit/aasm_spec.rb +++ b/spec/unit/aasm_spec.rb @@ -54,11 +54,11 @@ class Baz < Bar it 'should define a class level aasm_event() method on its including class' do Foo.should respond_to(:aasm_event) end - + it 'should define a class level aasm_states() method on its including class' do Foo.should respond_to(:aasm_states) end - + it 'should define a class level aasm_states_for_select() method on its including class' do Foo.should respond_to(:aasm_states_for_select) end @@ -157,7 +157,7 @@ class Baz < Bar it 'should attempt to persist if aasm_write_state is defined' do foo = Foo.new - + def foo.aasm_write_state end @@ -168,7 +168,7 @@ def foo.aasm_write_state it 'should return true if aasm_write_state is defined and returns true' do foo = Foo.new - + def foo.aasm_write_state(state) true end @@ -178,7 +178,7 @@ def foo.aasm_write_state(state) it 'should return false if aasm_write_state is defined and returns false' do foo = Foo.new - + def foo.aasm_write_state(state) false end @@ -188,7 +188,7 @@ def foo.aasm_write_state(state) it "should not update the aasm_current_state if the write fails" do foo = Foo.new - + def foo.aasm_write_state false end @@ -217,7 +217,7 @@ def foo.aasm_write_state it 'should attempt to persist if aasm_write_state is defined' do foo = Foo.new - + def foo.aasm_write_state end @@ -372,7 +372,7 @@ def wear_clothes(shirt_color, trouser_type) it 'should transition to specified next state (sleeping to showering)' do cp = ChetanPatil.new cp.wakeup! :showering - + cp.aasm_current_state.should == :showering end diff --git a/spec/unit/state_spec.rb b/spec/unit/state_spec.rb index 6eb3a8ed..b01d6984 100644 --- a/spec/unit/state_spec.rb +++ b/spec/unit/state_spec.rb @@ -16,10 +16,10 @@ def new_state(options={}) state.name.should == :astate end - + it 'should set the options and expose them as options' do state = new_state - + state.options.should == @options end @@ -56,7 +56,7 @@ def new_state(options={}) record = mock('record') record.should_receive(:foobar) - + state.call_action(:entering, record) end end diff --git a/spec/unit/state_transition_spec.rb b/spec/unit/state_transition_spec.rb index 46b32b23..ba276549 100644 --- a/spec/unit/state_transition_spec.rb +++ b/spec/unit/state_transition_spec.rb @@ -31,7 +31,7 @@ st.should_not == obj end - + it 'should fail equality check if to are not the same' do opts = {:from => 'foo', :to => 'bar', :guard => 'g'} st = AASM::SupportingClasses::StateTransition.new(opts) @@ -58,7 +58,7 @@ obj = mock('object') obj.should_receive(:test) - + st.perform(obj) end @@ -68,7 +68,7 @@ obj = mock('object') obj.should_receive(:test) - + st.perform(obj) end From f2c9c28ae704c39bfe54e7d7b048bf3ea26b6dbd Mon Sep 17 00:00:00 2001 From: Joao Vitor Date: Thu, 9 Apr 2009 02:14:02 -0300 Subject: [PATCH 3/7] Adding support to have arrays of procs, strings and symbols --- lib/event.rb | 15 ++++++++------- spec/unit/event_spec.rb | 14 ++++++++++++++ 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/lib/event.rb b/lib/event.rb index e5274848..6029e678 100644 --- a/lib/event.rb +++ b/lib/event.rb @@ -31,15 +31,16 @@ def fire(obj, to_state=nil, *args) def transitions_from_state?(state) @transitions.any? { |t| t.from == state } end - - def execute_success_callback(obj) - case success + + def execute_success_callback(obj, success = nil) + callback = success || @success + case(callback) when String, Symbol - obj.send(success) - when Array - success.each { |meth| obj.send(meth) } + obj.send(callback) when Proc - success.call(obj) + callback.call(obj) + when Array + callback.each{|meth|self.execute_success_callback(obj, meth)} end end diff --git a/spec/unit/event_spec.rb b/spec/unit/event_spec.rb index 45d42998..7dd6e96e 100644 --- a/spec/unit/event_spec.rb +++ b/spec/unit/event_spec.rb @@ -98,6 +98,20 @@ class ThisNameBetterNotBeInUse model.with_array! end + it "should call each success callback if passed an array of strings and/or symbols and/or procs" do + ThisNameBetterNotBeInUse.instance_eval { + aasm_event :with_array_including_procs, :success => [:success_callback1, 'success_callback2', lambda { |obj| obj.proc_success_callback }] do + transitions :to => :array, :from => [:initial] + end + } + + model = ThisNameBetterNotBeInUse.new + model.should_receive(:success_callback1) + model.should_receive(:success_callback2) + model.should_receive(:proc_success_callback) + model.with_array_including_procs! + end + it "should call the success callback if it's a proc" do ThisNameBetterNotBeInUse.instance_eval { aasm_event :with_proc, :success => lambda { |obj| obj.proc_success_callback } do From bd338c76efa95f110a4c4615098ee5ebacd15f6b Mon Sep 17 00:00:00 2001 From: Joao Vitor Date: Thu, 9 Apr 2009 02:23:02 -0300 Subject: [PATCH 4/7] Changing signature of aasm_event_fired and aasm_event_failed. And ensuring that aasm_event_fired receive event, old_state and new_state --- lib/aasm.rb | 7 ++-- spec/unit/aasm_spec.rb | 78 +++++++++++++++++------------------------- 2 files changed, 36 insertions(+), 49 deletions(-) diff --git a/lib/aasm.rb b/lib/aasm.rb index 6512ec89..972cc6c2 100644 --- a/lib/aasm.rb +++ b/lib/aasm.rb @@ -128,6 +128,7 @@ def aasm_state_object_for_state(name) def aasm_fire_event(name, persist, *args) aasm_state_object_for_state(aasm_current_state).call_action(:exit, self) + old_state = self.aasm_current_state new_state = self.class.aasm_events[name].fire(self, *args) unless new_state.nil? @@ -142,15 +143,15 @@ def aasm_fire_event(name, persist, *args) end if persist_successful - self.aasm_event_fired(self.aasm_current_state, new_state) if self.respond_to?(:aasm_event_fired) + self.aasm_event_fired(name, old_state, self.aasm_current_state) if self.respond_to?(:aasm_event_fired) else - self.aasm_event_failed(name) if self.respond_to?(:aasm_event_failed) + self.aasm_event_failed(name, old_state) if self.respond_to?(:aasm_event_failed) end persist_successful else if self.respond_to?(:aasm_event_failed) - self.aasm_event_failed(name) + self.aasm_event_failed(name, old_state) end false diff --git a/spec/unit/aasm_spec.rb b/spec/unit/aasm_spec.rb index 6ca181ee..81576ee1 100644 --- a/spec/unit/aasm_spec.rb +++ b/spec/unit/aasm_spec.rb @@ -255,66 +255,52 @@ def foo.aasm_read_state end describe AASM, '- event callbacks' do - it 'should call aasm_event_fired if defined and successful for bang fire' do - foo = Foo.new - def foo.aasm_event_fired(from, to) + describe "with aasm_event_fired defined" do + before do + @foo = Foo.new + def @foo.aasm_event_fired(event, from, to) + end end - foo.should_receive(:aasm_event_fired) - - foo.close! - end - - it 'should not call aasm_event_fired if defined but persist fails for bang fire' do - foo = Foo.new - def foo.aasm_event_fired(from, to) + it 'should call it for successful bang fire' do + @foo.should_receive(:aasm_event_fired).with(:close, :open, :closed) + @foo.close! end - foo.stub!(:set_aasm_current_state_with_persistence).and_return(false) - - foo.should_not_receive(:aasm_event_fired) - foo.close! - end - - it 'should not call aasm_event_failed if defined and persist fails for bang fire' do - foo = Foo.new - def foo.aasm_event_failed(from, to) + it 'should call it for successful non-bang fire' do + @foo.should_receive(:aasm_event_fired) + @foo.close end - foo.stub!(:set_aasm_current_state_with_persistence).and_return(false) - - foo.should_receive(:aasm_event_failed) - - foo.close! - end - it 'should call aasm_event_fired if defined and successful for non-bang fire' do - foo = Foo.new - def foo.aasm_event_fired(from, to) + it 'should not call it for failing bang fire' do + @foo.stub!(:set_aasm_current_state_with_persistence).and_return(false) + @foo.should_not_receive(:aasm_event_fired) + @foo.close! end - - foo.should_receive(:aasm_event_fired) - - foo.close end - it 'should call aasm_event_failed if defined and transition failed for bang fire' do - foo = Foo.new - def foo.aasm_event_failed(event) + describe "with aasm_event_failed defined" do + before do + @foo = Foo.new + def @foo.aasm_event_failed(event, from) + end end - foo.should_receive(:aasm_event_failed) - - foo.null! - end - - it 'should call aasm_event_failed if defined and transition failed for non-bang fire' do - foo = Foo.new - def foo.aasm_event_failed(event) + it 'should call it when transition failed for bang fire' do + @foo.should_receive(:aasm_event_failed).with(:null, :open) + @foo.null! end - foo.should_receive(:aasm_event_failed) + it 'should call it when transition failed for non-bang fire' do + @foo.should_receive(:aasm_event_failed).with(:null, :open) + @foo.null + end - foo.null + it 'should not call it if persist fails for bang fire' do + @foo.stub!(:set_aasm_current_state_with_persistence).and_return(false) + @foo.should_receive(:aasm_event_failed) + @foo.close! + end end end From 14baaf6a1e9e4ebbb460debe24e24be50c7f7820 Mon Sep 17 00:00:00 2001 From: Joao Vitor Date: Thu, 9 Apr 2009 10:32:59 -0300 Subject: [PATCH 5/7] changing version --- lib/aasm.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/aasm.rb b/lib/aasm.rb index 972cc6c2..71a9ec24 100644 --- a/lib/aasm.rb +++ b/lib/aasm.rb @@ -5,7 +5,7 @@ module AASM def self.Version - '2.0.5' + '2.0.6' end class InvalidTransition < RuntimeError From b56c3e90674f75d73344f4eb4cfb94c51c285d43 Mon Sep 17 00:00:00 2001 From: joaovitor Date: Thu, 9 Apr 2009 06:51:23 -0700 Subject: [PATCH 6/7] changing version --- aasm.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aasm.gemspec b/aasm.gemspec index 0e8ae535..350fc1fc 100644 --- a/aasm.gemspec +++ b/aasm.gemspec @@ -2,7 +2,7 @@ PKG_FILES = ["CHANGELOG", "MIT-LICENSE", "Rakefile", "README.rdoc", "TODO", "lib Gem::Specification.new do |s| s.name = 'aasm' - s.version = "2.0.5" + s.version = "2.0.6" s.summary = 'State machine mixin for Ruby objects' s.description = <<-EOF AASM is a continuation of the acts as state machine rails plugin, built for plain Ruby objects. From 220b8f84e47ea39a0ed22e10b722696d6beee346 Mon Sep 17 00:00:00 2001 From: Joao Vitor Date: Sat, 23 May 2009 05:00:20 -0300 Subject: [PATCH 7/7] Removing lib/version.rb of package list --- aasm.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aasm.gemspec b/aasm.gemspec index 350fc1fc..8a2d99ef 100644 --- a/aasm.gemspec +++ b/aasm.gemspec @@ -1,4 +1,4 @@ -PKG_FILES = ["CHANGELOG", "MIT-LICENSE", "Rakefile", "README.rdoc", "TODO", "lib/aasm.rb", "lib/event.rb", "lib/persistence/active_record_persistence.rb", "lib/persistence.rb", "lib/state.rb", "lib/state_machine.rb", "lib/state_transition.rb", "lib/version.rb", "doc/jamis.rb"] +PKG_FILES = ["CHANGELOG", "MIT-LICENSE", "Rakefile", "README.rdoc", "TODO", "lib/aasm.rb", "lib/event.rb", "lib/persistence/active_record_persistence.rb", "lib/persistence.rb", "lib/state.rb", "lib/state_machine.rb", "lib/state_transition.rb", "doc/jamis.rb"] Gem::Specification.new do |s| s.name = 'aasm'