aasm 4.0.8 → 4.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.travis.yml +7 -2
- data/CHANGELOG.md +43 -2
- data/CODE_OF_CONDUCT.md +13 -0
- data/Gemfile +6 -3
- data/LICENSE +1 -1
- data/PLANNED_CHANGES.md +8 -4
- data/README.md +171 -14
- data/aasm.gemspec +1 -5
- data/gemfiles/rails_3.2.gemfile +3 -2
- data/gemfiles/rails_4.0.gemfile +2 -6
- data/gemfiles/rails_4.0_mongo_mapper.gemfile +14 -0
- data/gemfiles/rails_4.1.gemfile +2 -6
- data/gemfiles/rails_4.1_mongo_mapper.gemfile +14 -0
- data/gemfiles/rails_4.2.gemfile +1 -5
- data/gemfiles/rails_4.2_mongo_mapper.gemfile +14 -0
- data/gemfiles/rails_4.2_mongoid_5.gemfile +12 -0
- data/lib/aasm/aasm.rb +69 -36
- data/lib/aasm/base.rb +51 -21
- data/lib/aasm/core/event.rb +7 -6
- data/lib/aasm/core/state.rb +11 -8
- data/lib/aasm/core/transition.rb +7 -5
- data/lib/aasm/errors.rb +15 -1
- data/lib/aasm/instance_base.rb +17 -13
- data/lib/aasm/localizer.rb +1 -1
- data/lib/aasm/persistence/active_record_persistence.rb +63 -73
- data/lib/aasm/persistence/base.rb +55 -20
- data/lib/aasm/persistence/mongo_mapper_persistence.rb +157 -0
- data/lib/aasm/persistence/mongoid_persistence.rb +16 -41
- data/lib/aasm/persistence/plain_persistence.rb +8 -7
- data/lib/aasm/persistence/sequel_persistence.rb +12 -9
- data/lib/aasm/persistence.rb +2 -0
- data/lib/aasm/rspec/allow_event.rb +22 -0
- data/lib/aasm/rspec/allow_transition_to.rb +22 -0
- data/lib/aasm/rspec/have_state.rb +22 -0
- data/lib/aasm/rspec/transition_from.rb +32 -0
- data/lib/aasm/rspec.rb +5 -0
- data/lib/aasm/state_machine.rb +20 -6
- data/lib/aasm/version.rb +1 -1
- data/spec/database.rb +27 -1
- data/spec/models/active_record/basic_active_record_two_state_machines_example.rb +25 -0
- data/spec/models/active_record/complex_active_record_example.rb +33 -0
- data/spec/models/active_record/derivate_new_dsl.rb +7 -0
- data/spec/models/active_record/false_state.rb +35 -0
- data/spec/models/active_record/gate.rb +39 -0
- data/spec/models/active_record/localizer_test_model.rb +34 -0
- data/spec/models/active_record/no_direct_assignment.rb +21 -0
- data/spec/models/active_record/no_scope.rb +21 -0
- data/spec/models/active_record/persisted_state.rb +12 -0
- data/spec/models/active_record/provided_and_persisted_state.rb +24 -0
- data/spec/models/active_record/reader.rb +7 -0
- data/spec/models/active_record/readme_job.rb +21 -0
- data/spec/models/active_record/simple_new_dsl.rb +17 -0
- data/spec/models/active_record/thief.rb +29 -0
- data/spec/models/active_record/transient.rb +6 -0
- data/spec/models/active_record/with_enum.rb +39 -0
- data/spec/models/active_record/with_false_enum.rb +31 -0
- data/spec/models/active_record/with_true_enum.rb +39 -0
- data/spec/models/active_record/writer.rb +6 -0
- data/spec/models/basic_two_state_machines_example.rb +25 -0
- data/spec/models/callbacks/basic.rb +3 -0
- data/spec/models/callbacks/basic_multiple.rb +75 -0
- data/spec/models/callbacks/guard_within_block_multiple.rb +66 -0
- data/spec/models/callbacks/multiple_transitions_transition_guard_multiple.rb +65 -0
- data/spec/models/callbacks/private_method_multiple.rb +44 -0
- data/spec/models/callbacks/with_args.rb +9 -9
- data/spec/models/callbacks/with_args_multiple.rb +61 -0
- data/spec/models/callbacks/{with_state_args.rb → with_state_arg.rb} +1 -1
- data/spec/models/callbacks/with_state_arg_multiple.rb +26 -0
- data/spec/models/complex_example.rb +222 -0
- data/spec/models/conversation.rb +47 -1
- data/spec/models/default_state.rb +12 -0
- data/spec/models/foo.rb +57 -0
- data/spec/models/foo_callback_multiple.rb +45 -0
- data/spec/models/guardian.rb +10 -0
- data/spec/models/guardian_multiple.rb +48 -0
- data/spec/models/initial_state_proc.rb +31 -0
- data/spec/models/invalid_persistor.rb +15 -0
- data/spec/models/mongo_mapper/complex_mongo_mapper_example.rb +37 -0
- data/spec/models/mongo_mapper/no_scope_mongo_mapper.rb +21 -0
- data/spec/models/mongo_mapper/simple_mongo_mapper.rb +23 -0
- data/spec/models/mongo_mapper/simple_new_dsl_mongo_mapper.rb +25 -0
- data/spec/models/mongoid/complex_mongoid_example.rb +37 -0
- data/spec/models/mongoid/no_scope_mongoid.rb +11 -0
- data/spec/models/mongoid/simple_mongoid.rb +12 -0
- data/spec/models/mongoid/simple_new_dsl_mongoid.rb +14 -1
- data/spec/models/no_initial_state.rb +25 -0
- data/spec/models/parametrised_event.rb +1 -1
- data/spec/models/parametrised_event_multiple.rb +29 -0
- data/spec/models/provided_state.rb +24 -0
- data/spec/models/sequel/complex_sequel_example.rb +45 -0
- data/spec/models/sequel/sequel_multiple.rb +25 -0
- data/spec/models/sequel/sequel_simple.rb +25 -0
- data/spec/models/silencer.rb +5 -0
- data/spec/models/simple_example.rb +15 -0
- data/spec/models/simple_multiple_example.rb +30 -0
- data/spec/models/state_machine_with_failed_event.rb +12 -0
- data/spec/models/sub_class.rb +7 -0
- data/spec/models/sub_class_with_more_states.rb +18 -0
- data/spec/models/super_class.rb +46 -0
- data/spec/models/transactor.rb +27 -0
- data/spec/models/valid_state_name.rb +23 -0
- data/spec/models/validator.rb +47 -0
- data/spec/spec_helper.rb +4 -4
- data/spec/unit/api_spec.rb +6 -1
- data/spec/unit/basic_two_state_machines_example_spec.rb +10 -0
- data/spec/unit/callback_multiple_spec.rb +295 -0
- data/spec/unit/callbacks_spec.rb +3 -2
- data/spec/unit/complex_example_spec.rb +2 -2
- data/spec/unit/complex_multiple_example_spec.rb +99 -0
- data/spec/unit/edge_cases_spec.rb +16 -0
- data/spec/unit/event_multiple_spec.rb +73 -0
- data/spec/unit/event_naming_spec.rb +2 -15
- data/spec/unit/event_spec.rb +11 -6
- data/spec/unit/guard_multiple_spec.rb +60 -0
- data/spec/unit/guard_spec.rb +12 -0
- data/spec/unit/initial_state_multiple_spec.rb +15 -0
- data/spec/unit/initial_state_spec.rb +3 -18
- data/spec/unit/inspection_multiple_spec.rb +201 -0
- data/spec/unit/inspection_spec.rb +12 -7
- data/spec/unit/localizer_spec.rb +0 -38
- data/spec/unit/persistence/active_record_persistence_multiple_spec.rb +573 -0
- data/spec/unit/persistence/active_record_persistence_spec.rb +70 -13
- data/spec/unit/persistence/mongo_mapper_persistence_multiple_spec.rb +146 -0
- data/spec/unit/persistence/mongo_mapper_persistence_spec.rb +93 -0
- data/spec/unit/persistence/mongoid_persistence_multiple_spec.rb +127 -0
- data/spec/unit/persistence/mongoid_persistence_spec.rb +79 -0
- data/spec/unit/persistence/sequel_persistence_multiple_spec.rb +153 -0
- data/spec/unit/persistence/sequel_persistence_spec.rb +20 -23
- data/spec/unit/readme_spec.rb +42 -0
- data/spec/unit/reloading_spec.rb +1 -1
- data/spec/unit/rspec_matcher_spec.rb +79 -0
- data/spec/unit/simple_example_spec.rb +26 -42
- data/spec/unit/simple_multiple_example_spec.rb +63 -0
- data/spec/unit/state_spec.rb +3 -1
- data/spec/unit/subclassing_multiple_spec.rb +39 -0
- data/spec/unit/subclassing_spec.rb +10 -10
- data/spec/unit/transition_spec.rb +39 -25
- metadata +152 -23
- data/spec/models/active_record/api.rb +0 -75
- data/spec/models/argument.rb +0 -11
- data/spec/models/auth_machine.rb +0 -88
- data/spec/models/bar.rb +0 -15
- data/spec/models/father.rb +0 -21
- data/spec/models/persistence.rb +0 -164
- data/spec/models/son.rb +0 -3
- data/spec/unit/persistence/mongoid_persistance_spec.rb +0 -152
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
describe 'sequel' do
|
|
2
|
+
begin
|
|
3
|
+
require 'sequel'
|
|
4
|
+
require 'logger'
|
|
5
|
+
require 'spec_helper'
|
|
6
|
+
|
|
7
|
+
Dir[File.dirname(__FILE__) + "/../../models/sequel/*.rb"].sort.each do |f|
|
|
8
|
+
require File.expand_path(f)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
before(:all) do
|
|
12
|
+
@model = SequelMultiple
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
describe "instance methods" do
|
|
16
|
+
let(:model) {@model.new}
|
|
17
|
+
|
|
18
|
+
it "should respond to aasm persistence methods" do
|
|
19
|
+
expect(model).to respond_to(:aasm_read_state)
|
|
20
|
+
expect(model).to respond_to(:aasm_write_state)
|
|
21
|
+
expect(model).to respond_to(:aasm_write_state_without_persistence)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
it "should return the initial state when new and the aasm field is nil" do
|
|
25
|
+
expect(model.aasm(:left).current_state).to eq(:alpha)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
it "should save the initial state" do
|
|
29
|
+
model.save
|
|
30
|
+
expect(model.status).to eq("alpha")
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
it "should return the aasm column when new and the aasm field is not nil" do
|
|
34
|
+
model.status = "beta"
|
|
35
|
+
expect(model.aasm(:left).current_state).to eq(:beta)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
it "should return the aasm column when not new and the aasm_column is not nil" do
|
|
39
|
+
allow(model).to receive(:new?).and_return(false)
|
|
40
|
+
model.status = "gamma"
|
|
41
|
+
expect(model.aasm(:left).current_state).to eq(:gamma)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
it "should allow a nil state" do
|
|
45
|
+
allow(model).to receive(:new?).and_return(false)
|
|
46
|
+
model.status = nil
|
|
47
|
+
expect(model.aasm(:left).current_state).to be_nil
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
it "should not change the state if state is not loaded" do
|
|
51
|
+
model.release
|
|
52
|
+
model.save
|
|
53
|
+
model.class.select(:id).first.save
|
|
54
|
+
model.reload
|
|
55
|
+
expect(model.aasm(:left).current_state).to eq(:beta)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
it "should call aasm_ensure_initial_state on validation before create" do
|
|
59
|
+
expect(model).to receive(:aasm_ensure_initial_state).and_return(true)
|
|
60
|
+
model.valid?
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
it "should call aasm_ensure_initial_state before create, even if skipping validations" do
|
|
64
|
+
expect(model).to receive(:aasm_ensure_initial_state).and_return(true)
|
|
65
|
+
model.save(:validate => false)
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
describe 'subclasses' do
|
|
70
|
+
it "should have the same states as its parent class" do
|
|
71
|
+
expect(Class.new(@model).aasm(:left).states).to eq(@model.aasm(:left).states)
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
it "should have the same events as its parent class" do
|
|
75
|
+
expect(Class.new(@model).aasm(:left).events).to eq(@model.aasm(:left).events)
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
it "should have the same column as its parent even for the new dsl" do
|
|
79
|
+
expect(@model.aasm(:left).attribute_name).to eq(:status)
|
|
80
|
+
expect(Class.new(@model).aasm(:left).attribute_name).to eq(:status)
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
describe 'initial states' do
|
|
85
|
+
it 'should support conditions' do
|
|
86
|
+
@model.aasm(:left) do
|
|
87
|
+
initial_state lambda{ |m| m.default }
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
expect(@model.new(:default => :beta).aasm(:left).current_state).to eq(:beta)
|
|
91
|
+
expect(@model.new(:default => :gamma).aasm(:left).current_state).to eq(:gamma)
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
describe "complex example" do
|
|
96
|
+
it "works" do
|
|
97
|
+
record = ComplexSequelExample.new
|
|
98
|
+
expect(record.aasm(:left).current_state).to eql :one
|
|
99
|
+
expect(record.left).to be_nil
|
|
100
|
+
expect(record.aasm(:right).current_state).to eql :alpha
|
|
101
|
+
expect(record.right).to be_nil
|
|
102
|
+
|
|
103
|
+
record.save
|
|
104
|
+
expect_aasm_states record, :one, :alpha
|
|
105
|
+
record.reload
|
|
106
|
+
expect_aasm_states record, :one, :alpha
|
|
107
|
+
|
|
108
|
+
record.increment!
|
|
109
|
+
expect_aasm_states record, :two, :alpha
|
|
110
|
+
record.reload
|
|
111
|
+
expect_aasm_states record, :two, :alpha
|
|
112
|
+
|
|
113
|
+
record.level_up!
|
|
114
|
+
expect_aasm_states record, :two, :beta
|
|
115
|
+
record.reload
|
|
116
|
+
expect_aasm_states record, :two, :beta
|
|
117
|
+
|
|
118
|
+
record.increment!
|
|
119
|
+
expect { record.increment! }.to raise_error(AASM::InvalidTransition)
|
|
120
|
+
expect_aasm_states record, :three, :beta
|
|
121
|
+
record.reload
|
|
122
|
+
expect_aasm_states record, :three, :beta
|
|
123
|
+
|
|
124
|
+
record.level_up!
|
|
125
|
+
expect_aasm_states record, :three, :gamma
|
|
126
|
+
record.reload
|
|
127
|
+
expect_aasm_states record, :three, :gamma
|
|
128
|
+
|
|
129
|
+
record.level_down # without saving
|
|
130
|
+
expect_aasm_states record, :three, :beta
|
|
131
|
+
record.reload
|
|
132
|
+
expect_aasm_states record, :three, :gamma
|
|
133
|
+
|
|
134
|
+
record.level_down # without saving
|
|
135
|
+
expect_aasm_states record, :three, :beta
|
|
136
|
+
record.reset!
|
|
137
|
+
expect_aasm_states record, :one, :beta
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
def expect_aasm_states(record, left_state, right_state)
|
|
141
|
+
expect(record.aasm(:left).current_state).to eql left_state.to_sym
|
|
142
|
+
expect(record.left).to eql left_state.to_s
|
|
143
|
+
expect(record.aasm(:right).current_state).to eql right_state.to_sym
|
|
144
|
+
expect(record.right).to eql right_state.to_s
|
|
145
|
+
end
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
rescue LoadError
|
|
149
|
+
puts "------------------------------------------------------------------------"
|
|
150
|
+
puts "Not running Sequel multiple-specs because sequel gem is not installed!!!"
|
|
151
|
+
puts "------------------------------------------------------------------------"
|
|
152
|
+
end
|
|
153
|
+
end
|
|
@@ -1,33 +1,15 @@
|
|
|
1
|
-
|
|
2
1
|
describe 'sequel' do
|
|
3
2
|
begin
|
|
4
3
|
require 'sequel'
|
|
5
4
|
require 'logger'
|
|
6
5
|
require 'spec_helper'
|
|
7
6
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
# db.loggers << Logger.new($stderr)
|
|
12
|
-
db.create_table(:models) do
|
|
13
|
-
primary_key :id
|
|
14
|
-
String :status
|
|
15
|
-
end
|
|
7
|
+
Dir[File.dirname(__FILE__) + "/../../models/sequel/*.rb"].sort.each do |f|
|
|
8
|
+
require File.expand_path(f)
|
|
9
|
+
end
|
|
16
10
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
attr_accessor :default
|
|
20
|
-
include AASM
|
|
21
|
-
aasm :column => :status
|
|
22
|
-
aasm do
|
|
23
|
-
state :alpha, :initial => true
|
|
24
|
-
state :beta
|
|
25
|
-
state :gamma
|
|
26
|
-
event :release do
|
|
27
|
-
transitions :from => [:alpha, :beta, :gamma], :to => :beta
|
|
28
|
-
end
|
|
29
|
-
end
|
|
30
|
-
end
|
|
11
|
+
before(:all) do
|
|
12
|
+
@model = SequelSimple
|
|
31
13
|
end
|
|
32
14
|
|
|
33
15
|
describe "instance methods" do
|
|
@@ -43,6 +25,11 @@ describe 'sequel' do
|
|
|
43
25
|
expect(model.aasm.current_state).to eq(:alpha)
|
|
44
26
|
end
|
|
45
27
|
|
|
28
|
+
it "should save the initial state" do
|
|
29
|
+
model.save
|
|
30
|
+
expect(model.status).to eq("alpha")
|
|
31
|
+
end
|
|
32
|
+
|
|
46
33
|
it "should return the aasm column when new and the aasm field is not nil" do
|
|
47
34
|
model.status = "beta"
|
|
48
35
|
expect(model.aasm.current_state).to eq(:beta)
|
|
@@ -60,6 +47,14 @@ describe 'sequel' do
|
|
|
60
47
|
expect(model.aasm.current_state).to be_nil
|
|
61
48
|
end
|
|
62
49
|
|
|
50
|
+
it "should not change the state if state is not loaded" do
|
|
51
|
+
model.release
|
|
52
|
+
model.save
|
|
53
|
+
model.class.select(:id).first.save
|
|
54
|
+
model.reload
|
|
55
|
+
expect(model.aasm.current_state).to eq(:beta)
|
|
56
|
+
end
|
|
57
|
+
|
|
63
58
|
it "should call aasm_ensure_initial_state on validation before create" do
|
|
64
59
|
expect(model).to receive(:aasm_ensure_initial_state).and_return(true)
|
|
65
60
|
model.valid?
|
|
@@ -98,6 +93,8 @@ describe 'sequel' do
|
|
|
98
93
|
end
|
|
99
94
|
|
|
100
95
|
rescue LoadError
|
|
96
|
+
puts "------------------------------------------------------------------------"
|
|
101
97
|
puts "Not running Sequel specs because sequel gem is not installed!!!"
|
|
98
|
+
puts "------------------------------------------------------------------------"
|
|
102
99
|
end
|
|
103
100
|
end
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe 'testing the README examples' do
|
|
4
|
+
|
|
5
|
+
it 'Usage' do
|
|
6
|
+
class Job
|
|
7
|
+
include AASM
|
|
8
|
+
|
|
9
|
+
aasm do
|
|
10
|
+
state :sleeping, :initial => true
|
|
11
|
+
state :running
|
|
12
|
+
state :cleaning
|
|
13
|
+
|
|
14
|
+
event :run do
|
|
15
|
+
transitions :from => :sleeping, :to => :running
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
event :clean do
|
|
19
|
+
transitions :from => :running, :to => :cleaning
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
event :sleep do
|
|
23
|
+
transitions :from => [:running, :cleaning], :to => :sleeping
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
job = Job.new
|
|
29
|
+
|
|
30
|
+
expect(job.sleeping?).to eql true
|
|
31
|
+
expect(job.may_run?).to eql true
|
|
32
|
+
|
|
33
|
+
job.run
|
|
34
|
+
|
|
35
|
+
expect(job.running?).to eql true
|
|
36
|
+
expect(job.sleeping?).to eql false
|
|
37
|
+
expect(job.may_run?).to eql false
|
|
38
|
+
|
|
39
|
+
expect { job.run }.to raise_error(AASM::InvalidTransition)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
end
|
data/spec/unit/reloading_spec.rb
CHANGED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe 'state machine' do
|
|
4
|
+
let(:simple) { SimpleExample.new }
|
|
5
|
+
let(:multiple) { SimpleMultipleExample.new }
|
|
6
|
+
|
|
7
|
+
describe 'transition_from' do
|
|
8
|
+
it "works for simple state machines" do
|
|
9
|
+
expect(simple).to transition_from(:initialised).to(:filled_out).on_event(:fill_out)
|
|
10
|
+
expect(simple).to_not transition_from(:initialised).to(:authorised).on_event(:fill_out)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
it "works for multiple state machines" do
|
|
14
|
+
expect(multiple).to transition_from(:standing).to(:walking).on_event(:walk).on(:move)
|
|
15
|
+
expect(multiple).to_not transition_from(:standing).to(:running).on_event(:walk).on(:move)
|
|
16
|
+
|
|
17
|
+
expect(multiple).to transition_from(:sleeping).to(:processing).on_event(:start).on(:work)
|
|
18
|
+
expect(multiple).to_not transition_from(:sleeping).to(:sleeping).on_event(:start).on(:work)
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
describe 'allow_transition_to' do
|
|
23
|
+
it "works for simple state machines" do
|
|
24
|
+
expect(simple).to allow_transition_to(:filled_out)
|
|
25
|
+
expect(simple).to_not allow_transition_to(:authorised)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
it "works for multiple state machines" do
|
|
29
|
+
expect(multiple).to allow_transition_to(:walking).on(:move)
|
|
30
|
+
expect(multiple).to_not allow_transition_to(:standing).on(:move)
|
|
31
|
+
|
|
32
|
+
expect(multiple).to allow_transition_to(:processing).on(:work)
|
|
33
|
+
expect(multiple).to_not allow_transition_to(:sleeping).on(:work)
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
describe "have_state" do
|
|
38
|
+
it "works for simple state machines" do
|
|
39
|
+
expect(simple).to have_state :initialised
|
|
40
|
+
expect(simple).to_not have_state :filled_out
|
|
41
|
+
simple.fill_out
|
|
42
|
+
expect(simple).to have_state :filled_out
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
it "works for multiple state machines" do
|
|
46
|
+
expect(multiple).to have_state(:standing).on(:move)
|
|
47
|
+
expect(multiple).to_not have_state(:walking).on(:move)
|
|
48
|
+
multiple.walk
|
|
49
|
+
expect(multiple).to have_state(:walking).on(:move)
|
|
50
|
+
|
|
51
|
+
expect(multiple).to have_state(:sleeping).on(:work)
|
|
52
|
+
expect(multiple).to_not have_state(:processing).on(:work)
|
|
53
|
+
multiple.start
|
|
54
|
+
expect(multiple).to have_state(:processing).on(:work)
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
describe "allow_event" do
|
|
59
|
+
it "works for simple state machines" do
|
|
60
|
+
expect(simple).to allow_event :fill_out
|
|
61
|
+
expect(simple).to_not allow_event :authorise
|
|
62
|
+
simple.fill_out
|
|
63
|
+
expect(simple).to allow_event :authorise
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
it "works for multiple state machines" do
|
|
67
|
+
expect(multiple).to allow_event(:walk).on(:move)
|
|
68
|
+
expect(multiple).to_not allow_event(:hold).on(:move)
|
|
69
|
+
multiple.walk
|
|
70
|
+
expect(multiple).to allow_event(:hold).on(:move)
|
|
71
|
+
|
|
72
|
+
expect(multiple).to allow_event(:start).on(:work)
|
|
73
|
+
expect(multiple).to_not allow_event(:stop).on(:work)
|
|
74
|
+
multiple.start
|
|
75
|
+
expect(multiple).to allow_event(:stop).on(:work)
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
end
|
|
@@ -1,58 +1,42 @@
|
|
|
1
1
|
require 'spec_helper'
|
|
2
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
3
|
describe 'state machine' do
|
|
20
|
-
let(:
|
|
4
|
+
let(:simple) { SimpleExample.new }
|
|
21
5
|
|
|
22
6
|
it 'starts with an initial state' do
|
|
23
|
-
expect(
|
|
24
|
-
expect(
|
|
25
|
-
expect(
|
|
7
|
+
expect(simple.aasm.current_state).to eq(:initialised)
|
|
8
|
+
expect(simple).to respond_to(:initialised?)
|
|
9
|
+
expect(simple).to be_initialised
|
|
26
10
|
end
|
|
27
11
|
|
|
28
12
|
it 'allows transitions to other states' do
|
|
29
|
-
expect(
|
|
30
|
-
expect(
|
|
31
|
-
|
|
32
|
-
expect(
|
|
33
|
-
expect(
|
|
34
|
-
|
|
35
|
-
expect(
|
|
36
|
-
expect(
|
|
37
|
-
|
|
38
|
-
expect(
|
|
39
|
-
expect(
|
|
13
|
+
expect(simple).to respond_to(:fill_out)
|
|
14
|
+
expect(simple).to respond_to(:fill_out!)
|
|
15
|
+
simple.fill_out!
|
|
16
|
+
expect(simple).to respond_to(:filled_out?)
|
|
17
|
+
expect(simple).to be_filled_out
|
|
18
|
+
|
|
19
|
+
expect(simple).to respond_to(:authorise)
|
|
20
|
+
expect(simple).to respond_to(:authorise!)
|
|
21
|
+
simple.authorise
|
|
22
|
+
expect(simple).to respond_to(:authorised?)
|
|
23
|
+
expect(simple).to be_authorised
|
|
40
24
|
end
|
|
41
25
|
|
|
42
26
|
it 'denies transitions to other states' do
|
|
43
|
-
expect {
|
|
44
|
-
expect {
|
|
45
|
-
|
|
46
|
-
expect {
|
|
47
|
-
expect {
|
|
48
|
-
|
|
49
|
-
expect {
|
|
50
|
-
expect {
|
|
27
|
+
expect {simple.authorise}.to raise_error(AASM::InvalidTransition)
|
|
28
|
+
expect {simple.authorise!}.to raise_error(AASM::InvalidTransition)
|
|
29
|
+
simple.fill_out
|
|
30
|
+
expect {simple.fill_out}.to raise_error(AASM::InvalidTransition)
|
|
31
|
+
expect {simple.fill_out!}.to raise_error(AASM::InvalidTransition)
|
|
32
|
+
simple.authorise
|
|
33
|
+
expect {simple.fill_out}.to raise_error(AASM::InvalidTransition)
|
|
34
|
+
expect {simple.fill_out!}.to raise_error(AASM::InvalidTransition)
|
|
51
35
|
end
|
|
52
36
|
|
|
53
37
|
it 'defines constants for each state name' do
|
|
54
|
-
expect(
|
|
55
|
-
expect(
|
|
56
|
-
expect(
|
|
38
|
+
expect(SimpleExample::STATE_INITIALISED).to eq(:initialised)
|
|
39
|
+
expect(SimpleExample::STATE_FILLED_OUT).to eq(:filled_out)
|
|
40
|
+
expect(SimpleExample::STATE_AUTHORISED).to eq(:authorised)
|
|
57
41
|
end
|
|
58
42
|
end
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe 'state machine' do
|
|
4
|
+
let(:simple) { SimpleMultipleExample.new }
|
|
5
|
+
|
|
6
|
+
it 'starts with an initial state' do
|
|
7
|
+
expect(simple.aasm(:move).current_state).to eq(:standing)
|
|
8
|
+
expect(simple).to respond_to(:standing?)
|
|
9
|
+
expect(simple).to be_standing
|
|
10
|
+
|
|
11
|
+
expect(simple.aasm(:work).current_state).to eq(:sleeping)
|
|
12
|
+
expect(simple).to respond_to(:sleeping?)
|
|
13
|
+
expect(simple).to be_sleeping
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
it 'allows transitions to other states' do
|
|
17
|
+
expect(simple).to respond_to(:walk)
|
|
18
|
+
expect(simple).to respond_to(:walk!)
|
|
19
|
+
simple.walk!
|
|
20
|
+
expect(simple).to respond_to(:walking?)
|
|
21
|
+
expect(simple).to be_walking
|
|
22
|
+
|
|
23
|
+
expect(simple).to respond_to(:run)
|
|
24
|
+
expect(simple).to respond_to(:run!)
|
|
25
|
+
simple.run
|
|
26
|
+
expect(simple).to respond_to(:running?)
|
|
27
|
+
expect(simple).to be_running
|
|
28
|
+
|
|
29
|
+
expect(simple).to respond_to(:start)
|
|
30
|
+
expect(simple).to respond_to(:start!)
|
|
31
|
+
simple.start
|
|
32
|
+
expect(simple).to respond_to(:processing?)
|
|
33
|
+
expect(simple).to be_processing
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
it 'denies transitions to other states' do
|
|
37
|
+
expect {simple.hold}.to raise_error(AASM::InvalidTransition)
|
|
38
|
+
expect {simple.hold!}.to raise_error(AASM::InvalidTransition)
|
|
39
|
+
simple.walk
|
|
40
|
+
expect {simple.walk}.to raise_error(AASM::InvalidTransition)
|
|
41
|
+
expect {simple.walk!}.to raise_error(AASM::InvalidTransition)
|
|
42
|
+
simple.run
|
|
43
|
+
expect {simple.walk}.to raise_error(AASM::InvalidTransition)
|
|
44
|
+
expect {simple.walk!}.to raise_error(AASM::InvalidTransition)
|
|
45
|
+
|
|
46
|
+
expect {simple.stop}.to raise_error(AASM::InvalidTransition)
|
|
47
|
+
expect {simple.stop!}.to raise_error(AASM::InvalidTransition)
|
|
48
|
+
simple.start
|
|
49
|
+
expect {simple.start}.to raise_error(AASM::InvalidTransition)
|
|
50
|
+
expect {simple.start!}.to raise_error(AASM::InvalidTransition)
|
|
51
|
+
simple.stop
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
it 'defines constants for each state name' do
|
|
55
|
+
expect(SimpleMultipleExample::STATE_STANDING).to eq(:standing)
|
|
56
|
+
expect(SimpleMultipleExample::STATE_WALKING).to eq(:walking)
|
|
57
|
+
expect(SimpleMultipleExample::STATE_RUNNING).to eq(:running)
|
|
58
|
+
|
|
59
|
+
expect(SimpleMultipleExample::STATE_SLEEPING).to eq(:sleeping)
|
|
60
|
+
expect(SimpleMultipleExample::STATE_PROCESSING).to eq(:processing)
|
|
61
|
+
expect(SimpleMultipleExample::STATE_RUNNING).to eq(:running)
|
|
62
|
+
end
|
|
63
|
+
end
|
data/spec/unit/state_spec.rb
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
require 'spec_helper'
|
|
2
2
|
|
|
3
3
|
describe AASM::Core::State do
|
|
4
|
+
let(:state_machine) { AASM::StateMachine.new(:name) }
|
|
5
|
+
|
|
4
6
|
before(:each) do
|
|
5
7
|
@name = :astate
|
|
6
8
|
@options = { :crazy_custom_key => 'key' }
|
|
7
9
|
end
|
|
8
10
|
|
|
9
11
|
def new_state(options={})
|
|
10
|
-
AASM::Core::State.new(@name, Conversation, @options.merge(options))
|
|
12
|
+
AASM::Core::State.new(@name, Conversation, state_machine, @options.merge(options))
|
|
11
13
|
end
|
|
12
14
|
|
|
13
15
|
it 'should set the name' do
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe 'subclassing with multiple state machines' do
|
|
4
|
+
|
|
5
|
+
it 'should have the parent states' do
|
|
6
|
+
SuperClassMultiple.aasm(:left).states.each do |state|
|
|
7
|
+
expect(SubClassWithMoreStatesMultiple.aasm(:left).states).to include(state)
|
|
8
|
+
end
|
|
9
|
+
expect(SubClassMultiple.aasm(:left).states).to eq(SuperClassMultiple.aasm(:left).states)
|
|
10
|
+
|
|
11
|
+
SuperClassMultiple.aasm(:right).states.each do |state|
|
|
12
|
+
expect(SubClassWithMoreStatesMultiple.aasm(:right).states).to include(state)
|
|
13
|
+
end
|
|
14
|
+
expect(SubClassMultiple.aasm(:right).states).to eq(SuperClassMultiple.aasm(:right).states)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
it 'should not add the child states to the parent machine' do
|
|
18
|
+
expect(SuperClassMultiple.aasm(:left).states).not_to include(:foo)
|
|
19
|
+
expect(SuperClassMultiple.aasm(:right).states).not_to include(:archived)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
it "should have the same events as its parent" do
|
|
23
|
+
expect(SubClassMultiple.aasm(:left).events).to eq(SuperClassMultiple.aasm(:left).events)
|
|
24
|
+
expect(SubClassMultiple.aasm(:right).events).to eq(SuperClassMultiple.aasm(:right).events)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
it 'should know how to respond to question methods' do
|
|
28
|
+
expect(SubClassMultiple.new.may_foo?).to be_truthy
|
|
29
|
+
expect(SubClassMultiple.new.may_close?).to be_truthy
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
it 'should not break if I call methods from super class' do
|
|
33
|
+
son = SubClassMultiple.new
|
|
34
|
+
son.update_state
|
|
35
|
+
expect(son.aasm(:left).current_state).to eq(:ended)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
end
|
|
39
|
+
|
|
@@ -1,30 +1,30 @@
|
|
|
1
1
|
require 'spec_helper'
|
|
2
2
|
|
|
3
3
|
describe 'subclassing' do
|
|
4
|
-
let(:son) {Son.new}
|
|
5
4
|
|
|
6
5
|
it 'should have the parent states' do
|
|
7
|
-
|
|
8
|
-
expect(
|
|
6
|
+
SuperClass.aasm.states.each do |state|
|
|
7
|
+
expect(SubClassWithMoreStates.aasm.states).to include(state)
|
|
9
8
|
end
|
|
10
|
-
expect(
|
|
9
|
+
expect(SubClass.aasm.states).to eq(SuperClass.aasm.states)
|
|
11
10
|
end
|
|
12
11
|
|
|
13
12
|
it 'should not add the child states to the parent machine' do
|
|
14
|
-
expect(
|
|
13
|
+
expect(SuperClass.aasm.states).not_to include(:foo)
|
|
15
14
|
end
|
|
16
15
|
|
|
17
16
|
it "should have the same events as its parent" do
|
|
18
|
-
expect(
|
|
17
|
+
expect(SubClass.aasm.events).to eq(SuperClass.aasm.events)
|
|
19
18
|
end
|
|
20
19
|
|
|
21
|
-
it 'should know how to respond to
|
|
22
|
-
expect(
|
|
20
|
+
it 'should know how to respond to question methods' do
|
|
21
|
+
expect(SubClass.new.may_foo?).to be_truthy
|
|
23
22
|
end
|
|
24
23
|
|
|
25
|
-
it 'should not break if I call
|
|
24
|
+
it 'should not break if I call methods from super class' do
|
|
25
|
+
son = SubClass.new
|
|
26
26
|
son.update_state
|
|
27
|
-
expect(son.aasm.current_state).to eq(:
|
|
27
|
+
expect(son.aasm.current_state).to eq(:ended)
|
|
28
28
|
end
|
|
29
29
|
|
|
30
30
|
end
|