aasm 2.1.3 → 2.1.4
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +0 -1
- data/README.rdoc +6 -1
- data/VERSION +1 -1
- data/lib/aasm.rb +8 -0
- data/lib/aasm/aasm.rb +36 -36
- data/lib/aasm/event.rb +92 -81
- data/lib/aasm/persistence.rb +9 -11
- data/lib/aasm/state.rb +49 -51
- data/lib/aasm/state_machine.rb +25 -29
- data/lib/aasm/state_transition.rb +42 -46
- data/lib/aasm/supporting_classes.rb +6 -0
- data/spec/unit/aasm_spec.rb +31 -1
- data/spec/unit/state_spec.rb +11 -0
- metadata +3 -2
data/.gitignore
CHANGED
data/README.rdoc
CHANGED
@@ -54,7 +54,8 @@ The latest AASM can currently be pulled from the git repository on github.
|
|
54
54
|
|
55
55
|
=== Building your own gems
|
56
56
|
|
57
|
-
% rake
|
57
|
+
% rake gemspec
|
58
|
+
% rake build
|
58
59
|
% sudo gem install pkg/aasm-2.1.gem
|
59
60
|
|
60
61
|
|
@@ -65,6 +66,8 @@ Here's a quick example highlighting some of the features.
|
|
65
66
|
class Conversation
|
66
67
|
include AASM
|
67
68
|
|
69
|
+
aasm_column :current_state # defaults to aasm_state
|
70
|
+
|
68
71
|
aasm_initial_state :unread
|
69
72
|
|
70
73
|
aasm_state :unread
|
@@ -87,6 +90,8 @@ This example uses a few of the more complex features available.
|
|
87
90
|
|
88
91
|
class Relationship
|
89
92
|
include AASM
|
93
|
+
|
94
|
+
aasm_column :status
|
90
95
|
|
91
96
|
aasm_initial_state Proc.new { |relationship| relationship.strictly_for_fun? ? :intimate : :dating }
|
92
97
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.1.
|
1
|
+
2.1.4
|
data/lib/aasm.rb
CHANGED
@@ -1 +1,9 @@
|
|
1
|
+
module AASM
|
2
|
+
end
|
3
|
+
|
4
|
+
require 'ostruct'
|
5
|
+
|
6
|
+
require File.join(File.dirname(__FILE__), 'aasm', 'supporting_classes')
|
7
|
+
require File.join(File.dirname(__FILE__), 'aasm', 'state_machine')
|
8
|
+
require File.join(File.dirname(__FILE__), 'aasm', 'persistence')
|
1
9
|
require File.join(File.dirname(__FILE__), 'aasm', 'aasm')
|
data/lib/aasm/aasm.rb
CHANGED
@@ -1,8 +1,3 @@
|
|
1
|
-
require File.join(File.dirname(__FILE__), 'event')
|
2
|
-
require File.join(File.dirname(__FILE__), 'state')
|
3
|
-
require File.join(File.dirname(__FILE__), 'state_machine')
|
4
|
-
require File.join(File.dirname(__FILE__), 'persistence')
|
5
|
-
|
6
1
|
module AASM
|
7
2
|
class InvalidTransition < RuntimeError
|
8
3
|
end
|
@@ -146,50 +141,55 @@ module AASM
|
|
146
141
|
end
|
147
142
|
|
148
143
|
def aasm_fire_event(name, persist, *args)
|
149
|
-
old_state = aasm_state_object_for_state(aasm_current_state)
|
150
144
|
event = self.class.aasm_events[name]
|
145
|
+
begin
|
146
|
+
old_state = aasm_state_object_for_state(aasm_current_state)
|
151
147
|
|
152
|
-
old_state.call_action(:exit, self)
|
153
148
|
|
154
|
-
|
155
|
-
event.call_action(:before, self)
|
149
|
+
old_state.call_action(:exit, self)
|
156
150
|
|
157
|
-
|
151
|
+
# new event before callback
|
152
|
+
event.call_action(:before, self)
|
158
153
|
|
159
|
-
|
160
|
-
new_state = aasm_state_object_for_state(new_state_name)
|
154
|
+
new_state_name = event.fire(self, *args)
|
161
155
|
|
162
|
-
|
163
|
-
|
164
|
-
new_state.call_action(:before_enter, self)
|
156
|
+
unless new_state_name.nil?
|
157
|
+
new_state = aasm_state_object_for_state(new_state_name)
|
165
158
|
|
166
|
-
|
159
|
+
# new before_ callbacks
|
160
|
+
old_state.call_action(:before_exit, self)
|
161
|
+
new_state.call_action(:before_enter, self)
|
167
162
|
|
168
|
-
|
169
|
-
|
170
|
-
persist_successful =
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
163
|
+
new_state.call_action(:enter, self)
|
164
|
+
|
165
|
+
persist_successful = true
|
166
|
+
if persist
|
167
|
+
persist_successful = set_aasm_current_state_with_persistence(new_state_name)
|
168
|
+
event.execute_success_callback(self) if persist_successful
|
169
|
+
else
|
170
|
+
self.aasm_current_state = new_state_name
|
171
|
+
end
|
175
172
|
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
173
|
+
if persist_successful
|
174
|
+
old_state.call_action(:after_exit, self)
|
175
|
+
new_state.call_action(:after_enter, self)
|
176
|
+
event.call_action(:after, self)
|
180
177
|
|
181
|
-
|
178
|
+
self.aasm_event_fired(name, old_state.name, self.aasm_current_state) if self.respond_to?(:aasm_event_fired)
|
179
|
+
else
|
180
|
+
self.aasm_event_failed(name, old_state.name) if self.respond_to?(:aasm_event_failed)
|
181
|
+
end
|
182
|
+
|
183
|
+
persist_successful
|
182
184
|
else
|
183
|
-
|
184
|
-
|
185
|
+
if self.respond_to?(:aasm_event_failed)
|
186
|
+
self.aasm_event_failed(name, old_state.name)
|
187
|
+
end
|
185
188
|
|
186
|
-
|
187
|
-
else
|
188
|
-
if self.respond_to?(:aasm_event_failed)
|
189
|
-
self.aasm_event_failed(name, old_state.name)
|
189
|
+
false
|
190
190
|
end
|
191
|
-
|
192
|
-
|
191
|
+
rescue StandardError => e
|
192
|
+
event.execute_error_callback(self, e)
|
193
193
|
end
|
194
194
|
end
|
195
195
|
end
|
data/lib/aasm/event.rb
CHANGED
@@ -1,98 +1,109 @@
|
|
1
|
-
|
1
|
+
class AASM::SupportingClasses::Event
|
2
|
+
attr_reader :name, :success, :options
|
2
3
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
def initialize(name, options = {}, &block)
|
9
|
-
@name = name
|
10
|
-
@transitions = []
|
11
|
-
update(options, &block)
|
12
|
-
end
|
4
|
+
def initialize(name, options = {}, &block)
|
5
|
+
@name = name
|
6
|
+
@transitions = []
|
7
|
+
update(options, &block)
|
8
|
+
end
|
13
9
|
|
14
|
-
|
15
|
-
|
16
|
-
|
10
|
+
def fire(obj, to_state=nil, *args)
|
11
|
+
transitions = @transitions.select { |t| t.from == obj.aasm_current_state }
|
12
|
+
raise AASM::InvalidTransition, "Event '#{name}' cannot transition from '#{obj.aasm_current_state}'" if transitions.size == 0
|
17
13
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
end
|
26
|
-
end
|
27
|
-
next_state
|
14
|
+
next_state = nil
|
15
|
+
transitions.each do |transition|
|
16
|
+
next if to_state and !Array(transition.to).include?(to_state)
|
17
|
+
if transition.perform(obj)
|
18
|
+
next_state = to_state || Array(transition.to).first
|
19
|
+
transition.execute(obj, *args)
|
20
|
+
break
|
28
21
|
end
|
22
|
+
end
|
23
|
+
next_state
|
24
|
+
end
|
29
25
|
|
30
|
-
|
31
|
-
|
32
|
-
|
26
|
+
def transitions_from_state?(state)
|
27
|
+
@transitions.any? { |t| t.from == state }
|
28
|
+
end
|
33
29
|
|
34
|
-
|
35
|
-
|
36
|
-
|
30
|
+
def transitions_from_state(state)
|
31
|
+
@transitions.select { |t| t.from == state }
|
32
|
+
end
|
37
33
|
|
38
|
-
|
39
|
-
|
40
|
-
|
34
|
+
def all_transitions
|
35
|
+
@transitions
|
36
|
+
end
|
41
37
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
38
|
+
def call_action(action, record)
|
39
|
+
action = @options[action]
|
40
|
+
action.is_a?(Array) ?
|
41
|
+
action.each {|a| _call_action(a, record)} :
|
42
|
+
_call_action(action, record)
|
43
|
+
end
|
48
44
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
45
|
+
def ==(event)
|
46
|
+
if event.is_a? Symbol
|
47
|
+
name == event
|
48
|
+
else
|
49
|
+
name == event.name
|
50
|
+
end
|
51
|
+
end
|
56
52
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
53
|
+
def update(options = {}, &block)
|
54
|
+
if options.key?(:success) then
|
55
|
+
@success = options[:success]
|
56
|
+
end
|
57
|
+
if options.key?(:error) then
|
58
|
+
@error = options[:error]
|
59
|
+
end
|
60
|
+
if block then
|
61
|
+
instance_eval(&block)
|
62
|
+
end
|
63
|
+
@options = options
|
64
|
+
self
|
65
|
+
end
|
67
66
|
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
67
|
+
def execute_success_callback(obj, success = nil)
|
68
|
+
callback = success || @success
|
69
|
+
case(callback)
|
70
|
+
when String, Symbol
|
71
|
+
obj.send(callback)
|
72
|
+
when Proc
|
73
|
+
callback.call(obj)
|
74
|
+
when Array
|
75
|
+
callback.each{|meth|self.execute_success_callback(obj, meth)}
|
76
|
+
end
|
77
|
+
end
|
79
78
|
|
80
|
-
|
79
|
+
def execute_error_callback(obj, error, error_callback=nil)
|
80
|
+
callback = error_callback || @error
|
81
|
+
raise error unless callback
|
82
|
+
case(callback)
|
83
|
+
when String, Symbol
|
84
|
+
raise NoMethodError unless obj.respond_to?(callback.to_sym)
|
85
|
+
obj.send(callback, error)
|
86
|
+
when Proc
|
87
|
+
callback.call(obj, error)
|
88
|
+
when Array
|
89
|
+
callback.each{|meth|self.execute_error_callback(obj, error, meth)}
|
90
|
+
end
|
91
|
+
end
|
81
92
|
|
82
|
-
|
83
|
-
case action
|
84
|
-
when Symbol, String
|
85
|
-
record.send(action)
|
86
|
-
when Proc
|
87
|
-
action.call(record)
|
88
|
-
end
|
89
|
-
end
|
93
|
+
private
|
90
94
|
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
95
|
+
def _call_action(action, record)
|
96
|
+
case action
|
97
|
+
when Symbol, String
|
98
|
+
record.send(action)
|
99
|
+
when Proc
|
100
|
+
action.call(record)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
def transitions(trans_opts)
|
105
|
+
Array(trans_opts[:from]).each do |s|
|
106
|
+
@transitions << AASM::SupportingClasses::StateTransition.new(trans_opts.merge({:from => s.to_sym}))
|
96
107
|
end
|
97
108
|
end
|
98
109
|
end
|
data/lib/aasm/persistence.rb
CHANGED
@@ -1,16 +1,14 @@
|
|
1
|
-
module AASM
|
2
|
-
module Persistence
|
1
|
+
module AASM::Persistence
|
3
2
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
3
|
+
# Checks to see this class or any of it's superclasses inherit from
|
4
|
+
# ActiveRecord::Base and if so includes ActiveRecordPersistence
|
5
|
+
def self.set_persistence(base)
|
6
|
+
# Use a fancier auto-loading thingy, perhaps. When there are more persistence engines.
|
7
|
+
hierarchy = base.ancestors.map {|klass| klass.to_s}
|
9
8
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
end
|
9
|
+
if hierarchy.include?("ActiveRecord::Base")
|
10
|
+
require File.join(File.dirname(__FILE__), 'persistence', 'active_record_persistence')
|
11
|
+
base.send(:include, AASM::Persistence::ActiveRecordPersistence)
|
14
12
|
end
|
15
13
|
end
|
16
14
|
end
|
data/lib/aasm/state.rb
CHANGED
@@ -1,55 +1,53 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
class State
|
4
|
-
attr_reader :name, :options
|
5
|
-
|
6
|
-
def initialize(name, options={})
|
7
|
-
@name = name
|
8
|
-
update(options)
|
9
|
-
end
|
10
|
-
|
11
|
-
def ==(state)
|
12
|
-
if state.is_a? Symbol
|
13
|
-
name == state
|
14
|
-
else
|
15
|
-
name == state.name
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
def call_action(action, record)
|
20
|
-
action = @options[action]
|
21
|
-
action.is_a?(Array) ?
|
22
|
-
action.each {|a| _call_action(a, record)} :
|
23
|
-
_call_action(action, record)
|
24
|
-
end
|
25
|
-
|
26
|
-
def display_name
|
27
|
-
@display_name ||= name.to_s.gsub(/_/, ' ').capitalize
|
28
|
-
end
|
29
|
-
|
30
|
-
def for_select
|
31
|
-
[display_name, name.to_s]
|
32
|
-
end
|
33
|
-
|
34
|
-
def update(options = {})
|
35
|
-
if options.key?(:display) then
|
36
|
-
@display_name = options.delete(:display)
|
37
|
-
end
|
38
|
-
@options = options
|
39
|
-
self
|
40
|
-
end
|
41
|
-
|
42
|
-
private
|
43
|
-
|
44
|
-
def _call_action(action, record)
|
45
|
-
case action
|
46
|
-
when Symbol, String
|
47
|
-
record.send(action)
|
48
|
-
when Proc
|
49
|
-
action.call(record)
|
50
|
-
end
|
51
|
-
end
|
1
|
+
class AASM::SupportingClasses::State
|
2
|
+
attr_reader :name, :options
|
52
3
|
|
4
|
+
def initialize(name, options={})
|
5
|
+
@name = name
|
6
|
+
update(options)
|
7
|
+
end
|
8
|
+
|
9
|
+
def ==(state)
|
10
|
+
if state.is_a? Symbol
|
11
|
+
name == state
|
12
|
+
else
|
13
|
+
name == state.name
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def call_action(action, record)
|
18
|
+
action = @options[action]
|
19
|
+
catch :halt_aasm_chain do
|
20
|
+
action.is_a?(Array) ?
|
21
|
+
action.each {|a| _call_action(a, record)} :
|
22
|
+
_call_action(action, record)
|
53
23
|
end
|
54
24
|
end
|
25
|
+
|
26
|
+
def display_name
|
27
|
+
@display_name ||= name.to_s.gsub(/_/, ' ').capitalize
|
28
|
+
end
|
29
|
+
|
30
|
+
def for_select
|
31
|
+
[display_name, name.to_s]
|
32
|
+
end
|
33
|
+
|
34
|
+
def update(options = {})
|
35
|
+
if options.key?(:display) then
|
36
|
+
@display_name = options.delete(:display)
|
37
|
+
end
|
38
|
+
@options = options
|
39
|
+
self
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
def _call_action(action, record)
|
45
|
+
case action
|
46
|
+
when Symbol, String
|
47
|
+
record.send(action)
|
48
|
+
when Proc
|
49
|
+
action.call(record)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
55
53
|
end
|
data/lib/aasm/state_machine.rb
CHANGED
@@ -1,36 +1,32 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
def self.[](*args)
|
6
|
-
(@machines ||= {})[args]
|
7
|
-
end
|
1
|
+
class AASM::StateMachine
|
2
|
+
def self.[](*args)
|
3
|
+
(@machines ||= {})[args]
|
4
|
+
end
|
8
5
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
6
|
+
def self.[]=(*args)
|
7
|
+
val = args.pop
|
8
|
+
(@machines ||= {})[args] = val
|
9
|
+
end
|
13
10
|
|
14
|
-
|
15
|
-
|
11
|
+
attr_accessor :states, :events, :initial_state, :config
|
12
|
+
attr_reader :name
|
16
13
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
14
|
+
def initialize(name)
|
15
|
+
@name = name
|
16
|
+
@initial_state = nil
|
17
|
+
@states = []
|
18
|
+
@events = {}
|
19
|
+
@config = OpenStruct.new
|
20
|
+
end
|
24
21
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
22
|
+
def clone
|
23
|
+
klone = super
|
24
|
+
klone.states = states.clone
|
25
|
+
klone.events = events.clone
|
26
|
+
klone
|
27
|
+
end
|
31
28
|
|
32
|
-
|
33
|
-
|
34
|
-
end
|
29
|
+
def create_state(name, options)
|
30
|
+
@states << AASM::SupportingClasses::State.new(name, options) unless @states.include?(name)
|
35
31
|
end
|
36
32
|
end
|
@@ -1,50 +1,46 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
attr_reader :from, :to, :opts
|
5
|
-
alias_method :options, :opts
|
6
|
-
|
7
|
-
def initialize(opts)
|
8
|
-
@from, @to, @guard, @on_transition = opts[:from], opts[:to], opts[:guard], opts[:on_transition]
|
9
|
-
@opts = opts
|
10
|
-
end
|
11
|
-
|
12
|
-
def perform(obj)
|
13
|
-
case @guard
|
14
|
-
when Symbol, String
|
15
|
-
obj.send(@guard)
|
16
|
-
when Proc
|
17
|
-
@guard.call(obj)
|
18
|
-
else
|
19
|
-
true
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
def execute(obj, *args)
|
24
|
-
@on_transition.is_a?(Array) ?
|
25
|
-
@on_transition.each {|ot| _execute(obj, ot, *args)} :
|
26
|
-
_execute(obj, @on_transition, *args)
|
27
|
-
end
|
28
|
-
|
29
|
-
def ==(obj)
|
30
|
-
@from == obj.from && @to == obj.to
|
31
|
-
end
|
32
|
-
|
33
|
-
def from?(value)
|
34
|
-
@from == value
|
35
|
-
end
|
36
|
-
|
37
|
-
private
|
38
|
-
|
39
|
-
def _execute(obj, on_transition, *args)
|
40
|
-
case on_transition
|
41
|
-
when Symbol, String
|
42
|
-
obj.send(on_transition, *args)
|
43
|
-
when Proc
|
44
|
-
on_transition.call(obj, *args)
|
45
|
-
end
|
46
|
-
end
|
1
|
+
class AASM::SupportingClasses::StateTransition
|
2
|
+
attr_reader :from, :to, :opts
|
3
|
+
alias_method :options, :opts
|
47
4
|
|
5
|
+
def initialize(opts)
|
6
|
+
@from, @to, @guard, @on_transition = opts[:from], opts[:to], opts[:guard], opts[:on_transition]
|
7
|
+
@opts = opts
|
8
|
+
end
|
9
|
+
|
10
|
+
def perform(obj)
|
11
|
+
case @guard
|
12
|
+
when Symbol, String
|
13
|
+
obj.send(@guard)
|
14
|
+
when Proc
|
15
|
+
@guard.call(obj)
|
16
|
+
else
|
17
|
+
true
|
48
18
|
end
|
49
19
|
end
|
20
|
+
|
21
|
+
def execute(obj, *args)
|
22
|
+
@on_transition.is_a?(Array) ?
|
23
|
+
@on_transition.each {|ot| _execute(obj, ot, *args)} :
|
24
|
+
_execute(obj, @on_transition, *args)
|
25
|
+
end
|
26
|
+
|
27
|
+
def ==(obj)
|
28
|
+
@from == obj.from && @to == obj.to
|
29
|
+
end
|
30
|
+
|
31
|
+
def from?(value)
|
32
|
+
@from == value
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def _execute(obj, on_transition, *args)
|
38
|
+
case on_transition
|
39
|
+
when Symbol, String
|
40
|
+
obj.send(on_transition, *args)
|
41
|
+
when Proc
|
42
|
+
on_transition.call(obj, *args)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
50
46
|
end
|
data/spec/unit/aasm_spec.rb
CHANGED
@@ -92,7 +92,7 @@ describe AASM, '- subclassing' do
|
|
92
92
|
FooTwo.aasm_states.should include(state)
|
93
93
|
end
|
94
94
|
end
|
95
|
-
|
95
|
+
|
96
96
|
it 'should not add the child states to the parent machine' do
|
97
97
|
Foo.aasm_states.should_not include(:foo)
|
98
98
|
end
|
@@ -270,6 +270,36 @@ describe AASM, '- getting events for a state' do
|
|
270
270
|
end
|
271
271
|
|
272
272
|
describe AASM, '- event callbacks' do
|
273
|
+
describe "with an error callback defined" do
|
274
|
+
before do
|
275
|
+
class Foo
|
276
|
+
aasm_event :safe_close, :success => :success_callback, :error => :error_callback do
|
277
|
+
transitions :to => :closed, :from => [:open]
|
278
|
+
end
|
279
|
+
end
|
280
|
+
|
281
|
+
@foo = Foo.new
|
282
|
+
end
|
283
|
+
|
284
|
+
it "should run error_callback if an exception is raised and error_callback defined" do
|
285
|
+
def @foo.error_callback(e)
|
286
|
+
end
|
287
|
+
@foo.stub!(:enter).and_raise(e=StandardError.new)
|
288
|
+
@foo.should_receive(:error_callback).with(e)
|
289
|
+
@foo.safe_close!
|
290
|
+
end
|
291
|
+
|
292
|
+
it "should raise NoMethodError if exceptionis raised and error_callback is declared but not defined" do
|
293
|
+
@foo.stub!(:enter).and_raise(StandardError)
|
294
|
+
lambda{@foo.safe_close!}.should raise_error(NoMethodError)
|
295
|
+
end
|
296
|
+
|
297
|
+
it "should propagate an error if no error callback is declared" do
|
298
|
+
@foo.stub!(:enter).and_raise("Cannot enter safe")
|
299
|
+
lambda{@foo.close!}.should raise_error(StandardError, "Cannot enter safe")
|
300
|
+
end
|
301
|
+
end
|
302
|
+
|
273
303
|
describe "with aasm_event_fired defined" do
|
274
304
|
before do
|
275
305
|
@foo = Foo.new
|
data/spec/unit/state_spec.rb
CHANGED
@@ -63,6 +63,17 @@ describe AASM::SupportingClasses::State do
|
|
63
63
|
state.call_action(:entering, record)
|
64
64
|
end
|
65
65
|
|
66
|
+
it "should stop calling actions if one of them raises :halt_aasm_chain" do
|
67
|
+
state = new_state(:entering => [:a, :b, :c])
|
68
|
+
|
69
|
+
record = mock('record')
|
70
|
+
record.should_receive(:a)
|
71
|
+
record.should_receive(:b).and_throw(:halt_aasm_chain)
|
72
|
+
record.should_not_receive(:c)
|
73
|
+
|
74
|
+
state.call_action(:entering, record)
|
75
|
+
end
|
76
|
+
|
66
77
|
it 'should call a proc, passing in the record for an action if the action is present' do
|
67
78
|
state = new_state(:entering => Proc.new {|r| r.foobar})
|
68
79
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: aasm
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.1.
|
4
|
+
version: 2.1.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Scott Barron
|
@@ -11,7 +11,7 @@ autorequire:
|
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
13
|
|
14
|
-
date:
|
14
|
+
date: 2010-01-17 00:00:00 -05:00
|
15
15
|
default_executable:
|
16
16
|
dependencies:
|
17
17
|
- !ruby/object:Gem::Dependency
|
@@ -68,6 +68,7 @@ files:
|
|
68
68
|
- lib/aasm/state.rb
|
69
69
|
- lib/aasm/state_machine.rb
|
70
70
|
- lib/aasm/state_transition.rb
|
71
|
+
- lib/aasm/supporting_classes.rb
|
71
72
|
- spec/functional/conversation.rb
|
72
73
|
- spec/functional/conversation_spec.rb
|
73
74
|
- spec/spec_helper.rb
|