aasm 5.0.8
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 +7 -0
- data/.document +6 -0
- data/.github/ISSUE_TEMPLATE/bug_report.md +27 -0
- data/.github/ISSUE_TEMPLATE/feature_request.md +20 -0
- data/.gitignore +20 -0
- data/.travis.yml +100 -0
- data/API +34 -0
- data/Appraisals +71 -0
- data/CHANGELOG.md +431 -0
- data/CODE_OF_CONDUCT.md +13 -0
- data/CONTRIBUTING.md +24 -0
- data/Dockerfile +44 -0
- data/Gemfile +6 -0
- data/Gemfile.lock_old +151 -0
- data/HOWTO +12 -0
- data/LICENSE +20 -0
- data/PLANNED_CHANGES.md +11 -0
- data/README.md +1439 -0
- data/README_FROM_VERSION_3_TO_4.md +240 -0
- data/Rakefile +31 -0
- data/TESTING.md +25 -0
- data/aasm.gemspec +37 -0
- data/callbacks.txt +51 -0
- data/docker-compose.yml +40 -0
- data/gemfiles/norails.gemfile +10 -0
- data/gemfiles/rails_3.2.gemfile +14 -0
- data/gemfiles/rails_4.2.gemfile +16 -0
- data/gemfiles/rails_4.2_mongoid_5.gemfile +11 -0
- data/gemfiles/rails_4.2_nobrainer.gemfile +9 -0
- data/gemfiles/rails_5.0.gemfile +13 -0
- data/gemfiles/rails_5.0_nobrainer.gemfile +9 -0
- data/gemfiles/rails_5.1.gemfile +13 -0
- data/gemfiles/rails_5.2.gemfile +13 -0
- data/lib/aasm.rb +23 -0
- data/lib/aasm/aasm.rb +208 -0
- data/lib/aasm/base.rb +271 -0
- data/lib/aasm/configuration.rb +45 -0
- data/lib/aasm/core/event.rb +172 -0
- 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 +90 -0
- data/lib/aasm/core/transition.rb +83 -0
- data/lib/aasm/dsl_helper.rb +30 -0
- data/lib/aasm/errors.rb +21 -0
- data/lib/aasm/instance_base.rb +133 -0
- data/lib/aasm/localizer.rb +54 -0
- data/lib/aasm/minitest.rb +5 -0
- 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_spec.rb +15 -0
- data/lib/aasm/persistence.rb +54 -0
- data/lib/aasm/persistence/active_record_persistence.rb +165 -0
- data/lib/aasm/persistence/base.rb +78 -0
- data/lib/aasm/persistence/core_data_query_persistence.rb +94 -0
- data/lib/aasm/persistence/dynamoid_persistence.rb +92 -0
- data/lib/aasm/persistence/mongoid_persistence.rb +126 -0
- data/lib/aasm/persistence/no_brainer_persistence.rb +105 -0
- data/lib/aasm/persistence/orm.rb +150 -0
- data/lib/aasm/persistence/plain_persistence.rb +26 -0
- data/lib/aasm/persistence/redis_persistence.rb +112 -0
- data/lib/aasm/persistence/sequel_persistence.rb +83 -0
- data/lib/aasm/rspec.rb +5 -0
- data/lib/aasm/rspec/allow_event.rb +26 -0
- data/lib/aasm/rspec/allow_transition_to.rb +26 -0
- data/lib/aasm/rspec/have_state.rb +22 -0
- data/lib/aasm/rspec/transition_from.rb +36 -0
- data/lib/aasm/state_machine.rb +53 -0
- data/lib/aasm/state_machine_store.rb +76 -0
- data/lib/aasm/version.rb +3 -0
- data/lib/generators/aasm/aasm_generator.rb +16 -0
- data/lib/generators/aasm/orm_helpers.rb +41 -0
- data/lib/generators/active_record/aasm_generator.rb +40 -0
- data/lib/generators/active_record/templates/migration.rb +8 -0
- data/lib/generators/active_record/templates/migration_existing.rb +5 -0
- data/lib/generators/mongoid/aasm_generator.rb +28 -0
- data/lib/generators/nobrainer/aasm_generator.rb +28 -0
- data/lib/motion-aasm.rb +37 -0
- data/spec/database.rb +59 -0
- data/spec/database.yml +3 -0
- data/spec/en.yml +12 -0
- data/spec/en_deprecated_style.yml +10 -0
- data/spec/generators/active_record_generator_spec.rb +53 -0
- data/spec/generators/mongoid_generator_spec.rb +31 -0
- data/spec/generators/no_brainer_generator_spec.rb +29 -0
- 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 +37 -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/instance_level_skip_validation_example.rb +19 -0
- data/spec/models/active_record/invalid_persistor.rb +29 -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/person.rb +23 -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/silent_persistor.rb +29 -0
- data/spec/models/active_record/simple_new_dsl.rb +32 -0
- data/spec/models/active_record/thief.rb +29 -0
- data/spec/models/active_record/transactor.rb +124 -0
- data/spec/models/active_record/transient.rb +6 -0
- data/spec/models/active_record/validator.rb +118 -0
- data/spec/models/active_record/with_enum.rb +39 -0
- data/spec/models/active_record/with_enum_without_column.rb +38 -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/work.rb +3 -0
- data/spec/models/active_record/worker.rb +2 -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 +98 -0
- data/spec/models/callbacks/basic_multiple.rb +75 -0
- data/spec/models/callbacks/guard_within_block.rb +67 -0
- data/spec/models/callbacks/guard_within_block_multiple.rb +66 -0
- data/spec/models/callbacks/multiple_transitions_transition_guard.rb +66 -0
- data/spec/models/callbacks/multiple_transitions_transition_guard_multiple.rb +65 -0
- data/spec/models/callbacks/private_method.rb +44 -0
- data/spec/models/callbacks/private_method_multiple.rb +44 -0
- data/spec/models/callbacks/with_args.rb +62 -0
- data/spec/models/callbacks/with_args_multiple.rb +61 -0
- data/spec/models/callbacks/with_state_arg.rb +34 -0
- data/spec/models/callbacks/with_state_arg_multiple.rb +29 -0
- data/spec/models/complex_example.rb +222 -0
- data/spec/models/conversation.rb +93 -0
- data/spec/models/default_state.rb +12 -0
- data/spec/models/double_definer.rb +21 -0
- data/spec/models/dynamoid/complex_dynamoid_example.rb +37 -0
- data/spec/models/dynamoid/dynamoid_multiple.rb +18 -0
- data/spec/models/dynamoid/dynamoid_simple.rb +18 -0
- data/spec/models/foo.rb +106 -0
- data/spec/models/foo_callback_multiple.rb +45 -0
- data/spec/models/guard_arguments_check.rb +17 -0
- data/spec/models/guard_with_params.rb +24 -0
- data/spec/models/guard_with_params_multiple.rb +18 -0
- data/spec/models/guardian.rb +58 -0
- data/spec/models/guardian_multiple.rb +48 -0
- data/spec/models/guardian_without_from_specified.rb +18 -0
- data/spec/models/initial_state_proc.rb +31 -0
- data/spec/models/mongoid/complex_mongoid_example.rb +37 -0
- data/spec/models/mongoid/invalid_persistor_mongoid.rb +39 -0
- data/spec/models/mongoid/mongoid_relationships.rb +26 -0
- data/spec/models/mongoid/no_scope_mongoid.rb +21 -0
- data/spec/models/mongoid/silent_persistor_mongoid.rb +39 -0
- data/spec/models/mongoid/simple_mongoid.rb +23 -0
- data/spec/models/mongoid/simple_new_dsl_mongoid.rb +25 -0
- data/spec/models/mongoid/validator_mongoid.rb +100 -0
- data/spec/models/multi_transitioner.rb +34 -0
- data/spec/models/multiple_transitions_that_differ_only_by_guard.rb +31 -0
- data/spec/models/namespaced_multiple_example.rb +42 -0
- data/spec/models/no_initial_state.rb +25 -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/nobrainer/simple_no_brainer.rb +23 -0
- data/spec/models/nobrainer/validator_no_brainer.rb +98 -0
- data/spec/models/not_auto_loaded/process.rb +21 -0
- data/spec/models/parametrised_event.rb +42 -0
- data/spec/models/parametrised_event_multiple.rb +29 -0
- data/spec/models/process_with_new_dsl.rb +31 -0
- data/spec/models/provided_state.rb +24 -0
- data/spec/models/redis/complex_redis_example.rb +40 -0
- 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 +46 -0
- data/spec/models/sequel/invalid_persistor.rb +52 -0
- data/spec/models/sequel/sequel_multiple.rb +25 -0
- data/spec/models/sequel/sequel_simple.rb +26 -0
- 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/silencer.rb +27 -0
- data/spec/models/simple_custom_example.rb +53 -0
- data/spec/models/simple_example.rb +23 -0
- data/spec/models/simple_example_with_guard_args.rb +17 -0
- data/spec/models/simple_multiple_example.rb +42 -0
- data/spec/models/state_machine_with_failed_event.rb +20 -0
- data/spec/models/states_on_one_line_example.rb +8 -0
- data/spec/models/sub_class.rb +41 -0
- data/spec/models/sub_class_with_more_states.rb +18 -0
- data/spec/models/sub_classing.rb +3 -0
- data/spec/models/super_class.rb +46 -0
- data/spec/models/this_name_better_not_be_in_use.rb +11 -0
- data/spec/models/valid_state_name.rb +23 -0
- data/spec/spec_helper.rb +36 -0
- 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 +100 -0
- data/spec/unit/basic_two_state_machines_example_spec.rb +10 -0
- data/spec/unit/callback_multiple_spec.rb +304 -0
- data/spec/unit/callbacks_spec.rb +521 -0
- data/spec/unit/complex_example_spec.rb +93 -0
- data/spec/unit/complex_multiple_example_spec.rb +115 -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 +16 -0
- data/spec/unit/event_spec.rb +394 -0
- data/spec/unit/exception_spec.rb +11 -0
- data/spec/unit/guard_arguments_check_spec.rb +9 -0
- data/spec/unit/guard_multiple_spec.rb +60 -0
- data/spec/unit/guard_spec.rb +89 -0
- data/spec/unit/guard_with_params_multiple_spec.rb +10 -0
- data/spec/unit/guard_with_params_spec.rb +14 -0
- data/spec/unit/guard_without_from_specified_spec.rb +10 -0
- data/spec/unit/initial_state_multiple_spec.rb +15 -0
- data/spec/unit/initial_state_spec.rb +12 -0
- data/spec/unit/inspection_multiple_spec.rb +201 -0
- data/spec/unit/inspection_spec.rb +149 -0
- 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 +78 -0
- data/spec/unit/memory_leak_spec.rb +38 -0
- data/spec/unit/multiple_transitions_that_differ_only_by_guard_spec.rb +14 -0
- data/spec/unit/namespaced_multiple_example_spec.rb +75 -0
- data/spec/unit/new_dsl_spec.rb +12 -0
- data/spec/unit/override_warning_spec.rb +94 -0
- data/spec/unit/persistence/active_record_persistence_multiple_spec.rb +618 -0
- data/spec/unit/persistence/active_record_persistence_spec.rb +773 -0
- data/spec/unit/persistence/dynamoid_persistence_multiple_spec.rb +135 -0
- data/spec/unit/persistence/dynamoid_persistence_spec.rb +84 -0
- data/spec/unit/persistence/mongoid_persistence_multiple_spec.rb +200 -0
- data/spec/unit/persistence/mongoid_persistence_spec.rb +165 -0
- 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 +53 -0
- data/spec/unit/persistence/sequel_persistence_multiple_spec.rb +148 -0
- data/spec/unit/persistence/sequel_persistence_spec.rb +368 -0
- data/spec/unit/readme_spec.rb +41 -0
- data/spec/unit/reloading_spec.rb +15 -0
- data/spec/unit/rspec_matcher_spec.rb +88 -0
- data/spec/unit/simple_custom_example_spec.rb +39 -0
- data/spec/unit/simple_example_spec.rb +57 -0
- data/spec/unit/simple_multiple_example_spec.rb +91 -0
- data/spec/unit/state_spec.rb +89 -0
- data/spec/unit/states_on_one_line_example_spec.rb +16 -0
- data/spec/unit/subclassing_multiple_spec.rb +74 -0
- data/spec/unit/subclassing_spec.rb +46 -0
- data/spec/unit/transition_spec.rb +436 -0
- data/test/minitest_helper.rb +57 -0
- data/test/unit/minitest_matcher_test.rb +80 -0
- metadata +609 -0
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'subclassing' do
|
4
|
+
|
5
|
+
it 'should have the parent states' do
|
6
|
+
SuperClass.aasm.states.each do |state|
|
7
|
+
expect(SubClassWithMoreStates.aasm.states).to include(state)
|
8
|
+
end
|
9
|
+
expect(SubClass.aasm.states).to eq(SuperClass.aasm.states)
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'should not add the child states to the parent machine' do
|
13
|
+
expect(SuperClass.aasm.states).not_to include(:foo)
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'should have the same events as its parent' do
|
17
|
+
expect(SubClass.aasm.events).to eq(SuperClass.aasm.events)
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'should know how to respond to question methods' do
|
21
|
+
expect(SubClass.new.may_foo?).to be_truthy
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'should not break if I call methods from super class' do
|
25
|
+
son = SubClass.new
|
26
|
+
son.update_state
|
27
|
+
expect(son.aasm.current_state).to eq(:ended)
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'should allow the child to modify its state machine' do
|
31
|
+
son = SubClass.new
|
32
|
+
expect(son.called_after).to eq(nil)
|
33
|
+
son.foo
|
34
|
+
expect(son.called_after).to eq(true)
|
35
|
+
global_callbacks = SubClass.aasm.state_machine.global_callbacks
|
36
|
+
expect(global_callbacks).to_not be_empty
|
37
|
+
expect(global_callbacks[:after_all_transitions]).to eq :after_all_event
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'should not modify the parent state machine' do
|
41
|
+
super_class_event = SuperClass.aasm.events.select { |event| event.name == :foo }.first
|
42
|
+
expect(super_class_event.options).to be_empty
|
43
|
+
expect(SuperClass.aasm.state_machine.global_callbacks).to be_empty
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
@@ -0,0 +1,436 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'transitions' do
|
4
|
+
|
5
|
+
it 'should raise an exception when whiny' do
|
6
|
+
process = ProcessWithNewDsl.new
|
7
|
+
expect { process.stop! }.to raise_error do |err|
|
8
|
+
expect(err.class).to eql(AASM::InvalidTransition)
|
9
|
+
expect(err.message).to eql("Event 'stop' cannot transition from 'sleeping'.")
|
10
|
+
expect(err.object).to eql(process)
|
11
|
+
expect(err.event_name).to eql(:stop)
|
12
|
+
end
|
13
|
+
expect(process).to be_sleeping
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'should not raise an exception when not whiny' do
|
17
|
+
silencer = Silencer.new
|
18
|
+
expect(silencer.smile!).to be_falsey
|
19
|
+
expect(silencer).to be_silent
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'should not raise an exception when superclass not whiny' do
|
23
|
+
sub = SubClassing.new
|
24
|
+
expect(sub.smile!).to be_falsey
|
25
|
+
expect(sub).to be_silent
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'should not raise an exception when from is nil even if whiny' do
|
29
|
+
silencer = Silencer.new
|
30
|
+
expect(silencer.smile_any!).to be_truthy
|
31
|
+
expect(silencer).to be_smiling
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'should call the block on success' do
|
35
|
+
silencer = Silencer.new
|
36
|
+
success = false
|
37
|
+
expect {
|
38
|
+
silencer.smile_any! do
|
39
|
+
success = true
|
40
|
+
end
|
41
|
+
}.to change { success }.to(true)
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'should not call the block on failure' do
|
45
|
+
silencer = Silencer.new
|
46
|
+
success = false
|
47
|
+
expect {
|
48
|
+
silencer.smile! do
|
49
|
+
success = true
|
50
|
+
end
|
51
|
+
}.not_to change { success }
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
|
56
|
+
describe AASM::Core::Transition do
|
57
|
+
let(:state_machine) { AASM::StateMachine.new(:name) }
|
58
|
+
let(:event) { AASM::Core::Event.new(:event, state_machine) }
|
59
|
+
|
60
|
+
it 'should set from, to, and opts attr readers' do
|
61
|
+
opts = {:from => 'foo', :to => 'bar', :guard => 'g'}
|
62
|
+
st = AASM::Core::Transition.new(event, opts)
|
63
|
+
|
64
|
+
expect(st.from).to eq(opts[:from])
|
65
|
+
expect(st.to).to eq(opts[:to])
|
66
|
+
expect(st.opts).to eq(opts)
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'should set on_transition with deprecation warning' do
|
70
|
+
opts = {:from => 'foo', :to => 'bar'}
|
71
|
+
st = AASM::Core::Transition.allocate
|
72
|
+
expect(st).to receive(:warn).with('[DEPRECATION] :on_transition is deprecated, use :after instead')
|
73
|
+
|
74
|
+
st.send :initialize, event, opts do
|
75
|
+
guard :gg
|
76
|
+
on_transition :after_callback
|
77
|
+
end
|
78
|
+
|
79
|
+
expect(st.opts[:after]).to eql [:after_callback]
|
80
|
+
end
|
81
|
+
|
82
|
+
it 'should set after, guard and success from dsl' do
|
83
|
+
opts = {:from => 'foo', :to => 'bar', :guard => 'g'}
|
84
|
+
st = AASM::Core::Transition.new(event, opts) do
|
85
|
+
guard :gg
|
86
|
+
after :after_callback
|
87
|
+
success :after_persist
|
88
|
+
end
|
89
|
+
|
90
|
+
expect(st.opts[:guard]).to eql ['g', :gg]
|
91
|
+
expect(st.opts[:after]).to eql [:after_callback] # TODO fix this bad code coupling
|
92
|
+
expect(st.opts[:success]).to eql [:after_persist] # TODO fix this bad code coupling
|
93
|
+
end
|
94
|
+
|
95
|
+
it 'should pass equality check if from and to are the same' do
|
96
|
+
opts = {:from => 'foo', :to => 'bar', :guard => 'g'}
|
97
|
+
st = AASM::Core::Transition.new(event, opts)
|
98
|
+
|
99
|
+
obj = double('object')
|
100
|
+
allow(obj).to receive(:from).and_return(opts[:from])
|
101
|
+
allow(obj).to receive(:to).and_return(opts[:to])
|
102
|
+
|
103
|
+
expect(st).to eq(obj)
|
104
|
+
end
|
105
|
+
|
106
|
+
it 'should fail equality check if from are not the same' do
|
107
|
+
opts = {:from => 'foo', :to => 'bar', :guard => 'g'}
|
108
|
+
st = AASM::Core::Transition.new(event, opts)
|
109
|
+
|
110
|
+
obj = double('object')
|
111
|
+
allow(obj).to receive(:from).and_return('blah')
|
112
|
+
allow(obj).to receive(:to).and_return(opts[:to])
|
113
|
+
|
114
|
+
expect(st).not_to eq(obj)
|
115
|
+
end
|
116
|
+
|
117
|
+
it 'should fail equality check if to are not the same' do
|
118
|
+
opts = {:from => 'foo', :to => 'bar', :guard => 'g'}
|
119
|
+
st = AASM::Core::Transition.new(event, opts)
|
120
|
+
|
121
|
+
obj = double('object')
|
122
|
+
allow(obj).to receive(:from).and_return(opts[:from])
|
123
|
+
allow(obj).to receive(:to).and_return('blah')
|
124
|
+
|
125
|
+
expect(st).not_to eq(obj)
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
describe AASM::Core::Transition, '- when performing guard checks' do
|
130
|
+
let(:state_machine) { AASM::StateMachine.new(:name) }
|
131
|
+
let(:event) { AASM::Core::Event.new(:event, state_machine) }
|
132
|
+
|
133
|
+
it 'should return true of there is no guard' do
|
134
|
+
opts = {:from => 'foo', :to => 'bar'}
|
135
|
+
st = AASM::Core::Transition.new(event, opts)
|
136
|
+
|
137
|
+
expect(st.allowed?(nil)).to be_truthy
|
138
|
+
end
|
139
|
+
|
140
|
+
it 'should call the method on the object if guard is a symbol' do
|
141
|
+
opts = {:from => 'foo', :to => 'bar', :guard => :test}
|
142
|
+
st = AASM::Core::Transition.new(event, opts)
|
143
|
+
|
144
|
+
obj = double('object')
|
145
|
+
expect(obj).to receive(:test)
|
146
|
+
|
147
|
+
expect(st.allowed?(obj)).to be false
|
148
|
+
end
|
149
|
+
|
150
|
+
it 'should add the name of the failed method calls to the failures instance var' do
|
151
|
+
opts = {:from => 'foo', :to => 'bar', :guard => :test}
|
152
|
+
st = AASM::Core::Transition.new(event, opts)
|
153
|
+
|
154
|
+
obj = double('object')
|
155
|
+
expect(obj).to receive(:test)
|
156
|
+
|
157
|
+
st.allowed?(obj)
|
158
|
+
expect(st.failures).to eq [:test]
|
159
|
+
end
|
160
|
+
|
161
|
+
it 'should call the method on the object if unless is a symbol' do
|
162
|
+
opts = {:from => 'foo', :to => 'bar', :unless => :test}
|
163
|
+
st = AASM::Core::Transition.new(event, opts)
|
164
|
+
|
165
|
+
obj = double('object')
|
166
|
+
expect(obj).to receive(:test)
|
167
|
+
|
168
|
+
expect(st.allowed?(obj)).to be true
|
169
|
+
end
|
170
|
+
|
171
|
+
it 'should call the method on the object if guard is a string' do
|
172
|
+
opts = {:from => 'foo', :to => 'bar', :guard => 'test'}
|
173
|
+
st = AASM::Core::Transition.new(event, opts)
|
174
|
+
|
175
|
+
obj = double('object')
|
176
|
+
expect(obj).to receive(:test)
|
177
|
+
|
178
|
+
expect(st.allowed?(obj)).to be false
|
179
|
+
end
|
180
|
+
|
181
|
+
it 'should call the method on the object if unless is a string' do
|
182
|
+
opts = {:from => 'foo', :to => 'bar', :unless => 'test'}
|
183
|
+
st = AASM::Core::Transition.new(event, opts)
|
184
|
+
|
185
|
+
obj = double('object')
|
186
|
+
expect(obj).to receive(:test)
|
187
|
+
|
188
|
+
expect(st.allowed?(obj)).to be true
|
189
|
+
end
|
190
|
+
|
191
|
+
it 'should call the proc passing the object if the guard is a proc' do
|
192
|
+
opts = {:from => 'foo', :to => 'bar', :guard => Proc.new { test }}
|
193
|
+
st = AASM::Core::Transition.new(event, opts)
|
194
|
+
|
195
|
+
obj = double('object')
|
196
|
+
expect(obj).to receive(:test)
|
197
|
+
|
198
|
+
expect(st.allowed?(obj)).to be false
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
describe AASM::Core::Transition, '- when executing the transition with a Proc' do
|
203
|
+
let(:state_machine) { AASM::StateMachine.new(:name) }
|
204
|
+
let(:event) { AASM::Core::Event.new(:event, state_machine) }
|
205
|
+
|
206
|
+
it 'should call a Proc on the object with args' do
|
207
|
+
opts = {:from => 'foo', :to => 'bar', :after => Proc.new {|a| test(a) }}
|
208
|
+
st = AASM::Core::Transition.new(event, opts)
|
209
|
+
args = {:arg1 => '1', :arg2 => '2'}
|
210
|
+
obj = double('object', :aasm => 'aasm')
|
211
|
+
|
212
|
+
expect(obj).to receive(:test).with(args)
|
213
|
+
|
214
|
+
st.execute(obj, args)
|
215
|
+
end
|
216
|
+
|
217
|
+
it 'should call a Proc on the object without args' do
|
218
|
+
# in order to test that the Proc has been called, we make sure
|
219
|
+
# that after running the :after callback the prc_object is set
|
220
|
+
prc_object = nil
|
221
|
+
prc = Proc.new { prc_object = self }
|
222
|
+
|
223
|
+
opts = {:from => 'foo', :to => 'bar', :after => prc }
|
224
|
+
st = AASM::Core::Transition.new(event, opts)
|
225
|
+
args = {:arg1 => '1', :arg2 => '2'}
|
226
|
+
obj = double('object', :aasm => 'aasm')
|
227
|
+
|
228
|
+
st.execute(obj, args)
|
229
|
+
expect(prc_object).to eql obj
|
230
|
+
end
|
231
|
+
end
|
232
|
+
|
233
|
+
describe AASM::Core::Transition, '- when executing the transition with an :after method call' do
|
234
|
+
let(:state_machine) { AASM::StateMachine.new(:name) }
|
235
|
+
let(:event) { AASM::Core::Event.new(:event, state_machine) }
|
236
|
+
|
237
|
+
it 'should accept a String for the method name' do
|
238
|
+
opts = {:from => 'foo', :to => 'bar', :after => 'test'}
|
239
|
+
st = AASM::Core::Transition.new(event, opts)
|
240
|
+
args = {:arg1 => '1', :arg2 => '2'}
|
241
|
+
obj = double('object', :aasm => 'aasm')
|
242
|
+
|
243
|
+
expect(obj).to receive(:test)
|
244
|
+
|
245
|
+
st.execute(obj, args)
|
246
|
+
end
|
247
|
+
|
248
|
+
it 'should accept a Symbol for the method name' do
|
249
|
+
opts = {:from => 'foo', :to => 'bar', :after => :test}
|
250
|
+
st = AASM::Core::Transition.new(event, opts)
|
251
|
+
args = {:arg1 => '1', :arg2 => '2'}
|
252
|
+
obj = double('object', :aasm => 'aasm')
|
253
|
+
|
254
|
+
expect(obj).to receive(:test)
|
255
|
+
|
256
|
+
st.execute(obj, args)
|
257
|
+
end
|
258
|
+
|
259
|
+
it 'should pass args if the target method accepts them' do
|
260
|
+
opts = {:from => 'foo', :to => 'bar', :after => :test}
|
261
|
+
st = AASM::Core::Transition.new(event, opts)
|
262
|
+
args = {:arg1 => '1', :arg2 => '2'}
|
263
|
+
obj = double('object', :aasm => 'aasm')
|
264
|
+
|
265
|
+
def obj.test(args)
|
266
|
+
"arg1: #{args[:arg1]} arg2: #{args[:arg2]}"
|
267
|
+
end
|
268
|
+
|
269
|
+
return_value = st.execute(obj, args)
|
270
|
+
|
271
|
+
expect(return_value).to eq('arg1: 1 arg2: 2')
|
272
|
+
end
|
273
|
+
|
274
|
+
it 'should NOT pass args if the target method does NOT accept them' do
|
275
|
+
opts = {:from => 'foo', :to => 'bar', :after => :test}
|
276
|
+
st = AASM::Core::Transition.new(event, opts)
|
277
|
+
args = {:arg1 => '1', :arg2 => '2'}
|
278
|
+
obj = double('object', :aasm => 'aasm')
|
279
|
+
|
280
|
+
def obj.test
|
281
|
+
'success'
|
282
|
+
end
|
283
|
+
|
284
|
+
return_value = st.execute(obj, args)
|
285
|
+
|
286
|
+
expect(return_value).to eq('success')
|
287
|
+
end
|
288
|
+
|
289
|
+
it 'should allow accessing the from_state and the to_state' do
|
290
|
+
opts = {:from => 'foo', :to => 'bar', :after => :test}
|
291
|
+
transition = AASM::Core::Transition.new(event, opts)
|
292
|
+
args = {:arg1 => '1', :arg2 => '2'}
|
293
|
+
obj = double('object', :aasm => AASM::InstanceBase.new('object'))
|
294
|
+
|
295
|
+
def obj.test(args)
|
296
|
+
"from: #{aasm.from_state} to: #{aasm.to_state}"
|
297
|
+
end
|
298
|
+
|
299
|
+
return_value = transition.execute(obj, args)
|
300
|
+
|
301
|
+
expect(return_value).to eq('from: foo to: bar')
|
302
|
+
end
|
303
|
+
|
304
|
+
end
|
305
|
+
|
306
|
+
describe AASM::Core::Transition, '- when executing the transition with a Class' do
|
307
|
+
let(:state_machine) { AASM::StateMachine.new(:name) }
|
308
|
+
let(:event) { AASM::Core::Event.new(:event, state_machine) }
|
309
|
+
|
310
|
+
class AfterTransitionClass
|
311
|
+
def initialize(record)
|
312
|
+
@record = record
|
313
|
+
end
|
314
|
+
|
315
|
+
def call
|
316
|
+
"from: #{@record.aasm.from_state} to: #{@record.aasm.to_state}"
|
317
|
+
end
|
318
|
+
end
|
319
|
+
|
320
|
+
class AfterTransitionClassWithArgs
|
321
|
+
def initialize(record, args)
|
322
|
+
@record = record
|
323
|
+
@args = args
|
324
|
+
end
|
325
|
+
|
326
|
+
def call
|
327
|
+
"arg1: #{@args[:arg1]}, arg2: #{@args[:arg2]}"
|
328
|
+
end
|
329
|
+
end
|
330
|
+
|
331
|
+
class AfterTransitionClassWithoutArgs
|
332
|
+
def call
|
333
|
+
'success'
|
334
|
+
end
|
335
|
+
end
|
336
|
+
|
337
|
+
it 'passes the record to the initialize method on the class to give access to the from_state and to_state' do
|
338
|
+
opts = {:from => 'foo', :to => 'bar', :after => AfterTransitionClass}
|
339
|
+
transition = AASM::Core::Transition.new(event, opts)
|
340
|
+
obj = double('object', :aasm => AASM::InstanceBase.new('object'))
|
341
|
+
|
342
|
+
return_value = transition.execute(obj)
|
343
|
+
|
344
|
+
expect(return_value).to eq('from: foo to: bar')
|
345
|
+
end
|
346
|
+
|
347
|
+
it 'should pass args to the initialize method on the class if it accepts them' do
|
348
|
+
opts = {:from => 'foo', :to => 'bar', :after => AfterTransitionClassWithArgs}
|
349
|
+
st = AASM::Core::Transition.new(event, opts)
|
350
|
+
args = {:arg1 => '1', :arg2 => '2'}
|
351
|
+
obj = double('object', :aasm => 'aasm')
|
352
|
+
|
353
|
+
return_value = st.execute(obj, args)
|
354
|
+
|
355
|
+
expect(return_value).to eq('arg1: 1, arg2: 2')
|
356
|
+
end
|
357
|
+
|
358
|
+
it 'should NOT pass args if the call method of the class if it does NOT accept them' do
|
359
|
+
opts = {:from => 'foo', :to => 'bar', :after => AfterTransitionClassWithoutArgs}
|
360
|
+
st = AASM::Core::Transition.new(event, opts)
|
361
|
+
obj = double('object', :aasm => 'aasm')
|
362
|
+
|
363
|
+
return_value = st.execute(obj)
|
364
|
+
|
365
|
+
expect(return_value).to eq('success')
|
366
|
+
end
|
367
|
+
end
|
368
|
+
|
369
|
+
describe AASM::Core::Transition, '- when invoking the transition :success method call' do
|
370
|
+
let(:state_machine) { AASM::StateMachine.new(:name) }
|
371
|
+
let(:event) { AASM::Core::Event.new(:event, state_machine) }
|
372
|
+
|
373
|
+
it 'should accept a String for the method name' do
|
374
|
+
opts = {:from => 'foo', :to => 'bar', :success => 'test'}
|
375
|
+
st = AASM::Core::Transition.new(event, opts)
|
376
|
+
args = {:arg1 => '1', :arg2 => '2'}
|
377
|
+
obj = double('object', :aasm => 'aasm')
|
378
|
+
|
379
|
+
expect(obj).to receive(:test)
|
380
|
+
|
381
|
+
st.invoke_success_callbacks(obj, args)
|
382
|
+
end
|
383
|
+
|
384
|
+
it 'should accept a Symbol for the method name' do
|
385
|
+
opts = {:from => 'foo', :to => 'bar', :success => :test}
|
386
|
+
st = AASM::Core::Transition.new(event, opts)
|
387
|
+
args = {:arg1 => '1', :arg2 => '2'}
|
388
|
+
obj = double('object', :aasm => 'aasm')
|
389
|
+
|
390
|
+
expect(obj).to receive(:test)
|
391
|
+
|
392
|
+
st.invoke_success_callbacks(obj, args)
|
393
|
+
end
|
394
|
+
|
395
|
+
it 'should accept a Array for the method name' do
|
396
|
+
opts = {:from => 'foo', :to => 'bar', :success => [:test1, :test2]}
|
397
|
+
st = AASM::Core::Transition.new(event, opts)
|
398
|
+
args = {:arg1 => '1', :arg2 => '2'}
|
399
|
+
obj = double('object', :aasm => 'aasm')
|
400
|
+
|
401
|
+
expect(obj).to receive(:test1)
|
402
|
+
expect(obj).to receive(:test2)
|
403
|
+
|
404
|
+
st.invoke_success_callbacks(obj, args)
|
405
|
+
end
|
406
|
+
|
407
|
+
it 'should pass args if the target method accepts them' do
|
408
|
+
opts = {:from => 'foo', :to => 'bar', :success => :test}
|
409
|
+
st = AASM::Core::Transition.new(event, opts)
|
410
|
+
args = {:arg1 => '1', :arg2 => '2'}
|
411
|
+
obj = double('object', :aasm => 'aasm')
|
412
|
+
|
413
|
+
def obj.test(args)
|
414
|
+
"arg1: #{args[:arg1]} arg2: #{args[:arg2]}"
|
415
|
+
end
|
416
|
+
|
417
|
+
return_value = st.invoke_success_callbacks(obj, args)
|
418
|
+
|
419
|
+
expect(return_value).to eq('arg1: 1 arg2: 2')
|
420
|
+
end
|
421
|
+
|
422
|
+
it 'should NOT pass args if the target method does NOT accept them' do
|
423
|
+
opts = {:from => 'foo', :to => 'bar', :success => :test}
|
424
|
+
st = AASM::Core::Transition.new(event, opts)
|
425
|
+
args = {:arg1 => '1', :arg2 => '2'}
|
426
|
+
obj = double('object', :aasm => 'aasm')
|
427
|
+
|
428
|
+
def obj.test
|
429
|
+
'success'
|
430
|
+
end
|
431
|
+
|
432
|
+
return_value = st.invoke_success_callbacks(obj, args)
|
433
|
+
|
434
|
+
expect(return_value).to eq('success')
|
435
|
+
end
|
436
|
+
end
|