aasm 4.11.1 → 5.2.0
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 +5 -5
- data/.github/ISSUE_TEMPLATE/bug_report.md +27 -0
- data/.github/ISSUE_TEMPLATE/feature_request.md +20 -0
- data/.travis.yml +56 -23
- data/Appraisals +67 -0
- data/CHANGELOG.md +112 -0
- data/CONTRIBUTING.md +24 -0
- data/Dockerfile +44 -0
- data/Gemfile +3 -21
- data/Gemfile.lock_old +151 -0
- data/LICENSE +1 -1
- data/README.md +540 -139
- data/Rakefile +6 -1
- data/TESTING.md +25 -0
- data/aasm.gemspec +5 -0
- data/docker-compose.yml +40 -0
- data/gemfiles/norails.gemfile +10 -0
- data/gemfiles/rails_4.2.gemfile +13 -11
- data/gemfiles/rails_4.2_mongoid_5.gemfile +8 -11
- data/gemfiles/rails_4.2_nobrainer.gemfile +9 -0
- data/gemfiles/rails_5.0.gemfile +11 -18
- data/gemfiles/rails_5.0_nobrainer.gemfile +9 -0
- data/gemfiles/rails_5.1.gemfile +14 -0
- data/gemfiles/rails_5.2.gemfile +14 -0
- data/lib/aasm/aasm.rb +40 -29
- data/lib/aasm/base.rb +61 -11
- data/lib/aasm/configuration.rb +10 -0
- data/lib/aasm/core/event.rb +45 -37
- data/lib/aasm/core/invoker.rb +129 -0
- data/lib/aasm/core/invokers/base_invoker.rb +75 -0
- data/lib/aasm/core/invokers/class_invoker.rb +52 -0
- data/lib/aasm/core/invokers/literal_invoker.rb +47 -0
- data/lib/aasm/core/invokers/proc_invoker.rb +59 -0
- data/lib/aasm/core/state.rb +22 -13
- data/lib/aasm/core/transition.rb +17 -69
- data/lib/aasm/dsl_helper.rb +24 -22
- data/lib/aasm/errors.rb +4 -6
- data/lib/aasm/instance_base.rb +22 -4
- data/lib/aasm/localizer.rb +13 -3
- data/lib/aasm/minitest/allow_event.rb +13 -0
- data/lib/aasm/minitest/allow_transition_to.rb +13 -0
- data/lib/aasm/minitest/have_state.rb +13 -0
- data/lib/aasm/minitest/transition_from.rb +21 -0
- data/lib/aasm/minitest.rb +5 -0
- data/lib/aasm/minitest_spec.rb +15 -0
- data/lib/aasm/persistence/active_record_persistence.rb +49 -105
- data/lib/aasm/persistence/base.rb +20 -5
- data/lib/aasm/persistence/core_data_query_persistence.rb +2 -1
- data/lib/aasm/persistence/dynamoid_persistence.rb +1 -1
- data/lib/aasm/persistence/mongoid_persistence.rb +26 -32
- data/lib/aasm/persistence/no_brainer_persistence.rb +105 -0
- data/lib/aasm/persistence/orm.rb +154 -0
- data/lib/aasm/persistence/plain_persistence.rb +2 -1
- data/lib/aasm/persistence/redis_persistence.rb +16 -11
- data/lib/aasm/persistence/sequel_persistence.rb +36 -64
- data/lib/aasm/persistence.rb +3 -3
- data/lib/aasm/rspec/allow_event.rb +5 -1
- data/lib/aasm/rspec/allow_transition_to.rb +5 -1
- data/lib/aasm/rspec/transition_from.rb +5 -1
- data/lib/aasm/state_machine.rb +4 -2
- data/lib/aasm/state_machine_store.rb +5 -2
- data/lib/aasm/version.rb +1 -1
- data/lib/aasm.rb +5 -2
- data/lib/generators/aasm/orm_helpers.rb +6 -0
- data/lib/generators/active_record/aasm_generator.rb +3 -1
- data/lib/generators/active_record/templates/migration.rb +1 -1
- data/lib/generators/active_record/templates/migration_existing.rb +1 -1
- data/lib/generators/nobrainer/aasm_generator.rb +28 -0
- data/lib/motion-aasm.rb +3 -1
- data/spec/database.rb +20 -7
- data/spec/en.yml +0 -3
- data/spec/generators/active_record_generator_spec.rb +49 -40
- data/spec/generators/mongoid_generator_spec.rb +4 -6
- data/spec/generators/no_brainer_generator_spec.rb +29 -0
- data/spec/{en_deprecated_style.yml → localizer_test_model_deprecated_style.yml} +6 -3
- data/spec/localizer_test_model_new_style.yml +11 -0
- data/spec/models/active_record/active_record_callback.rb +93 -0
- data/spec/models/active_record/complex_active_record_example.rb +5 -1
- data/spec/models/active_record/instance_level_skip_validation_example.rb +19 -0
- data/spec/models/{invalid_persistor.rb → active_record/invalid_persistor.rb} +0 -2
- data/spec/models/active_record/localizer_test_model.rb +11 -3
- data/spec/models/active_record/namespaced.rb +16 -0
- data/spec/models/active_record/person.rb +23 -0
- data/spec/models/{silent_persistor.rb → active_record/silent_persistor.rb} +0 -2
- data/spec/models/active_record/simple_new_dsl.rb +15 -0
- data/spec/models/active_record/timestamp_example.rb +16 -0
- data/spec/models/{transactor.rb → active_record/transactor.rb} +25 -2
- data/spec/models/{validator.rb → active_record/validator.rb} +0 -2
- data/spec/models/active_record/work.rb +3 -0
- data/spec/models/{worker.rb → active_record/worker.rb} +0 -0
- data/spec/models/callbacks/basic.rb +5 -2
- data/spec/models/callbacks/with_state_arg.rb +5 -1
- data/spec/models/callbacks/with_state_arg_multiple.rb +4 -1
- data/spec/models/default_state.rb +1 -1
- data/spec/models/guard_arguments_check.rb +17 -0
- data/spec/models/guard_with_params.rb +1 -1
- data/spec/models/guardian_without_from_specified.rb +18 -0
- data/spec/models/mongoid/invalid_persistor_mongoid.rb +39 -0
- data/spec/models/mongoid/silent_persistor_mongoid.rb +39 -0
- data/spec/models/mongoid/timestamp_example_mongoid.rb +20 -0
- data/spec/models/mongoid/validator_mongoid.rb +100 -0
- data/spec/models/multiple_transitions_that_differ_only_by_guard.rb +31 -0
- data/spec/models/namespaced_multiple_example.rb +14 -0
- data/spec/models/nobrainer/complex_no_brainer_example.rb +36 -0
- data/spec/models/nobrainer/invalid_persistor_no_brainer.rb +39 -0
- data/spec/models/nobrainer/no_scope_no_brainer.rb +21 -0
- data/spec/models/nobrainer/nobrainer_relationships.rb +25 -0
- data/spec/models/nobrainer/silent_persistor_no_brainer.rb +39 -0
- data/spec/models/nobrainer/simple_new_dsl_nobrainer.rb +25 -0
- data/spec/models/{mongo_mapper/simple_mongo_mapper.rb → nobrainer/simple_no_brainer.rb} +8 -8
- data/spec/models/nobrainer/validator_no_brainer.rb +98 -0
- data/spec/models/parametrised_event.rb +7 -0
- data/spec/models/{mongo_mapper/complex_mongo_mapper_example.rb → redis/complex_redis_example.rb} +8 -5
- data/spec/models/redis/redis_multiple.rb +20 -0
- data/spec/models/redis/redis_simple.rb +20 -0
- data/spec/models/sequel/complex_sequel_example.rb +4 -3
- data/spec/models/sequel/invalid_persistor.rb +52 -0
- data/spec/models/sequel/sequel_multiple.rb +13 -13
- data/spec/models/sequel/sequel_simple.rb +13 -12
- data/spec/models/sequel/silent_persistor.rb +50 -0
- data/spec/models/sequel/transactor.rb +112 -0
- data/spec/models/sequel/validator.rb +93 -0
- data/spec/models/sequel/worker.rb +12 -0
- data/spec/models/simple_example.rb +8 -0
- data/spec/models/simple_example_with_guard_args.rb +17 -0
- data/spec/models/simple_multiple_example.rb +12 -0
- data/spec/models/sub_class.rb +34 -0
- data/spec/models/timestamps_example.rb +19 -0
- data/spec/models/timestamps_with_named_machine_example.rb +13 -0
- data/spec/spec_helper.rb +15 -33
- data/spec/spec_helpers/active_record.rb +8 -0
- data/spec/spec_helpers/dynamoid.rb +35 -0
- data/spec/spec_helpers/mongoid.rb +26 -0
- data/spec/spec_helpers/nobrainer.rb +15 -0
- data/spec/spec_helpers/redis.rb +18 -0
- data/spec/spec_helpers/remove_warnings.rb +1 -0
- data/spec/spec_helpers/sequel.rb +7 -0
- data/spec/unit/abstract_class_spec.rb +27 -0
- data/spec/unit/api_spec.rb +79 -72
- data/spec/unit/callback_multiple_spec.rb +7 -3
- data/spec/unit/callbacks_spec.rb +37 -2
- data/spec/unit/complex_example_spec.rb +12 -3
- data/spec/unit/complex_multiple_example_spec.rb +20 -4
- data/spec/unit/event_multiple_spec.rb +1 -1
- data/spec/unit/event_spec.rb +29 -4
- data/spec/unit/exception_spec.rb +1 -1
- data/spec/unit/guard_arguments_check_spec.rb +9 -0
- data/spec/unit/guard_spec.rb +17 -0
- data/spec/unit/guard_with_params_spec.rb +4 -0
- data/spec/unit/guard_without_from_specified_spec.rb +10 -0
- data/spec/unit/inspection_multiple_spec.rb +9 -5
- data/spec/unit/inspection_spec.rb +7 -3
- data/spec/unit/invoker_spec.rb +189 -0
- data/spec/unit/invokers/base_invoker_spec.rb +72 -0
- data/spec/unit/invokers/class_invoker_spec.rb +95 -0
- data/spec/unit/invokers/literal_invoker_spec.rb +86 -0
- data/spec/unit/invokers/proc_invoker_spec.rb +86 -0
- data/spec/unit/localizer_spec.rb +85 -52
- data/spec/unit/multiple_transitions_that_differ_only_by_guard_spec.rb +14 -0
- data/spec/unit/namespaced_multiple_example_spec.rb +22 -0
- data/spec/unit/override_warning_spec.rb +8 -0
- data/spec/unit/persistence/active_record_persistence_multiple_spec.rb +468 -447
- data/spec/unit/persistence/active_record_persistence_spec.rb +639 -486
- data/spec/unit/persistence/dynamoid_persistence_multiple_spec.rb +4 -9
- data/spec/unit/persistence/dynamoid_persistence_spec.rb +4 -9
- data/spec/unit/persistence/mongoid_persistence_multiple_spec.rb +83 -13
- data/spec/unit/persistence/mongoid_persistence_spec.rb +97 -13
- data/spec/unit/persistence/no_brainer_persistence_multiple_spec.rb +198 -0
- data/spec/unit/persistence/no_brainer_persistence_spec.rb +158 -0
- data/spec/unit/persistence/redis_persistence_multiple_spec.rb +88 -0
- data/spec/unit/persistence/redis_persistence_spec.rb +8 -32
- data/spec/unit/persistence/sequel_persistence_multiple_spec.rb +6 -11
- data/spec/unit/persistence/sequel_persistence_spec.rb +278 -10
- data/spec/unit/rspec_matcher_spec.rb +9 -0
- data/spec/unit/simple_example_spec.rb +15 -0
- data/spec/unit/simple_multiple_example_spec.rb +28 -0
- data/spec/unit/state_spec.rb +23 -7
- data/spec/unit/subclassing_multiple_spec.rb +37 -2
- data/spec/unit/subclassing_spec.rb +17 -2
- data/spec/unit/timestamps_spec.rb +32 -0
- data/spec/unit/transition_spec.rb +1 -1
- data/test/minitest_helper.rb +57 -0
- data/test/unit/minitest_matcher_test.rb +80 -0
- metadata +213 -37
- data/callbacks.txt +0 -51
- data/gemfiles/rails_3.2_stable.gemfile +0 -15
- data/gemfiles/rails_4.0.gemfile +0 -16
- data/gemfiles/rails_4.0_mongo_mapper.gemfile +0 -16
- data/gemfiles/rails_4.2_mongo_mapper.gemfile +0 -17
- data/lib/aasm/persistence/mongo_mapper_persistence.rb +0 -163
- data/spec/models/mongo_mapper/no_scope_mongo_mapper.rb +0 -21
- data/spec/models/mongo_mapper/simple_new_dsl_mongo_mapper.rb +0 -25
- data/spec/unit/persistence/mongo_mapper_persistence_multiple_spec.rb +0 -149
- data/spec/unit/persistence/mongo_mapper_persistence_spec.rb +0 -96
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
if defined?(ActiveRecord)
|
|
3
|
+
require 'models/active_record/person'
|
|
4
|
+
|
|
5
|
+
load_schema
|
|
6
|
+
describe 'Abstract subclassing' do
|
|
7
|
+
|
|
8
|
+
it 'should have the parent states' do
|
|
9
|
+
Person.aasm.states.each do |state|
|
|
10
|
+
expect(Base.aasm.states).to include(state)
|
|
11
|
+
end
|
|
12
|
+
expect(Person.aasm.states).to eq(Base.aasm.states)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
it 'should have the same events as its parent' do
|
|
16
|
+
expect(Base.aasm.events).to eq(Person.aasm.events)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
it 'should not break aasm methods when super class is abstract_class' do
|
|
20
|
+
person = Person.new
|
|
21
|
+
person.status = 'active'
|
|
22
|
+
person.deactivate!
|
|
23
|
+
expect(person.aasm.current_state).to eq(:inactive)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
end
|
|
27
|
+
end
|
data/spec/unit/api_spec.rb
CHANGED
|
@@ -1,97 +1,104 @@
|
|
|
1
1
|
require 'spec_helper'
|
|
2
|
-
require 'models/default_state.rb'
|
|
3
|
-
require 'models/provided_state.rb'
|
|
4
|
-
require 'models/active_record/persisted_state.rb'
|
|
5
|
-
require 'models/active_record/provided_and_persisted_state.rb'
|
|
6
2
|
|
|
7
|
-
|
|
3
|
+
if defined?(ActiveRecord)
|
|
4
|
+
require 'models/default_state.rb'
|
|
5
|
+
require 'models/provided_state.rb'
|
|
6
|
+
require 'models/active_record/persisted_state.rb'
|
|
7
|
+
require 'models/active_record/provided_and_persisted_state.rb'
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
it "uses the AASM default" do
|
|
11
|
-
expect(DefaultState.new.aasm.current_state).to eql :alpha
|
|
12
|
-
end
|
|
9
|
+
load_schema
|
|
13
10
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
11
|
+
describe "reading the current state" do
|
|
12
|
+
it "uses the AASM default" do
|
|
13
|
+
expect(DefaultState.new.aasm.current_state).to eql :alpha
|
|
14
|
+
end
|
|
17
15
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
16
|
+
it "uses display option" do
|
|
17
|
+
expect(DefaultState.new.aasm.human_state).to eql "ALPHA"
|
|
18
|
+
end
|
|
21
19
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
20
|
+
it "uses the provided method" do
|
|
21
|
+
expect(ProvidedState.new.aasm.current_state).to eql :beta
|
|
22
|
+
end
|
|
25
23
|
|
|
26
|
-
context "after dup" do
|
|
27
24
|
it "uses the persistence storage" do
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
copy.save!
|
|
25
|
+
expect(PersistedState.new.aasm.current_state).to eql :alpha
|
|
26
|
+
end
|
|
31
27
|
|
|
32
|
-
|
|
28
|
+
it "uses the provided method even if persisted" do
|
|
29
|
+
expect(ProvidedAndPersistedState.new.aasm.current_state).to eql :gamma
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
context "after dup" do
|
|
33
|
+
it "uses the persistence storage" do
|
|
34
|
+
source = PersistedState.create!
|
|
35
|
+
copy = source.dup
|
|
36
|
+
copy.save!
|
|
33
37
|
|
|
34
|
-
|
|
35
|
-
expect(source.aasm.current_state).to eql :alpha
|
|
38
|
+
copy.release!
|
|
36
39
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
expect(source2.aasm.current_state).to eql :alpha
|
|
40
|
+
expect(source.aasm_state).to eql 'alpha'
|
|
41
|
+
expect(source.aasm.current_state).to eql :alpha
|
|
40
42
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
+
source2 = PersistedState.find(source.id)
|
|
44
|
+
expect(source2.reload.aasm_state).to eql 'alpha'
|
|
45
|
+
expect(source2.aasm.current_state).to eql :alpha
|
|
46
|
+
|
|
47
|
+
expect(copy.aasm_state).to eql 'beta'
|
|
48
|
+
expect(copy.aasm.current_state).to eql :beta
|
|
49
|
+
end
|
|
43
50
|
end
|
|
44
51
|
end
|
|
45
|
-
end
|
|
46
52
|
|
|
47
|
-
describe "writing and persisting the current state" do
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
+
describe "writing and persisting the current state" do
|
|
54
|
+
it "uses the AASM default" do
|
|
55
|
+
o = DefaultState.new
|
|
56
|
+
o.release!
|
|
57
|
+
expect(o.persisted_store).to be_nil
|
|
58
|
+
end
|
|
53
59
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
60
|
+
it "uses the provided method" do
|
|
61
|
+
o = ProvidedState.new
|
|
62
|
+
o.release!
|
|
63
|
+
expect(o.persisted_store).to eql :beta
|
|
64
|
+
end
|
|
59
65
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
66
|
+
it "uses the persistence storage" do
|
|
67
|
+
o = PersistedState.new
|
|
68
|
+
o.release!
|
|
69
|
+
expect(o.persisted_store).to be_nil
|
|
70
|
+
end
|
|
65
71
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
72
|
+
it "uses the provided method even if persisted" do
|
|
73
|
+
o = ProvidedAndPersistedState.new
|
|
74
|
+
o.release!
|
|
75
|
+
expect(o.persisted_store).to eql :beta
|
|
76
|
+
end
|
|
70
77
|
end
|
|
71
|
-
end
|
|
72
78
|
|
|
73
|
-
describe "writing the current state without persisting it" do
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
+
describe "writing the current state without persisting it" do
|
|
80
|
+
it "uses the AASM default" do
|
|
81
|
+
o = DefaultState.new
|
|
82
|
+
o.release
|
|
83
|
+
expect(o.transient_store).to be_nil
|
|
84
|
+
end
|
|
79
85
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
86
|
+
it "uses the provided method" do
|
|
87
|
+
o = ProvidedState.new
|
|
88
|
+
o.release
|
|
89
|
+
expect(o.transient_store).to eql :beta
|
|
90
|
+
end
|
|
85
91
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
92
|
+
it "uses the persistence storage" do
|
|
93
|
+
o = PersistedState.new
|
|
94
|
+
o.release
|
|
95
|
+
expect(o.transient_store).to be_nil
|
|
96
|
+
end
|
|
91
97
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
98
|
+
it "uses the provided method even if persisted" do
|
|
99
|
+
o = ProvidedAndPersistedState.new
|
|
100
|
+
o.release
|
|
101
|
+
expect(o.transient_store).to eql :beta
|
|
102
|
+
end
|
|
96
103
|
end
|
|
97
104
|
end
|
|
@@ -49,7 +49,7 @@ describe 'callbacks for the new DSL' do
|
|
|
49
49
|
|
|
50
50
|
expect {
|
|
51
51
|
callback.left_close!
|
|
52
|
-
}.to raise_error(AASM::InvalidTransition, "Event 'left_close' cannot transition from 'open'. Failed callback(s): [:
|
|
52
|
+
}.to raise_error(AASM::InvalidTransition, "Event 'left_close' cannot transition from 'open'. Failed callback(s): [:event_guard].")
|
|
53
53
|
|
|
54
54
|
end
|
|
55
55
|
|
|
@@ -88,7 +88,7 @@ describe 'callbacks for the new DSL' do
|
|
|
88
88
|
|
|
89
89
|
expect {
|
|
90
90
|
callback.left_close!
|
|
91
|
-
}.to raise_error(AASM::InvalidTransition, "Event 'left_close' cannot transition from 'open'. Failed callback(s): [:
|
|
91
|
+
}.to raise_error(AASM::InvalidTransition, "Event 'left_close' cannot transition from 'open'. Failed callback(s): [:transition_guard].")
|
|
92
92
|
end
|
|
93
93
|
|
|
94
94
|
it "does not run transition_guard twice for multiple permitted transitions" do
|
|
@@ -154,6 +154,8 @@ describe 'callbacks for the new DSL' do
|
|
|
154
154
|
expect(cb).to receive(:before_method).with(:arg1).once.ordered
|
|
155
155
|
expect(cb).to receive(:transition_method).never
|
|
156
156
|
expect(cb).to receive(:transition_method2).with(:arg1).once.ordered
|
|
157
|
+
expect(cb).to receive(:before_success_method).with(:arg1).once.ordered
|
|
158
|
+
expect(cb).to receive(:success_method).with(:arg1).once.ordered
|
|
157
159
|
expect(cb).to receive(:after_method).with(:arg1).once.ordered
|
|
158
160
|
cb.close!(:out_to_lunch, :arg1)
|
|
159
161
|
|
|
@@ -161,6 +163,8 @@ describe 'callbacks for the new DSL' do
|
|
|
161
163
|
some_object = double('some object')
|
|
162
164
|
expect(cb).to receive(:before_method).with(some_object).once.ordered
|
|
163
165
|
expect(cb).to receive(:transition_method2).with(some_object).once.ordered
|
|
166
|
+
expect(cb).to receive(:before_success_method).with(some_object).once.ordered
|
|
167
|
+
expect(cb).to receive(:success_method).with(some_object).once.ordered
|
|
164
168
|
expect(cb).to receive(:after_method).with(some_object).once.ordered
|
|
165
169
|
cb.close!(:out_to_lunch, some_object)
|
|
166
170
|
end
|
|
@@ -287,7 +291,7 @@ describe 'event callbacks' do
|
|
|
287
291
|
expect(@foo).to receive(:aasm_event_failed).with(:null, :open)
|
|
288
292
|
expect{
|
|
289
293
|
@foo.null
|
|
290
|
-
}.to raise_error(AASM::InvalidTransition, "Event 'null' cannot transition from 'open'. Failed callback(s): [:always_false
|
|
294
|
+
}.to raise_error(AASM::InvalidTransition, "Event 'null' cannot transition from 'open'. Failed callback(s): [:always_false].")
|
|
291
295
|
end
|
|
292
296
|
|
|
293
297
|
it 'should not call it if persist fails for bang fire' do
|
data/spec/unit/callbacks_spec.rb
CHANGED
|
@@ -3,14 +3,14 @@ Dir[File.dirname(__FILE__) + "/../models/callbacks/*.rb"].sort.each { |f| requir
|
|
|
3
3
|
|
|
4
4
|
shared_examples 'an implemented callback that accepts error' do
|
|
5
5
|
context 'with callback defined' do
|
|
6
|
-
it "should run error_callback if an exception is raised" do
|
|
6
|
+
it "should run error_callback if an exception is raised and always return false" do
|
|
7
7
|
aasm_model.class.send(:define_method, callback_name) do |e|
|
|
8
8
|
@data = [e]
|
|
9
9
|
end
|
|
10
10
|
|
|
11
11
|
allow(aasm_model).to receive(:before_enter).and_raise(e = StandardError.new)
|
|
12
12
|
|
|
13
|
-
aasm_model.safe_close!
|
|
13
|
+
expect(aasm_model.safe_close!).to be false
|
|
14
14
|
expect(aasm_model.data).to eql [e]
|
|
15
15
|
end
|
|
16
16
|
|
|
@@ -118,6 +118,7 @@ describe 'callbacks for the new DSL' do
|
|
|
118
118
|
expect(callback).to receive(:before_enter_closed).once.ordered
|
|
119
119
|
expect(callback).to receive(:enter_closed).once.ordered
|
|
120
120
|
expect(callback).to receive(:aasm_write_state).once.ordered.and_return(true) # this is when the state changes
|
|
121
|
+
expect(callback).to receive(:event_before_success).once.ordered
|
|
121
122
|
expect(callback).to receive(:success_transition).once.ordered.and_return(true) # these should be after the state changes
|
|
122
123
|
expect(callback).to receive(:after_exit_open).once.ordered
|
|
123
124
|
expect(callback).to receive(:after_enter_closed).once.ordered
|
|
@@ -143,6 +144,7 @@ describe 'callbacks for the new DSL' do
|
|
|
143
144
|
expect(callback).to_not receive(:before_enter_closed)
|
|
144
145
|
expect(callback).to_not receive(:enter_closed)
|
|
145
146
|
expect(callback).to_not receive(:aasm_write_state)
|
|
147
|
+
expect(callback).to_not receive(:event_before_success)
|
|
146
148
|
expect(callback).to_not receive(:success_transition)
|
|
147
149
|
expect(callback).to_not receive(:after_exit_open)
|
|
148
150
|
expect(callback).to_not receive(:after_enter_closed)
|
|
@@ -186,6 +188,7 @@ describe 'callbacks for the new DSL' do
|
|
|
186
188
|
expect(callback).to_not receive(:before_enter_closed)
|
|
187
189
|
expect(callback).to_not receive(:enter_closed)
|
|
188
190
|
expect(callback).to_not receive(:aasm_write_state)
|
|
191
|
+
expect(callback).to_not receive(:event_before_success)
|
|
189
192
|
expect(callback).to_not receive(:success_transition)
|
|
190
193
|
expect(callback).to_not receive(:after_exit_open)
|
|
191
194
|
expect(callback).to_not receive(:after_enter_closed)
|
|
@@ -200,6 +203,32 @@ describe 'callbacks for the new DSL' do
|
|
|
200
203
|
}.to raise_error(AASM::InvalidTransition)
|
|
201
204
|
end
|
|
202
205
|
|
|
206
|
+
it "does not propagate failures to next attempt of same transition" do
|
|
207
|
+
callback = Callbacks::Basic.new(:log => false, :fail_transition_guard => true)
|
|
208
|
+
|
|
209
|
+
expect {
|
|
210
|
+
callback.close!
|
|
211
|
+
}.to raise_error(AASM::InvalidTransition, "Event 'close' cannot transition from 'open'. Failed callback(s): [:transition_guard].")
|
|
212
|
+
|
|
213
|
+
expect {
|
|
214
|
+
callback.close!
|
|
215
|
+
}.to raise_error(AASM::InvalidTransition, "Event 'close' cannot transition from 'open'. Failed callback(s): [:transition_guard].")
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
it "does not propagate failures to next attempt of same event when no transition is applicable" do
|
|
219
|
+
callback = Callbacks::Basic.new(:log => false, :fail_transition_guard => true)
|
|
220
|
+
|
|
221
|
+
expect {
|
|
222
|
+
callback.close!
|
|
223
|
+
}.to raise_error(AASM::InvalidTransition, "Event 'close' cannot transition from 'open'. Failed callback(s): [:transition_guard].")
|
|
224
|
+
|
|
225
|
+
callback.aasm.current_state = :closed
|
|
226
|
+
|
|
227
|
+
expect {
|
|
228
|
+
callback.close!
|
|
229
|
+
}.to raise_error(AASM::InvalidTransition, "Event 'close' cannot transition from 'closed'.")
|
|
230
|
+
end
|
|
231
|
+
|
|
203
232
|
it "does not run transition_guard twice for multiple permitted transitions" do
|
|
204
233
|
show_debug_log = false
|
|
205
234
|
callback = Callbacks::MultipleTransitionsTransitionGuard.new(:log => show_debug_log, :fail_transition_guard => true)
|
|
@@ -217,6 +246,7 @@ describe 'callbacks for the new DSL' do
|
|
|
217
246
|
expect(callback).to receive(:after).once.ordered
|
|
218
247
|
|
|
219
248
|
expect(callback).to_not receive(:transitioning)
|
|
249
|
+
expect(callback).to_not receive(:event_before_success)
|
|
220
250
|
expect(callback).to_not receive(:success_transition)
|
|
221
251
|
expect(callback).to_not receive(:before_enter_closed)
|
|
222
252
|
expect(callback).to_not receive(:enter_closed)
|
|
@@ -240,6 +270,7 @@ describe 'callbacks for the new DSL' do
|
|
|
240
270
|
expect(callback).to_not receive(:before_enter_closed)
|
|
241
271
|
expect(callback).to_not receive(:enter_closed)
|
|
242
272
|
expect(callback).to_not receive(:aasm_write_state)
|
|
273
|
+
expect(callback).to_not receive(:event_before_success)
|
|
243
274
|
expect(callback).to_not receive(:success_transition)
|
|
244
275
|
expect(callback).to_not receive(:after_exit_open)
|
|
245
276
|
expect(callback).to_not receive(:after_enter_closed)
|
|
@@ -284,7 +315,9 @@ describe 'callbacks for the new DSL' do
|
|
|
284
315
|
expect(cb).to receive(:before_method).with(:arg1).once.ordered
|
|
285
316
|
expect(cb).to receive(:transition_method).with(:arg1).once.ordered
|
|
286
317
|
expect(cb).to receive(:transition_method).never
|
|
318
|
+
expect(cb).to receive(:before_success_method).with(:arg1).once.ordered
|
|
287
319
|
expect(cb).to receive(:success_method).with(:arg1).once.ordered
|
|
320
|
+
expect(cb).to receive(:success_method3).with(:arg1).once.ordered
|
|
288
321
|
expect(cb).to receive(:success_method).never
|
|
289
322
|
expect(cb).to receive(:after_method).with(:arg1).once.ordered
|
|
290
323
|
cb.close!(:arg1)
|
|
@@ -294,7 +327,9 @@ describe 'callbacks for the new DSL' do
|
|
|
294
327
|
expect(cb).to receive(:before_method).with(some_object).once.ordered
|
|
295
328
|
expect(cb).to receive(:transition_method).with(some_object).once.ordered
|
|
296
329
|
expect(cb).to receive(:transition_method).never
|
|
330
|
+
expect(cb).to receive(:before_success_method).with(some_object).once.ordered
|
|
297
331
|
expect(cb).to receive(:success_method).with(some_object).once.ordered
|
|
332
|
+
expect(cb).to receive(:success_method3).with(some_object).once.ordered
|
|
298
333
|
expect(cb).to receive(:success_method).never
|
|
299
334
|
expect(cb).to receive(:after_method).with(some_object).once.ordered
|
|
300
335
|
cb.close!(some_object)
|
|
@@ -30,14 +30,14 @@ describe 'when being unsuspended' do
|
|
|
30
30
|
it 'should be able to be unsuspended into active if polite' do
|
|
31
31
|
auth.suspend!
|
|
32
32
|
expect(auth.may_wait?(:waiting, :please)).to be true
|
|
33
|
-
auth.wait!(
|
|
33
|
+
auth.wait!(:please)
|
|
34
34
|
end
|
|
35
35
|
|
|
36
36
|
it 'should not be able to be unsuspended into active if not polite' do
|
|
37
37
|
auth.suspend!
|
|
38
38
|
expect(auth.may_wait?(:waiting)).not_to be true
|
|
39
39
|
expect(auth.may_wait?(:waiting, :rude)).not_to be true
|
|
40
|
-
expect {auth.wait!(
|
|
40
|
+
expect {auth.wait!(:rude)}.to raise_error(AASM::InvalidTransition)
|
|
41
41
|
expect {auth.wait!}.to raise_error(AASM::InvalidTransition)
|
|
42
42
|
end
|
|
43
43
|
|
|
@@ -77,8 +77,17 @@ describe 'when being unsuspended' do
|
|
|
77
77
|
expect(auth.aasm.may_fire_event?(:activate)).to be true
|
|
78
78
|
end
|
|
79
79
|
|
|
80
|
+
it "should be able to fire event by name" do
|
|
81
|
+
expect(auth.aasm.fire(:activate)).to be true
|
|
82
|
+
expect(auth.aasm.current_state).to eq(:active)
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
it "should be able to fire! event by name" do
|
|
86
|
+
expect(auth.aasm.fire!(:activate)).to be true
|
|
87
|
+
expect(auth.aasm.current_state).to eq(:active)
|
|
88
|
+
end
|
|
89
|
+
|
|
80
90
|
it "should not be able to fire unknown events" do
|
|
81
91
|
expect(auth.aasm.may_fire_event?(:unknown)).to be false
|
|
82
92
|
end
|
|
83
|
-
|
|
84
93
|
end
|
|
@@ -39,18 +39,18 @@ describe 'when being unsuspended' do
|
|
|
39
39
|
it 'should be able to wait into waiting if polite' do
|
|
40
40
|
auth.left_suspend!
|
|
41
41
|
expect(auth.may_left_wait?(:waiting, :please)).to be true
|
|
42
|
-
auth.left_wait!(
|
|
42
|
+
auth.left_wait!(:please)
|
|
43
43
|
|
|
44
44
|
auth.right_suspend!
|
|
45
45
|
expect(auth.may_right_wait?(:waiting)).to be false
|
|
46
|
-
auth.right_wait!(
|
|
46
|
+
auth.right_wait!(:please)
|
|
47
47
|
end
|
|
48
48
|
|
|
49
49
|
it 'should not be able to be unsuspended into active if not polite' do
|
|
50
50
|
auth.left_suspend!
|
|
51
51
|
expect(auth.may_left_wait?(:waiting)).not_to be true
|
|
52
52
|
expect(auth.may_left_wait?(:waiting, :rude)).not_to be true
|
|
53
|
-
expect {auth.left_wait!(
|
|
53
|
+
expect {auth.left_wait!(:rude)}.to raise_error(AASM::InvalidTransition)
|
|
54
54
|
expect {auth.left_wait!}.to raise_error(AASM::InvalidTransition)
|
|
55
55
|
end
|
|
56
56
|
|
|
@@ -91,9 +91,25 @@ describe 'when being unsuspended' do
|
|
|
91
91
|
expect(auth.aasm(:right).may_fire_event?(:right_activate)).to be true
|
|
92
92
|
end
|
|
93
93
|
|
|
94
|
-
it
|
|
94
|
+
it 'should not be able to fire unknown events' do
|
|
95
95
|
expect(auth.aasm(:left).may_fire_event?(:unknown)).to be false
|
|
96
96
|
expect(auth.aasm(:right).may_fire_event?(:unknown)).to be false
|
|
97
97
|
end
|
|
98
98
|
|
|
99
|
+
it 'should be able to fire event by name' do
|
|
100
|
+
expect(auth.aasm(:left).fire(:left_activate)).to be true
|
|
101
|
+
expect(auth.aasm(:left).current_state).to eq(:active)
|
|
102
|
+
|
|
103
|
+
expect(auth.aasm(:right).fire(:right_activate)).to be true
|
|
104
|
+
expect(auth.aasm(:right).current_state).to eq(:active)
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
it 'should be able to fire! event by name' do
|
|
108
|
+
expect(auth.aasm(:left).fire!(:left_activate)).to be true
|
|
109
|
+
expect(auth.aasm(:left).current_state).to eq(:active)
|
|
110
|
+
|
|
111
|
+
expect(auth.aasm(:right).fire!(:right_activate)).to be true
|
|
112
|
+
expect(auth.aasm(:right).current_state).to eq(:active)
|
|
113
|
+
end
|
|
114
|
+
|
|
99
115
|
end
|
data/spec/unit/event_spec.rb
CHANGED
|
@@ -106,7 +106,7 @@ describe 'firing an event' do
|
|
|
106
106
|
obj = double('object', :aasm => double('aasm', :current_state => :open))
|
|
107
107
|
expect(obj).to receive(:guard_fn).with('arg1', 'arg2').and_return(true)
|
|
108
108
|
|
|
109
|
-
expect(event.fire(obj, {},
|
|
109
|
+
expect(event.fire(obj, {}, 'arg1', 'arg2')).to eq(:closed)
|
|
110
110
|
end
|
|
111
111
|
|
|
112
112
|
context 'when given a gaurd proc' do
|
|
@@ -118,7 +118,7 @@ describe 'firing an event' do
|
|
|
118
118
|
line_number = __LINE__ - 2
|
|
119
119
|
obj = double('object', :aasm => double('aasm', :current_state => :student))
|
|
120
120
|
|
|
121
|
-
event.fire(obj, {}
|
|
121
|
+
event.fire(obj, {})
|
|
122
122
|
expect(event.failed_callbacks).to eq ["#{__FILE__}##{line_number}"]
|
|
123
123
|
end
|
|
124
124
|
end
|
|
@@ -133,7 +133,7 @@ describe 'firing an event' do
|
|
|
133
133
|
obj = double('object', :aasm => double('aasm', :current_state => :student))
|
|
134
134
|
allow(obj).to receive(:paid_tuition?).and_return(false)
|
|
135
135
|
|
|
136
|
-
event.fire(obj, {}
|
|
136
|
+
event.fire(obj, {})
|
|
137
137
|
expect(event.failed_callbacks).to eq [:paid_tuition?]
|
|
138
138
|
end
|
|
139
139
|
end
|
|
@@ -294,6 +294,19 @@ describe 'current event' do
|
|
|
294
294
|
pe.wakeup!
|
|
295
295
|
expect(pe.aasm.current_event).to eql :wakeup!
|
|
296
296
|
end
|
|
297
|
+
|
|
298
|
+
describe "when calling events with fire/fire!" do
|
|
299
|
+
it "fire should populate aasm.current_event and transition (sleeping to showering)" do
|
|
300
|
+
pe.aasm.fire(:wakeup)
|
|
301
|
+
expect(pe.aasm.current_event).to eq :wakeup
|
|
302
|
+
expect(pe.aasm.current_state).to eq :showering
|
|
303
|
+
end
|
|
304
|
+
it "fire! should populate aasm.current_event and transition (sleeping to showering)" do
|
|
305
|
+
pe.aasm.fire!(:wakeup)
|
|
306
|
+
expect(pe.aasm.current_event).to eq :wakeup!
|
|
307
|
+
expect(pe.aasm.current_state).to eq :showering
|
|
308
|
+
end
|
|
309
|
+
end
|
|
297
310
|
end
|
|
298
311
|
|
|
299
312
|
describe 'parametrised events' do
|
|
@@ -315,7 +328,7 @@ describe 'parametrised events' do
|
|
|
315
328
|
end
|
|
316
329
|
|
|
317
330
|
it 'should transition to default state when :after transition invoked' do
|
|
318
|
-
pe.dress!(
|
|
331
|
+
pe.dress!('purple', 'dressy')
|
|
319
332
|
expect(pe.aasm.current_state).to eq(:working)
|
|
320
333
|
end
|
|
321
334
|
|
|
@@ -325,6 +338,12 @@ describe 'parametrised events' do
|
|
|
325
338
|
pe.dress!(:working, 'blue', 'jeans')
|
|
326
339
|
end
|
|
327
340
|
|
|
341
|
+
it 'should call :after transition method if arg is nil' do
|
|
342
|
+
dryer = nil
|
|
343
|
+
expect(pe).to receive(:wet_hair).with(dryer)
|
|
344
|
+
pe.shower!(dryer)
|
|
345
|
+
end
|
|
346
|
+
|
|
328
347
|
it 'should call :after transition proc' do
|
|
329
348
|
pe.wakeup!(:showering)
|
|
330
349
|
expect(pe).to receive(:wear_clothes).with('purple', 'slacks')
|
|
@@ -344,6 +363,12 @@ describe 'parametrised events' do
|
|
|
344
363
|
pe.dress!(:working, 'foundation', 'SPF')
|
|
345
364
|
end
|
|
346
365
|
|
|
366
|
+
it 'should call :success transition method if arg is nil' do
|
|
367
|
+
shirt_color = nil
|
|
368
|
+
expect(pe).to receive(:wear_clothes).with(shirt_color)
|
|
369
|
+
pe.shower!(shirt_color)
|
|
370
|
+
end
|
|
371
|
+
|
|
347
372
|
it 'should call :success transition proc' do
|
|
348
373
|
pe.wakeup!(:showering)
|
|
349
374
|
expect(pe).to receive(:wear_makeup).with('purple', 'slacks')
|
data/spec/unit/exception_spec.rb
CHANGED
|
@@ -5,7 +5,7 @@ describe AASM::InvalidTransition do
|
|
|
5
5
|
process = ProcessWithNewDsl.new
|
|
6
6
|
expect { process.stop! }.to raise_error do |err|
|
|
7
7
|
process.start
|
|
8
|
-
expect(err.message).to eql("Event 'stop' cannot transition from 'sleeping'.
|
|
8
|
+
expect(err.message).to eql("Event 'stop' cannot transition from 'sleeping'.")
|
|
9
9
|
end
|
|
10
10
|
end
|
|
11
11
|
end
|
data/spec/unit/guard_spec.rb
CHANGED
|
@@ -70,3 +70,20 @@ describe "event guards" do
|
|
|
70
70
|
end
|
|
71
71
|
|
|
72
72
|
end
|
|
73
|
+
|
|
74
|
+
if defined?(ActiveRecord)
|
|
75
|
+
|
|
76
|
+
Dir[File.dirname(__FILE__) + "/../models/active_record/*.rb"].sort.each do |f|
|
|
77
|
+
require File.expand_path(f)
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
load_schema
|
|
81
|
+
|
|
82
|
+
describe "ActiveRecord per-transition guards" do
|
|
83
|
+
let(:example) { ComplexActiveRecordExample.new }
|
|
84
|
+
|
|
85
|
+
it "should be able to increment" do
|
|
86
|
+
expect(example.may_increment?).to be true
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
end
|
|
@@ -7,4 +7,8 @@ describe "guards with params" do
|
|
|
7
7
|
it "list permitted states" do
|
|
8
8
|
expect(guard.aasm.states({:permitted => true}, user).map(&:name)).to eql [:reviewed]
|
|
9
9
|
end
|
|
10
|
+
|
|
11
|
+
it "list no states if user is blank" do
|
|
12
|
+
expect(guard.aasm.states({:permitted => true}, nil).map(&:name)).to eql []
|
|
13
|
+
end
|
|
10
14
|
end
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe "transitions without from specified" do
|
|
4
|
+
let(:guardian) { GuardianWithoutFromSpecified.new }
|
|
5
|
+
|
|
6
|
+
it "allows the transitions if guard succeeds" do
|
|
7
|
+
expect { guardian.use_guards_where_the_first_fails! }.to_not raise_error
|
|
8
|
+
expect(guardian).to be_gamma
|
|
9
|
+
end
|
|
10
|
+
end
|
|
@@ -166,11 +166,15 @@ describe "special cases" do
|
|
|
166
166
|
end
|
|
167
167
|
|
|
168
168
|
describe 'aasm.states_for_select' do
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
169
|
+
context 'without I18n' do
|
|
170
|
+
before { allow(Module).to receive(:const_defined?).with(:I18n).and_return(nil) }
|
|
171
|
+
|
|
172
|
+
it "should return a select friendly array of states" do
|
|
173
|
+
expect(FooMultiple.aasm(:left)).to respond_to(:states_for_select)
|
|
174
|
+
expect(FooMultiple.aasm(:left).states_for_select).to eq(
|
|
175
|
+
[['Open', 'open'], ['Closed', 'closed'], ['Final', 'final']]
|
|
176
|
+
)
|
|
177
|
+
end
|
|
174
178
|
end
|
|
175
179
|
end
|
|
176
180
|
|
|
@@ -102,9 +102,13 @@ describe "special cases" do
|
|
|
102
102
|
end
|
|
103
103
|
|
|
104
104
|
describe 'aasm.states_for_select' do
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
105
|
+
context 'without I18n' do
|
|
106
|
+
before { allow(Module).to receive(:const_defined?).with(:I18n).and_return(nil) }
|
|
107
|
+
|
|
108
|
+
it "should return a select friendly array of states" do
|
|
109
|
+
expect(Foo.aasm).to respond_to(:states_for_select)
|
|
110
|
+
expect(Foo.aasm.states_for_select).to eq([['Open', 'open'], ['Closed', 'closed'], ['Final', 'final']])
|
|
111
|
+
end
|
|
108
112
|
end
|
|
109
113
|
end
|
|
110
114
|
|