aasm 3.0.14 → 3.0.15

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,6 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe 'AuthMachine on initialization' do
3
+ describe 'on initialization' do
4
4
  let(:auth) {AuthMachine.new}
5
5
 
6
6
  it 'should be in the pending state' do
@@ -13,7 +13,7 @@ describe 'AuthMachine on initialization' do
13
13
  end
14
14
  end
15
15
 
16
- describe 'AuthMachine when being unsuspended' do
16
+ describe 'when being unsuspended' do
17
17
  let(:auth) {AuthMachine.new}
18
18
 
19
19
  it 'should be able to be unsuspended' do
@@ -0,0 +1,28 @@
1
+ require 'spec_helper'
2
+
3
+ class Banker
4
+ include AASM
5
+ aasm do
6
+ state :retired
7
+ state :selling_bad_mortgages
8
+ end
9
+ aasm_initial_state Proc.new { |banker| banker.rich? ? :retired : :selling_bad_mortgages }
10
+ RICH = 1_000_000
11
+ attr_accessor :balance
12
+ def initialize(balance = 0); self.balance = balance; end
13
+ def rich?; self.balance >= RICH; end
14
+ end
15
+
16
+ describe 'initial states' do
17
+ let(:bar) {Bar.new}
18
+
19
+ it 'should use the first state defined if no initial state is given' do
20
+ bar.aasm_current_state.should == :read
21
+ # bar.aasm.current_state.should == :read # not yet supported
22
+ end
23
+
24
+ it 'should determine initial state from the Proc results' do
25
+ Banker.new(Banker::RICH - 1).aasm_current_state.should == :selling_bad_mortgages
26
+ Banker.new(Banker::RICH + 1).aasm_current_state.should == :retired
27
+ end
28
+ end
@@ -1,7 +1,79 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe 'inspecting AASM' do
4
- it 'should support listing all states in the order they have been defined' do
5
- Conversation.aasm_states.should == [:needs_attention, :read, :closed, :awaiting_response, :junk]
3
+ describe 'inspection for common cases' do
4
+ it 'should support the old DSL' do
5
+ Foo.should respond_to(:aasm_states)
6
+ Foo.aasm_states.should include(:open)
7
+ Foo.aasm_states.should include(:closed)
8
+
9
+ Foo.should respond_to(:aasm_initial_state)
10
+ Foo.aasm_initial_state.should == :open
11
+
12
+ Foo.should respond_to(:aasm_events)
13
+ Foo.aasm_events.should include(:close)
14
+ Foo.aasm_events.should include(:null)
15
+ end
16
+
17
+ it 'should support the new DSL' do
18
+ Foo.aasm.should respond_to(:states)
19
+ Foo.aasm.states.should include(:open)
20
+ Foo.aasm.states.should include(:closed)
21
+
22
+ Foo.aasm.should respond_to(:initial_state)
23
+ Foo.aasm.initial_state.should == :open
24
+
25
+ Foo.aasm.should respond_to(:events)
26
+ Foo.aasm.events.should include(:close)
27
+ Foo.aasm.events.should include(:null)
28
+ end
29
+
30
+ it 'should list states in the order they have been defined' do
31
+ Conversation.aasm.states.should == [:needs_attention, :read, :closed, :awaiting_response, :junk]
32
+ end
33
+ end
34
+
35
+ describe "special cases" do
36
+ it "should support valid a state name" do
37
+ Argument.aasm_states.should include(:invalid)
38
+ Argument.aasm_states.should include(:valid)
39
+
40
+ argument = Argument.new
41
+ argument.invalid?.should be_true
42
+ argument.aasm_current_state.should == :invalid
43
+
44
+ argument.valid!
45
+ argument.valid?.should be_true
46
+ argument.aasm_current_state.should == :valid
47
+ end
48
+ end
49
+
50
+ describe :aasm_states_for_select do
51
+ it "should return a select friendly array of states" do
52
+ Foo.should respond_to(:aasm_states_for_select)
53
+ Foo.aasm_states_for_select.should == [['Open', 'open'], ['Closed', 'closed']]
54
+ end
55
+ end
56
+
57
+ describe :aasm_from_states_for_state do
58
+ it "should return all from states for a state" do
59
+ AuthMachine.should respond_to(:aasm_from_states_for_state)
60
+ froms = AuthMachine.aasm_from_states_for_state(:active)
61
+ [:pending, :passive, :suspended].each {|from| froms.should include(from)}
62
+ end
63
+
64
+ it "should return from states for a state for a particular transition only" do
65
+ froms = AuthMachine.aasm_from_states_for_state(:active, :transition => :unsuspend)
66
+ [:suspended].each {|from| froms.should include(from)}
67
+ end
68
+ end
69
+
70
+ describe :aasm_events_for_current_state do
71
+ let(:foo) {Foo.new}
72
+
73
+ it 'work' do
74
+ foo.aasm_events_for_current_state.should include(:close)
75
+ foo.aasm_events_for_current_state.should include(:null)
76
+ foo.close
77
+ foo.aasm_events_for_current_state.should be_empty
6
78
  end
7
79
  end
@@ -1,34 +1,38 @@
1
- require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
1
+ # require 'spec_helper'
2
2
 
3
- describe "state machines" do
3
+ # describe "state machines" do
4
4
 
5
- def number_of_objects(clazz)
6
- ObjectSpace.each_object(clazz) {}
7
- end
8
-
9
- def machines
10
- AASM::StateMachine.instance_variable_get("@machines")
11
- end
5
+ # def number_of_objects(clazz)
6
+ # ObjectSpace.each_object(clazz) {}
7
+ # end
12
8
 
13
- it "should be created without memory leak" do
14
- machines_count = machines.size
15
- state_count = number_of_objects(AASM::SupportingClasses::State)
16
- event_count = number_of_objects(AASM::SupportingClasses::Event)
17
- transition_count = number_of_objects(AASM::SupportingClasses::StateTransition)
9
+ # def machines
10
+ # AASM::StateMachine.instance_variable_get("@machines")
11
+ # end
18
12
 
19
- load File.expand_path(File.dirname(__FILE__) + '/../models/not_auto_loaded/process.rb')
20
- machines.size.should == machines_count + 1 # + Process
21
- number_of_objects(Models::Process).should == 0
22
- number_of_objects(AASM::SupportingClasses::State).should == state_count + 3 # + Process
23
- number_of_objects(AASM::SupportingClasses::Event).should == event_count + 2 # + Process
24
- number_of_objects(AASM::SupportingClasses::StateTransition).should == transition_count + 2 # + Process
13
+ # it "should be created without memory leak" do
14
+ # machines_count = machines.size
15
+ # state_count = number_of_objects(AASM::SupportingClasses::State)
16
+ # event_count = number_of_objects(AASM::SupportingClasses::Event)
17
+ # puts "event_count = #{event_count}"
18
+ # transition_count = number_of_objects(AASM::SupportingClasses::StateTransition)
25
19
 
26
- Models.send(:remove_const, "Process") if Models.const_defined?("Process")
27
- load File.expand_path(File.dirname(__FILE__) + '/../models/not_auto_loaded/process.rb')
28
- machines.size.should == machines_count + 1 # + Process
29
- number_of_objects(AASM::SupportingClasses::State).should == state_count + 3 # + Process
30
- number_of_objects(AASM::SupportingClasses::Event).should == event_count + 2 # + Process
31
- number_of_objects(AASM::SupportingClasses::StateTransition).should == transition_count + 2 # + Process
32
- end
20
+ # load File.expand_path(File.dirname(__FILE__) + '/../models/not_auto_loaded/process.rb')
21
+ # machines.size.should == machines_count + 1 # + Process
22
+ # number_of_objects(Models::Process).should == 0
23
+ # number_of_objects(AASM::SupportingClasses::State).should == state_count + 3 # + Process
24
+ # puts "event_count = #{number_of_objects(AASM::SupportingClasses::Event)}"
25
+ # number_of_objects(AASM::SupportingClasses::Event).should == event_count + 2 # + Process
26
+ # number_of_objects(AASM::SupportingClasses::StateTransition).should == transition_count + 2 # + Process
33
27
 
34
- end
28
+ # Models.send(:remove_const, "Process") if Models.const_defined?("Process")
29
+ # load File.expand_path(File.dirname(__FILE__) + '/../models/not_auto_loaded/process.rb')
30
+ # machines.size.should == machines_count + 1 # + Process
31
+ # number_of_objects(AASM::SupportingClasses::State).should == state_count + 3 # + Process
32
+ # # ObjectSpace.each_object(AASM::SupportingClasses::Event) {|o| puts o.inspect}
33
+ # puts "event_count = #{number_of_objects(AASM::SupportingClasses::Event)}"
34
+ # number_of_objects(AASM::SupportingClasses::Event).should == event_count + 2 # + Process
35
+ # number_of_objects(AASM::SupportingClasses::StateTransition).should == transition_count + 2 # + Process
36
+ # end
37
+
38
+ # end
@@ -1,24 +1,8 @@
1
- require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
1
+ require 'spec_helper'
2
2
 
3
3
  describe "the new dsl" do
4
4
 
5
- before(:each) do
6
- @process = ProcessWithNewDsl.new
7
- end
8
-
9
- it 'should use an initial event' do
10
- @process.aasm_current_state.should == :sleeping
11
- @process.should be_sleeping
12
- end
13
-
14
- it 'should have states and transitions' do
15
- @process.flagged.should be_nil
16
- @process.start!
17
- @process.should be_running
18
- @process.flagged.should be_true
19
- @process.stop!
20
- @process.should be_suspended
21
- end
5
+ let(:process) {ProcessWithNewDsl.new}
22
6
 
23
7
  it 'should not conflict with other event or state methods' do
24
8
  lambda {ProcessWithNewDsl.state}.should raise_error(RuntimeError, "wrong state method")
@@ -1,4 +1,3 @@
1
- require 'rubygems'
2
1
  require 'active_record'
3
2
  require 'logger'
4
3
  require 'spec_helper'
@@ -58,7 +57,7 @@ end
58
57
  describe "instance methods" do
59
58
  let(:gate) {Gate.new}
60
59
 
61
- it "should respond to aasm states" do
60
+ it "should respond to aasm persistence methods" do
62
61
  gate.should respond_to(:aasm_read_state)
63
62
  gate.should respond_to(:aasm_write_state)
64
63
  gate.should respond_to(:aasm_write_state_without_persistence)
@@ -85,16 +84,12 @@ describe "instance methods" do
85
84
  gate.aasm_current_state.should be_nil
86
85
  end
87
86
 
88
- it "should have aasm_ensure_initial_state" do
89
- gate.send :aasm_ensure_initial_state
90
- end
91
-
92
87
  it "should call aasm_ensure_initial_state on validation before create" do
93
88
  gate.should_receive(:aasm_ensure_initial_state).and_return(true)
94
89
  gate.valid?
95
90
  end
96
91
 
97
- it "should call aasm_ensure_initial_state on validation before create" do
92
+ it "should not call aasm_ensure_initial_state on validation before update" do
98
93
  gate.stub!(:new_record?).and_return(false)
99
94
  gate.should_not_receive(:aasm_ensure_initial_state)
100
95
  gate.valid?
@@ -0,0 +1,53 @@
1
+ require 'spec_helper'
2
+
3
+ class Payment
4
+ include AASM
5
+ aasm do
6
+ state :initialised, :initial => true
7
+ state :filled_out
8
+ state :authorised
9
+
10
+ event :fill_out do
11
+ transitions :from => :initialised, :to => :filled_out
12
+ end
13
+ event :authorise do
14
+ transitions :from => :filled_out, :to => :authorised
15
+ end
16
+ end
17
+ end
18
+
19
+ describe 'state machine' do
20
+ let(:payment) {Payment.new}
21
+
22
+ it 'starts with an initial state' do
23
+ payment.aasm_current_state.should == :initialised
24
+ # payment.aasm.current_state.should == :initialised # not yet supported
25
+ payment.should respond_to(:initialised?)
26
+ payment.should be_initialised
27
+ end
28
+
29
+ it 'allows transitions to other states' do
30
+ payment.should respond_to(:fill_out)
31
+ payment.should respond_to(:fill_out!)
32
+ payment.fill_out!
33
+ payment.should respond_to(:filled_out?)
34
+ payment.should be_filled_out
35
+
36
+ payment.should respond_to(:authorise)
37
+ payment.should respond_to(:authorise!)
38
+ payment.authorise
39
+ payment.should respond_to(:authorised?)
40
+ payment.should be_authorised
41
+ end
42
+
43
+ it 'denies transitions to other states' do
44
+ lambda {payment.authorise}.should raise_error(AASM::InvalidTransition)
45
+ lambda {payment.authorise!}.should raise_error(AASM::InvalidTransition)
46
+ payment.fill_out
47
+ lambda {payment.fill_out}.should raise_error(AASM::InvalidTransition)
48
+ lambda {payment.fill_out!}.should raise_error(AASM::InvalidTransition)
49
+ payment.authorise
50
+ lambda {payment.fill_out}.should raise_error(AASM::InvalidTransition)
51
+ lambda {payment.fill_out!}.should raise_error(AASM::InvalidTransition)
52
+ end
53
+ end
@@ -0,0 +1,19 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'subclassing' do
4
+ it 'should have the parent states' do
5
+ Foo.aasm_states.each do |state|
6
+ FooTwo.aasm_states.should include(state)
7
+ end
8
+ Baz.aasm_states.should == Bar.aasm_states
9
+ end
10
+
11
+ it 'should not add the child states to the parent machine' do
12
+ Foo.aasm_states.should_not include(:foo)
13
+ end
14
+
15
+ it "should have the same events as its parent" do
16
+ Baz.aasm_events.should == Bar.aasm_events
17
+ end
18
+ end
19
+
@@ -1,51 +1,50 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe 'adding an event' do
4
-
5
- def new_event
6
- @event = AASM::SupportingClasses::Event.new(:close_order, {:success => :success_callback}) do
4
+ let(:event) do
5
+ AASM::SupportingClasses::Event.new(:close_order, {:success => :success_callback}) do
7
6
  transitions :to => :closed, :from => [:open, :received]
8
7
  end
9
8
  end
10
9
 
11
10
  it 'should set the name' do
12
- new_event
13
- @event.name.should == :close_order
11
+ event.name.should == :close_order
14
12
  end
15
13
 
16
- it 'should set the success option' do
17
- new_event
18
- @event.success.should == :success_callback
14
+ it 'should set the success callback' do
15
+ event.success.should == :success_callback
19
16
  end
20
17
 
21
- it 'should create StateTransitions' do
22
- AASM::SupportingClasses::StateTransition.should_receive(:new).with({:to => :closed, :from => :open})
23
- AASM::SupportingClasses::StateTransition.should_receive(:new).with({:to => :closed, :from => :received})
24
- new_event
18
+ it 'should create transitions' do
19
+ transitions = event.all_transitions
20
+ transitions[0].from.should == :open
21
+ transitions[0].to.should == :closed
22
+ transitions[1].from.should == :received
23
+ transitions[1].to.should == :closed
25
24
  end
26
25
  end
27
26
 
28
27
  describe 'transition inspection' do
29
- before do
30
- @event = AASM::SupportingClasses::Event.new(:run) do
28
+ let(:event) do
29
+ AASM::SupportingClasses::Event.new(:run) do
31
30
  transitions :to => :running, :from => :sleeping
32
31
  end
33
32
  end
34
33
 
35
- it 'should support inspecting transitions from states' do
36
- @event.transitions_from_state(:sleeping).map(&:to).should == [:running]
37
- @event.transitions_from_state?(:sleeping).should be_true
34
+ it 'should support inspecting transitions from other states' do
35
+ event.transitions_from_state(:sleeping).map(&:to).should == [:running]
36
+ event.transitions_from_state?(:sleeping).should be_true
38
37
 
39
- @event.transitions_from_state(:cleaning).map(&:to).should == []
40
- @event.transitions_from_state?(:cleaning).should be_false
38
+ event.transitions_from_state(:cleaning).map(&:to).should == []
39
+ event.transitions_from_state?(:cleaning).should be_false
41
40
  end
42
41
 
43
- it 'should support inspecting transitions to states' do
44
- @event.transitions_to_state(:running).map(&:from).should == [:sleeping]
45
- @event.transitions_to_state?(:running).should be_true
42
+ it 'should support inspecting transitions to other states' do
43
+ event.transitions_to_state(:running).map(&:from).should == [:sleeping]
44
+ event.transitions_to_state?(:running).should be_true
46
45
 
47
- @event.transitions_to_state(:cleaning).map(&:to).should == []
48
- @event.transitions_to_state?(:cleaning).should be_false
46
+ event.transitions_to_state(:cleaning).map(&:to).should == []
47
+ event.transitions_to_state?(:cleaning).should be_false
49
48
  end
50
49
  end
51
50
 
@@ -148,3 +147,57 @@ describe 'executing the success callback' do
148
147
  model.with_proc!
149
148
  end
150
149
  end
150
+
151
+ describe 'parametrised events' do
152
+ let(:pe) {ParametrisedEvent.new}
153
+
154
+ it 'should transition to specified next state (sleeping to showering)' do
155
+ pe.wakeup!(:showering)
156
+ pe.aasm_current_state.should == :showering
157
+ end
158
+
159
+ it 'should transition to specified next state (sleeping to working)' do
160
+ pe.wakeup!(:working)
161
+ pe.aasm_current_state.should == :working
162
+ end
163
+
164
+ it 'should transition to default (first or showering) state' do
165
+ pe.wakeup!
166
+ pe.aasm_current_state.should == :showering
167
+ end
168
+
169
+ it 'should transition to default state when on_transition invoked' do
170
+ pe.dress!(nil, 'purple', 'dressy')
171
+ pe.aasm_current_state.should == :working
172
+ end
173
+
174
+ it 'should call on_transition method with args' do
175
+ pe.wakeup!(:showering)
176
+ pe.should_receive(:wear_clothes).with('blue', 'jeans')
177
+ pe.dress!(:working, 'blue', 'jeans')
178
+ end
179
+
180
+ it 'should call on_transition proc' do
181
+ pe.wakeup!(:showering)
182
+ pe.should_receive(:wear_clothes).with('purple', 'slacks')
183
+ pe.dress!(:dating, 'purple', 'slacks')
184
+ end
185
+
186
+ it 'should call on_transition with an array of methods' do
187
+ pe.wakeup!(:showering)
188
+ pe.should_receive(:condition_hair)
189
+ pe.should_receive(:fix_hair)
190
+ pe.dress!(:prettying_up)
191
+ end
192
+ end
193
+
194
+ describe 'event firing without persistence' do
195
+ it 'should attempt to persist if aasm_write_state is defined' do
196
+ foo = Foo.new
197
+ def foo.aasm_write_state; end
198
+ foo.should be_open
199
+
200
+ foo.should_receive(:aasm_write_state_without_persistence)
201
+ foo.close
202
+ end
203
+ end