aasm 2.3.1 → 2.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -0
- data/CHANGELOG.md +15 -0
- data/LICENSE +1 -1
- data/README.md +40 -13
- data/Rakefile +2 -2
- data/lib/aasm/aasm.rb +19 -31
- data/lib/aasm/base.rb +56 -0
- data/lib/aasm/supporting_classes.rb +1 -0
- data/lib/aasm/version.rb +1 -1
- data/spec/{functional → models}/conversation.rb +0 -2
- data/{test/models → spec/models/not_auto_loaded}/process.rb +1 -0
- data/spec/models/process_with_new_dsl.rb +31 -0
- data/spec/spec_helper.rb +3 -0
- data/spec/spec_helpers/models_spec_helper.rb +184 -0
- data/spec/unit/aasm_spec.rb +16 -89
- data/spec/unit/active_record_persistence_spec.rb +195 -191
- data/spec/unit/auth_machine_spec.rb +66 -0
- data/spec/{functional → unit}/conversation_spec.rb +2 -3
- data/spec/unit/event_spec.rb +0 -9
- data/spec/unit/memory_leak_spec.rb +34 -0
- data/spec/unit/new_dsl_spec.rb +28 -0
- data/spec/unit/state_spec.rb +13 -11
- metadata +23 -25
- data/test/functional/auth_machine_test.rb +0 -148
- data/test/test_helper.rb +0 -43
- data/test/unit/aasm_test.rb +0 -0
- data/test/unit/event_test.rb +0 -54
- data/test/unit/state_machine_test.rb +0 -37
- data/test/unit/state_test.rb +0 -69
- data/test/unit/state_transition_test.rb +0 -75
@@ -0,0 +1,66 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
|
2
|
+
|
3
|
+
describe 'AuthMachine on initialization' do
|
4
|
+
before(:each) do
|
5
|
+
@auth = AuthMachine.new
|
6
|
+
end
|
7
|
+
|
8
|
+
it 'should be in the pending state' do
|
9
|
+
@auth.aasm_current_state.should == :pending
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'should have an activation code' do
|
13
|
+
@auth.has_activation_code?.should be_true
|
14
|
+
@auth.activation_code.should_not be_nil
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe 'AuthMachine when being unsuspended' do
|
19
|
+
it 'should be able to be unsuspended' do
|
20
|
+
@auth = AuthMachine.new
|
21
|
+
@auth.activate!
|
22
|
+
@auth.suspend!
|
23
|
+
@auth.may_unsuspend?.should be_true
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'should not be able to be unsuspended into active' do
|
27
|
+
@auth = AuthMachine.new
|
28
|
+
@auth.suspend!
|
29
|
+
@auth.may_unsuspend?(:active).should_not be_true
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'should not be able to be unpassified' do
|
33
|
+
@auth = AuthMachine.new
|
34
|
+
@auth.activate!
|
35
|
+
@auth.suspend!
|
36
|
+
@auth.unsuspend!
|
37
|
+
|
38
|
+
@auth.may_unpassify?.should_not be_true
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'should be active if previously activated' do
|
42
|
+
@auth = AuthMachine.new
|
43
|
+
@auth.activate!
|
44
|
+
@auth.suspend!
|
45
|
+
@auth.unsuspend!
|
46
|
+
|
47
|
+
@auth.aasm_current_state.should == :active
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'should be pending if not previously activated, but an activation code is present' do
|
51
|
+
@auth = AuthMachine.new
|
52
|
+
@auth.suspend!
|
53
|
+
@auth.unsuspend!
|
54
|
+
|
55
|
+
@auth.aasm_current_state.should == :pending
|
56
|
+
end
|
57
|
+
|
58
|
+
it 'should be passive if not previously activated and there is no activation code' do
|
59
|
+
@auth = AuthMachine.new
|
60
|
+
@auth.activation_code = nil
|
61
|
+
@auth.suspend!
|
62
|
+
@auth.unsuspend!
|
63
|
+
|
64
|
+
@auth.aasm_current_state.should == :passive
|
65
|
+
end
|
66
|
+
end
|
@@ -1,8 +1,7 @@
|
|
1
1
|
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
|
2
|
-
require File.expand_path(File.join(File.dirname(__FILE__), 'conversation'))
|
3
2
|
|
4
|
-
describe
|
5
|
-
it '
|
3
|
+
describe 'aasm_states' do
|
4
|
+
it 'should contain all of the states' do
|
6
5
|
Conversation.aasm_states.should == [:needs_attention, :read, :closed, :awaiting_response, :junk]
|
7
6
|
end
|
8
7
|
end
|
data/spec/unit/event_spec.rb
CHANGED
@@ -65,15 +65,6 @@ describe AASM::SupportingClasses::Event, 'when firing an event' do
|
|
65
65
|
end
|
66
66
|
|
67
67
|
describe AASM::SupportingClasses::Event, 'when executing the success callback' do
|
68
|
-
class ThisNameBetterNotBeInUse
|
69
|
-
include AASM
|
70
|
-
|
71
|
-
aasm_state :initial
|
72
|
-
aasm_state :symbol
|
73
|
-
aasm_state :string
|
74
|
-
aasm_state :array
|
75
|
-
aasm_state :proc
|
76
|
-
end
|
77
68
|
|
78
69
|
it "should send the success callback if it's a symbol" do
|
79
70
|
ThisNameBetterNotBeInUse.instance_eval {
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
|
2
|
+
|
3
|
+
describe "state machines" do
|
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
|
12
|
+
|
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)
|
18
|
+
|
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
|
25
|
+
|
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
|
33
|
+
|
34
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
|
2
|
+
|
3
|
+
describe "the new dsl" do
|
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
|
22
|
+
|
23
|
+
it 'should not conflict with other event or state methods' do
|
24
|
+
lambda {ProcessWithNewDsl.state}.should raise_error(RuntimeError, "wrong state method")
|
25
|
+
lambda {ProcessWithNewDsl.event}.should raise_error(RuntimeError, "wrong event method")
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
data/spec/unit/state_spec.rb
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
|
2
2
|
|
3
|
-
# TODO These are specs ported from original aasm
|
4
3
|
describe AASM::SupportingClasses::State do
|
5
4
|
before(:each) do
|
6
5
|
@name = :astate
|
@@ -13,20 +12,23 @@ describe AASM::SupportingClasses::State do
|
|
13
12
|
|
14
13
|
it 'should set the name' do
|
15
14
|
state = new_state
|
16
|
-
|
17
15
|
state.name.should == :astate
|
18
16
|
end
|
19
17
|
|
20
|
-
it 'should set the
|
21
|
-
|
18
|
+
it 'should set the display_name from name' do
|
19
|
+
new_state.display_name.should == 'Astate'
|
20
|
+
end
|
22
21
|
|
23
|
-
|
22
|
+
it 'should set the display_name from options' do
|
23
|
+
new_state(:display => "A State").display_name.should == 'A State'
|
24
24
|
end
|
25
25
|
|
26
|
-
it 'should
|
27
|
-
|
26
|
+
it 'should set the options and expose them as options' do
|
27
|
+
new_state.options.should == @options
|
28
|
+
end
|
28
29
|
|
29
|
-
|
30
|
+
it 'should be equal to a symbol of the same name' do
|
31
|
+
new_state.should == :astate
|
30
32
|
end
|
31
33
|
|
32
34
|
it 'should be equal to a State of the same name' do
|
@@ -50,16 +52,16 @@ describe AASM::SupportingClasses::State do
|
|
50
52
|
|
51
53
|
state.call_action(:entering, record)
|
52
54
|
end
|
53
|
-
|
55
|
+
|
54
56
|
it 'should send a message to the record for each action' do
|
55
57
|
state = new_state(:entering => [:a, :b, "c", lambda {|r| r.foobar }])
|
56
|
-
|
58
|
+
|
57
59
|
record = mock('record')
|
58
60
|
record.should_receive(:a)
|
59
61
|
record.should_receive(:b)
|
60
62
|
record.should_receive(:c)
|
61
63
|
record.should_receive(:foobar)
|
62
|
-
|
64
|
+
|
63
65
|
state.call_action(:entering, record)
|
64
66
|
end
|
65
67
|
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: aasm
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 31
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 2
|
8
|
-
-
|
9
|
-
-
|
10
|
-
version: 2.
|
8
|
+
- 4
|
9
|
+
- 0
|
10
|
+
version: 2.4.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Scott Barron
|
@@ -18,7 +18,7 @@ autorequire:
|
|
18
18
|
bindir: bin
|
19
19
|
cert_chain: []
|
20
20
|
|
21
|
-
date: 2011-
|
21
|
+
date: 2011-11-26 00:00:00 +01:00
|
22
22
|
default_executable:
|
23
23
|
dependencies:
|
24
24
|
- !ruby/object:Gem::Dependency
|
@@ -159,6 +159,7 @@ extra_rdoc_files: []
|
|
159
159
|
files:
|
160
160
|
- .document
|
161
161
|
- .gitignore
|
162
|
+
- CHANGELOG.md
|
162
163
|
- Gemfile
|
163
164
|
- LICENSE
|
164
165
|
- README.md
|
@@ -166,6 +167,7 @@ files:
|
|
166
167
|
- aasm.gemspec
|
167
168
|
- lib/aasm.rb
|
168
169
|
- lib/aasm/aasm.rb
|
170
|
+
- lib/aasm/base.rb
|
169
171
|
- lib/aasm/event.rb
|
170
172
|
- lib/aasm/localizer.rb
|
171
173
|
- lib/aasm/persistence.rb
|
@@ -177,25 +179,23 @@ files:
|
|
177
179
|
- lib/aasm/version.rb
|
178
180
|
- spec/database.yml
|
179
181
|
- spec/en.yml
|
180
|
-
- spec/
|
181
|
-
- spec/
|
182
|
+
- spec/models/conversation.rb
|
183
|
+
- spec/models/not_auto_loaded/process.rb
|
184
|
+
- spec/models/process_with_new_dsl.rb
|
182
185
|
- spec/schema.rb
|
183
186
|
- spec/spec_helper.rb
|
187
|
+
- spec/spec_helpers/models_spec_helper.rb
|
184
188
|
- spec/unit/aasm_spec.rb
|
185
189
|
- spec/unit/active_record_persistence_spec.rb
|
190
|
+
- spec/unit/auth_machine_spec.rb
|
186
191
|
- spec/unit/before_after_callbacks_spec.rb
|
192
|
+
- spec/unit/conversation_spec.rb
|
187
193
|
- spec/unit/event_spec.rb
|
188
194
|
- spec/unit/localizer_spec.rb
|
195
|
+
- spec/unit/memory_leak_spec.rb
|
196
|
+
- spec/unit/new_dsl_spec.rb
|
189
197
|
- spec/unit/state_spec.rb
|
190
198
|
- spec/unit/state_transition_spec.rb
|
191
|
-
- test/functional/auth_machine_test.rb
|
192
|
-
- test/models/process.rb
|
193
|
-
- test/test_helper.rb
|
194
|
-
- test/unit/aasm_test.rb
|
195
|
-
- test/unit/event_test.rb
|
196
|
-
- test/unit/state_machine_test.rb
|
197
|
-
- test/unit/state_test.rb
|
198
|
-
- test/unit/state_transition_test.rb
|
199
199
|
has_rdoc: true
|
200
200
|
homepage: http://rubyist.github.com/aasm/
|
201
201
|
licenses: []
|
@@ -233,22 +233,20 @@ summary: State machine mixin for Ruby objects
|
|
233
233
|
test_files:
|
234
234
|
- spec/database.yml
|
235
235
|
- spec/en.yml
|
236
|
-
- spec/
|
237
|
-
- spec/
|
236
|
+
- spec/models/conversation.rb
|
237
|
+
- spec/models/not_auto_loaded/process.rb
|
238
|
+
- spec/models/process_with_new_dsl.rb
|
238
239
|
- spec/schema.rb
|
239
240
|
- spec/spec_helper.rb
|
241
|
+
- spec/spec_helpers/models_spec_helper.rb
|
240
242
|
- spec/unit/aasm_spec.rb
|
241
243
|
- spec/unit/active_record_persistence_spec.rb
|
244
|
+
- spec/unit/auth_machine_spec.rb
|
242
245
|
- spec/unit/before_after_callbacks_spec.rb
|
246
|
+
- spec/unit/conversation_spec.rb
|
243
247
|
- spec/unit/event_spec.rb
|
244
248
|
- spec/unit/localizer_spec.rb
|
249
|
+
- spec/unit/memory_leak_spec.rb
|
250
|
+
- spec/unit/new_dsl_spec.rb
|
245
251
|
- spec/unit/state_spec.rb
|
246
252
|
- spec/unit/state_transition_spec.rb
|
247
|
-
- test/functional/auth_machine_test.rb
|
248
|
-
- test/models/process.rb
|
249
|
-
- test/test_helper.rb
|
250
|
-
- test/unit/aasm_test.rb
|
251
|
-
- test/unit/event_test.rb
|
252
|
-
- test/unit/state_machine_test.rb
|
253
|
-
- test/unit/state_test.rb
|
254
|
-
- test/unit/state_transition_test.rb
|
@@ -1,148 +0,0 @@
|
|
1
|
-
require 'test_helper'
|
2
|
-
|
3
|
-
class AuthMachine
|
4
|
-
include AASM
|
5
|
-
|
6
|
-
attr_accessor :activation_code, :activated_at, :deleted_at
|
7
|
-
|
8
|
-
aasm_initial_state :pending
|
9
|
-
|
10
|
-
aasm_state :passive
|
11
|
-
aasm_state :pending, :enter => :make_activation_code
|
12
|
-
aasm_state :active, :enter => :do_activate
|
13
|
-
aasm_state :suspended
|
14
|
-
aasm_state :deleted, :enter => :do_delete, :exit => :do_undelete
|
15
|
-
|
16
|
-
aasm_event :register do
|
17
|
-
transitions :from => :passive, :to => :pending, :guard => Proc.new {|u| u.can_register? }
|
18
|
-
end
|
19
|
-
|
20
|
-
aasm_event :activate do
|
21
|
-
transitions :from => :pending, :to => :active
|
22
|
-
end
|
23
|
-
|
24
|
-
aasm_event :suspend do
|
25
|
-
transitions :from => [:passive, :pending, :active], :to => :suspended
|
26
|
-
end
|
27
|
-
|
28
|
-
aasm_event :delete do
|
29
|
-
transitions :from => [:passive, :pending, :active, :suspended], :to => :deleted
|
30
|
-
end
|
31
|
-
|
32
|
-
# a dummy event that can never happen
|
33
|
-
aasm_event :unpassify do
|
34
|
-
transitions :from => :passive, :to => :active, :guard => Proc.new {|u| false }
|
35
|
-
end
|
36
|
-
|
37
|
-
aasm_event :unsuspend do
|
38
|
-
transitions :from => :suspended, :to => :active, :guard => Proc.new {|u| u.has_activated? }
|
39
|
-
transitions :from => :suspended, :to => :pending, :guard => Proc.new {|u| u.has_activation_code? }
|
40
|
-
transitions :from => :suspended, :to => :passive
|
41
|
-
end
|
42
|
-
|
43
|
-
def initialize
|
44
|
-
# the AR backend uses a before_validate_on_create :aasm_ensure_initial_state
|
45
|
-
# lets do something similar here for testing purposes.
|
46
|
-
aasm_enter_initial_state
|
47
|
-
end
|
48
|
-
|
49
|
-
def make_activation_code
|
50
|
-
@activation_code = 'moo'
|
51
|
-
end
|
52
|
-
|
53
|
-
def do_activate
|
54
|
-
@activated_at = Time.now
|
55
|
-
@activation_code = nil
|
56
|
-
end
|
57
|
-
|
58
|
-
def do_delete
|
59
|
-
@deleted_at = Time.now
|
60
|
-
end
|
61
|
-
|
62
|
-
def do_undelete
|
63
|
-
@deleted_at = false
|
64
|
-
end
|
65
|
-
|
66
|
-
def can_register?
|
67
|
-
true
|
68
|
-
end
|
69
|
-
|
70
|
-
def has_activated?
|
71
|
-
!!@activated_at
|
72
|
-
end
|
73
|
-
|
74
|
-
def has_activation_code?
|
75
|
-
!!@activation_code
|
76
|
-
end
|
77
|
-
end
|
78
|
-
|
79
|
-
class AuthMachineTest < Test::Unit::TestCase
|
80
|
-
context 'authentication state machine' do
|
81
|
-
context 'on initialization' do
|
82
|
-
setup do
|
83
|
-
@auth = AuthMachine.new
|
84
|
-
end
|
85
|
-
|
86
|
-
should 'be in the pending state' do
|
87
|
-
assert_equal :pending, @auth.aasm_current_state
|
88
|
-
end
|
89
|
-
|
90
|
-
should 'have an activation code' do
|
91
|
-
assert @auth.has_activation_code?
|
92
|
-
assert_not_nil @auth.activation_code
|
93
|
-
end
|
94
|
-
end
|
95
|
-
|
96
|
-
context 'when being unsuspended' do
|
97
|
-
|
98
|
-
should 'be able to be unsuspended' do
|
99
|
-
@auth = AuthMachine.new
|
100
|
-
@auth.activate!
|
101
|
-
@auth.suspend!
|
102
|
-
assert @auth.may_unsuspend?
|
103
|
-
end
|
104
|
-
|
105
|
-
should 'not be able to be unsuspended into active' do
|
106
|
-
@auth = AuthMachine.new
|
107
|
-
@auth.suspend!
|
108
|
-
assert_equal false, @auth.may_unsuspend?(:active)
|
109
|
-
end
|
110
|
-
|
111
|
-
should 'not be able to be unpassified' do
|
112
|
-
@auth = AuthMachine.new
|
113
|
-
@auth.activate!
|
114
|
-
@auth.suspend!
|
115
|
-
@auth.unsuspend!
|
116
|
-
|
117
|
-
assert_equal false, @auth.may_unpassify?
|
118
|
-
end
|
119
|
-
|
120
|
-
should 'be active if previously activated' do
|
121
|
-
@auth = AuthMachine.new
|
122
|
-
@auth.activate!
|
123
|
-
@auth.suspend!
|
124
|
-
@auth.unsuspend!
|
125
|
-
|
126
|
-
assert_equal :active, @auth.aasm_current_state
|
127
|
-
end
|
128
|
-
|
129
|
-
should 'be pending if not previously activated, but an activation code is present' do
|
130
|
-
@auth = AuthMachine.new
|
131
|
-
@auth.suspend!
|
132
|
-
@auth.unsuspend!
|
133
|
-
|
134
|
-
assert_equal :pending, @auth.aasm_current_state
|
135
|
-
end
|
136
|
-
|
137
|
-
should 'be passive if not previously activated and there is no activation code' do
|
138
|
-
@auth = AuthMachine.new
|
139
|
-
@auth.activation_code = nil
|
140
|
-
@auth.suspend!
|
141
|
-
@auth.unsuspend!
|
142
|
-
|
143
|
-
assert_equal :passive, @auth.aasm_current_state
|
144
|
-
end
|
145
|
-
end
|
146
|
-
|
147
|
-
end
|
148
|
-
end
|