Skip to content

Commit

Permalink
Merge branch 'joaovitor/master'
Browse files Browse the repository at this point in the history
Conflicts:
	spec/functional/conversation_spec.rb
  • Loading branch information
Travis Tilley committed May 27, 2009
2 parents 792d5f0 + 220b8f8 commit 56af04d
Show file tree
Hide file tree
Showing 11 changed files with 94 additions and 90 deletions.
4 changes: 2 additions & 2 deletions aasm.gemspec
@@ -1,8 +1,8 @@
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'
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.
Expand Down
31 changes: 16 additions & 15 deletions lib/aasm.rb
Expand Up @@ -5,15 +5,15 @@

module AASM
def self.Version
'2.0.5'
'2.0.6'
end

class InvalidTransition < RuntimeError
end

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
Expand All @@ -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)
Expand All @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -128,11 +128,12 @@ 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?
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)
Expand All @@ -141,18 +142,18 @@ def aasm_fire_event(name, persist, *args)
self.aasm_current_state = new_state
end

if persist_successful
self.aasm_event_fired(self.aasm_current_state, new_state) if self.respond_to?(:aasm_event_fired)
if persist_successful
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
end
end
Expand Down
17 changes: 9 additions & 8 deletions lib/event.rb
Expand Up @@ -4,7 +4,7 @@ module AASM
module SupportingClasses
class Event
attr_reader :name, :success

def initialize(name, options = {}, &block)
@name = name
@success = options[:success]
Expand All @@ -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

Expand Down
4 changes: 2 additions & 2 deletions 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)
Expand Down
4 changes: 2 additions & 2 deletions lib/state_machine.rb
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion lib/state_transition.rb
Expand Up @@ -18,7 +18,7 @@ def perform(obj)
true
end
end

def execute(obj, *args)
case @on_transition
when Symbol, String
Expand Down
2 changes: 2 additions & 0 deletions spec/functional/conversation_spec.rb
@@ -1,4 +1,6 @@
require File.join(File.dirname(__FILE__), "..", "spec_helper")
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]
Expand Down
94 changes: 40 additions & 54 deletions spec/unit/aasm_spec.rb
Expand Up @@ -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
Expand Down Expand Up @@ -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

Expand All @@ -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
Expand All @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -372,7 +358,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

Expand Down
14 changes: 14 additions & 0 deletions spec/unit/event_spec.rb
Expand Up @@ -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
Expand Down
6 changes: 3 additions & 3 deletions spec/unit/state_spec.rb
Expand Up @@ -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

Expand Down Expand Up @@ -56,7 +56,7 @@ def new_state(options={})

record = mock('record')
record.should_receive(:foobar)

state.call_action(:entering, record)
end
end

0 comments on commit 56af04d

Please sign in to comment.