aasm 4.5.1 → 5.5.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.
Files changed (186) hide show
  1. checksums.yaml +5 -5
  2. data/LICENSE +1 -1
  3. data/README.md +809 -129
  4. data/lib/aasm/aasm.rb +74 -37
  5. data/lib/aasm/base.rb +188 -41
  6. data/lib/aasm/configuration.rb +27 -2
  7. data/lib/aasm/core/event.rb +75 -47
  8. data/lib/aasm/core/invoker.rb +129 -0
  9. data/lib/aasm/core/invokers/base_invoker.rb +75 -0
  10. data/lib/aasm/core/invokers/class_invoker.rb +52 -0
  11. data/lib/aasm/core/invokers/literal_invoker.rb +49 -0
  12. data/lib/aasm/core/invokers/proc_invoker.rb +59 -0
  13. data/lib/aasm/core/state.rb +22 -13
  14. data/lib/aasm/core/transition.rb +30 -23
  15. data/lib/aasm/dsl_helper.rb +24 -22
  16. data/lib/aasm/errors.rb +8 -5
  17. data/lib/aasm/instance_base.rb +63 -15
  18. data/lib/aasm/localizer.rb +13 -3
  19. data/lib/aasm/minitest/allow_event.rb +13 -0
  20. data/lib/aasm/minitest/allow_transition_to.rb +13 -0
  21. data/lib/aasm/minitest/have_state.rb +13 -0
  22. data/lib/aasm/minitest/transition_from.rb +21 -0
  23. data/lib/aasm/minitest.rb +5 -0
  24. data/lib/aasm/minitest_spec.rb +15 -0
  25. data/lib/aasm/persistence/active_record_persistence.rb +87 -79
  26. data/lib/aasm/persistence/base.rb +30 -30
  27. data/lib/aasm/persistence/core_data_query_persistence.rb +94 -0
  28. data/lib/aasm/persistence/dynamoid_persistence.rb +92 -0
  29. data/lib/aasm/persistence/mongoid_persistence.rb +49 -35
  30. data/lib/aasm/persistence/no_brainer_persistence.rb +105 -0
  31. data/lib/aasm/persistence/orm.rb +154 -0
  32. data/lib/aasm/persistence/plain_persistence.rb +2 -1
  33. data/lib/aasm/persistence/redis_persistence.rb +112 -0
  34. data/lib/aasm/persistence/sequel_persistence.rb +37 -67
  35. data/lib/aasm/persistence.rb +20 -5
  36. data/lib/aasm/rspec/allow_event.rb +5 -1
  37. data/lib/aasm/rspec/allow_transition_to.rb +5 -1
  38. data/lib/aasm/rspec/transition_from.rb +8 -4
  39. data/lib/aasm/state_machine.rb +6 -12
  40. data/lib/aasm/state_machine_store.rb +76 -0
  41. data/lib/aasm/version.rb +1 -1
  42. data/lib/aasm.rb +8 -2
  43. data/lib/generators/aasm/aasm_generator.rb +16 -0
  44. data/lib/generators/aasm/orm_helpers.rb +41 -0
  45. data/lib/generators/active_record/aasm_generator.rb +40 -0
  46. data/lib/generators/active_record/templates/migration.rb +8 -0
  47. data/lib/generators/active_record/templates/migration_existing.rb +5 -0
  48. data/lib/generators/mongoid/aasm_generator.rb +28 -0
  49. data/lib/generators/nobrainer/aasm_generator.rb +28 -0
  50. data/lib/motion-aasm.rb +37 -0
  51. metadata +104 -259
  52. data/.document +0 -6
  53. data/.gitignore +0 -19
  54. data/.travis.yml +0 -37
  55. data/API +0 -34
  56. data/CHANGELOG.md +0 -272
  57. data/CODE_OF_CONDUCT.md +0 -13
  58. data/Gemfile +0 -15
  59. data/HOWTO +0 -12
  60. data/PLANNED_CHANGES.md +0 -11
  61. data/README_FROM_VERSION_3_TO_4.md +0 -240
  62. data/Rakefile +0 -26
  63. data/aasm.gemspec +0 -31
  64. data/callbacks.txt +0 -51
  65. data/gemfiles/rails_3.2.gemfile +0 -14
  66. data/gemfiles/rails_4.0.gemfile +0 -12
  67. data/gemfiles/rails_4.0_mongo_mapper.gemfile +0 -14
  68. data/gemfiles/rails_4.1.gemfile +0 -12
  69. data/gemfiles/rails_4.1_mongo_mapper.gemfile +0 -14
  70. data/gemfiles/rails_4.2.gemfile +0 -12
  71. data/gemfiles/rails_4.2_mongo_mapper.gemfile +0 -14
  72. data/gemfiles/rails_4.2_mongoid_5.gemfile +0 -12
  73. data/lib/aasm/persistence/mongo_mapper_persistence.rb +0 -157
  74. data/spec/database.rb +0 -63
  75. data/spec/database.yml +0 -3
  76. data/spec/en.yml +0 -9
  77. data/spec/en_deprecated_style.yml +0 -10
  78. data/spec/models/active_record/basic_active_record_two_state_machines_example.rb +0 -25
  79. data/spec/models/active_record/complex_active_record_example.rb +0 -33
  80. data/spec/models/active_record/derivate_new_dsl.rb +0 -7
  81. data/spec/models/active_record/false_state.rb +0 -35
  82. data/spec/models/active_record/gate.rb +0 -39
  83. data/spec/models/active_record/localizer_test_model.rb +0 -34
  84. data/spec/models/active_record/no_direct_assignment.rb +0 -21
  85. data/spec/models/active_record/no_scope.rb +0 -21
  86. data/spec/models/active_record/persisted_state.rb +0 -12
  87. data/spec/models/active_record/provided_and_persisted_state.rb +0 -24
  88. data/spec/models/active_record/reader.rb +0 -7
  89. data/spec/models/active_record/readme_job.rb +0 -21
  90. data/spec/models/active_record/simple_new_dsl.rb +0 -17
  91. data/spec/models/active_record/thief.rb +0 -29
  92. data/spec/models/active_record/transient.rb +0 -6
  93. data/spec/models/active_record/with_enum.rb +0 -39
  94. data/spec/models/active_record/with_false_enum.rb +0 -31
  95. data/spec/models/active_record/with_true_enum.rb +0 -39
  96. data/spec/models/active_record/writer.rb +0 -6
  97. data/spec/models/basic_two_state_machines_example.rb +0 -25
  98. data/spec/models/callbacks/basic.rb +0 -78
  99. data/spec/models/callbacks/basic_multiple.rb +0 -75
  100. data/spec/models/callbacks/guard_within_block.rb +0 -66
  101. data/spec/models/callbacks/guard_within_block_multiple.rb +0 -66
  102. data/spec/models/callbacks/multiple_transitions_transition_guard.rb +0 -65
  103. data/spec/models/callbacks/multiple_transitions_transition_guard_multiple.rb +0 -65
  104. data/spec/models/callbacks/private_method.rb +0 -44
  105. data/spec/models/callbacks/private_method_multiple.rb +0 -44
  106. data/spec/models/callbacks/with_args.rb +0 -61
  107. data/spec/models/callbacks/with_args_multiple.rb +0 -61
  108. data/spec/models/callbacks/with_state_arg.rb +0 -26
  109. data/spec/models/callbacks/with_state_arg_multiple.rb +0 -26
  110. data/spec/models/complex_example.rb +0 -222
  111. data/spec/models/conversation.rb +0 -93
  112. data/spec/models/default_state.rb +0 -12
  113. data/spec/models/double_definer.rb +0 -21
  114. data/spec/models/foo.rb +0 -92
  115. data/spec/models/foo_callback_multiple.rb +0 -45
  116. data/spec/models/guardian.rb +0 -48
  117. data/spec/models/guardian_multiple.rb +0 -48
  118. data/spec/models/initial_state_proc.rb +0 -31
  119. data/spec/models/invalid_persistor.rb +0 -31
  120. data/spec/models/mongo_mapper/complex_mongo_mapper_example.rb +0 -37
  121. data/spec/models/mongo_mapper/no_scope_mongo_mapper.rb +0 -21
  122. data/spec/models/mongo_mapper/simple_mongo_mapper.rb +0 -23
  123. data/spec/models/mongo_mapper/simple_new_dsl_mongo_mapper.rb +0 -25
  124. data/spec/models/mongoid/complex_mongoid_example.rb +0 -37
  125. data/spec/models/mongoid/no_scope_mongoid.rb +0 -21
  126. data/spec/models/mongoid/simple_mongoid.rb +0 -23
  127. data/spec/models/mongoid/simple_new_dsl_mongoid.rb +0 -25
  128. data/spec/models/no_initial_state.rb +0 -25
  129. data/spec/models/not_auto_loaded/process.rb +0 -21
  130. data/spec/models/parametrised_event.rb +0 -29
  131. data/spec/models/parametrised_event_multiple.rb +0 -29
  132. data/spec/models/process_with_new_dsl.rb +0 -31
  133. data/spec/models/provided_state.rb +0 -24
  134. data/spec/models/sequel/complex_sequel_example.rb +0 -45
  135. data/spec/models/sequel/sequel_multiple.rb +0 -25
  136. data/spec/models/sequel/sequel_simple.rb +0 -25
  137. data/spec/models/silencer.rb +0 -27
  138. data/spec/models/simple_example.rb +0 -15
  139. data/spec/models/simple_multiple_example.rb +0 -30
  140. data/spec/models/state_machine_with_failed_event.rb +0 -12
  141. data/spec/models/sub_class.rb +0 -7
  142. data/spec/models/sub_class_with_more_states.rb +0 -18
  143. data/spec/models/sub_classing.rb +0 -3
  144. data/spec/models/super_class.rb +0 -46
  145. data/spec/models/this_name_better_not_be_in_use.rb +0 -11
  146. data/spec/models/transactor.rb +0 -53
  147. data/spec/models/valid_state_name.rb +0 -23
  148. data/spec/models/validator.rb +0 -79
  149. data/spec/models/worker.rb +0 -2
  150. data/spec/spec_helper.rb +0 -25
  151. data/spec/unit/api_spec.rb +0 -77
  152. data/spec/unit/basic_two_state_machines_example_spec.rb +0 -10
  153. data/spec/unit/callback_multiple_spec.rb +0 -295
  154. data/spec/unit/callbacks_spec.rb +0 -296
  155. data/spec/unit/complex_example_spec.rb +0 -84
  156. data/spec/unit/complex_multiple_example_spec.rb +0 -99
  157. data/spec/unit/edge_cases_spec.rb +0 -16
  158. data/spec/unit/event_multiple_spec.rb +0 -73
  159. data/spec/unit/event_naming_spec.rb +0 -11
  160. data/spec/unit/event_spec.rb +0 -322
  161. data/spec/unit/guard_multiple_spec.rb +0 -60
  162. data/spec/unit/guard_spec.rb +0 -60
  163. data/spec/unit/initial_state_multiple_spec.rb +0 -15
  164. data/spec/unit/initial_state_spec.rb +0 -12
  165. data/spec/unit/inspection_multiple_spec.rb +0 -201
  166. data/spec/unit/inspection_spec.rb +0 -111
  167. data/spec/unit/localizer_spec.rb +0 -76
  168. data/spec/unit/memory_leak_spec.rb +0 -38
  169. data/spec/unit/new_dsl_spec.rb +0 -12
  170. data/spec/unit/persistence/active_record_persistence_multiple_spec.rb +0 -573
  171. data/spec/unit/persistence/active_record_persistence_spec.rb +0 -552
  172. data/spec/unit/persistence/mongo_mapper_persistence_multiple_spec.rb +0 -146
  173. data/spec/unit/persistence/mongo_mapper_persistence_spec.rb +0 -93
  174. data/spec/unit/persistence/mongoid_persistence_multiple_spec.rb +0 -127
  175. data/spec/unit/persistence/mongoid_persistence_spec.rb +0 -79
  176. data/spec/unit/persistence/sequel_persistence_multiple_spec.rb +0 -153
  177. data/spec/unit/persistence/sequel_persistence_spec.rb +0 -100
  178. data/spec/unit/readme_spec.rb +0 -42
  179. data/spec/unit/reloading_spec.rb +0 -15
  180. data/spec/unit/rspec_matcher_spec.rb +0 -79
  181. data/spec/unit/simple_example_spec.rb +0 -42
  182. data/spec/unit/simple_multiple_example_spec.rb +0 -63
  183. data/spec/unit/state_spec.rb +0 -89
  184. data/spec/unit/subclassing_multiple_spec.rb +0 -39
  185. data/spec/unit/subclassing_spec.rb +0 -31
  186. data/spec/unit/transition_spec.rb +0 -291
@@ -1,42 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe 'state machine' do
4
- let(:simple) { SimpleExample.new }
5
-
6
- it 'starts with an initial state' do
7
- expect(simple.aasm.current_state).to eq(:initialised)
8
- expect(simple).to respond_to(:initialised?)
9
- expect(simple).to be_initialised
10
- end
11
-
12
- it 'allows transitions to other states' do
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
24
- end
25
-
26
- it 'denies transitions to other states' do
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)
35
- end
36
-
37
- it 'defines constants for each state name' do
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)
41
- end
42
- end
@@ -1,63 +0,0 @@
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
@@ -1,89 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe AASM::Core::State do
4
- let(:state_machine) { AASM::StateMachine.new(:name) }
5
-
6
- before(:each) do
7
- @name = :astate
8
- @options = { :crazy_custom_key => 'key' }
9
- end
10
-
11
- def new_state(options={})
12
- AASM::Core::State.new(@name, Conversation, state_machine, @options.merge(options))
13
- end
14
-
15
- it 'should set the name' do
16
- state = new_state
17
- expect(state.name).to eq(:astate)
18
- end
19
-
20
- it 'should set the display_name from name' do
21
- expect(new_state.display_name).to eq('Astate')
22
- end
23
-
24
- it 'should set the display_name from options' do
25
- expect(new_state(:display => "A State").display_name).to eq('A State')
26
- end
27
-
28
- it 'should set the options and expose them as options' do
29
- expect(new_state.options).to eq(@options)
30
- end
31
-
32
- it 'should be equal to a symbol of the same name' do
33
- expect(new_state).to eq(:astate)
34
- end
35
-
36
- it 'should be equal to a State of the same name' do
37
- expect(new_state).to eq(new_state)
38
- end
39
-
40
- it 'should send a message to the record for an action if the action is present as a symbol' do
41
- state = new_state(:entering => :foo)
42
-
43
- record = double('record')
44
- expect(record).to receive(:foo)
45
-
46
- state.fire_callbacks(:entering, record)
47
- end
48
-
49
- it 'should send a message to the record for an action if the action is present as a string' do
50
- state = new_state(:entering => 'foo')
51
-
52
- record = double('record')
53
- expect(record).to receive(:foo)
54
-
55
- state.fire_callbacks(:entering, record)
56
- end
57
-
58
- it 'should send a message to the record for each action' do
59
- state = new_state(:entering => [:a, :b, "c", lambda {|r| r.foobar }])
60
-
61
- record = double('record')
62
- expect(record).to receive(:a)
63
- expect(record).to receive(:b)
64
- expect(record).to receive(:c)
65
- expect(record).to receive(:foobar)
66
-
67
- state.fire_callbacks(:entering, record)
68
- end
69
-
70
- it "should stop calling actions if one of them raises :halt_aasm_chain" do
71
- state = new_state(:entering => [:a, :b, :c])
72
-
73
- record = double('record')
74
- expect(record).to receive(:a)
75
- expect(record).to receive(:b).and_throw(:halt_aasm_chain)
76
- expect(record).not_to receive(:c)
77
-
78
- state.fire_callbacks(:entering, record)
79
- end
80
-
81
- it 'should call a proc, passing in the record for an action if the action is present' do
82
- state = new_state(:entering => Proc.new {|r| r.foobar})
83
-
84
- record = double('record')
85
- expect(record).to receive(:foobar)
86
-
87
- state.fire_callbacks(:entering, record)
88
- end
89
- end
@@ -1,39 +0,0 @@
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,31 +0,0 @@
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
- end
31
-
@@ -1,291 +0,0 @@
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 and guard 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
- end
88
-
89
- expect(st.opts[:guard]).to eql ['g', :gg]
90
- expect(st.opts[:after]).to eql [:after_callback] # TODO fix this bad code coupling
91
- end
92
-
93
- it 'should pass equality check if from and to are the same' do
94
- opts = {:from => 'foo', :to => 'bar', :guard => 'g'}
95
- st = AASM::Core::Transition.new(event, opts)
96
-
97
- obj = double('object')
98
- allow(obj).to receive(:from).and_return(opts[:from])
99
- allow(obj).to receive(:to).and_return(opts[:to])
100
-
101
- expect(st).to eq(obj)
102
- end
103
-
104
- it 'should fail equality check if from are not the same' do
105
- opts = {:from => 'foo', :to => 'bar', :guard => 'g'}
106
- st = AASM::Core::Transition.new(event, opts)
107
-
108
- obj = double('object')
109
- allow(obj).to receive(:from).and_return('blah')
110
- allow(obj).to receive(:to).and_return(opts[:to])
111
-
112
- expect(st).not_to eq(obj)
113
- end
114
-
115
- it 'should fail equality check if to are not the same' do
116
- opts = {:from => 'foo', :to => 'bar', :guard => 'g'}
117
- st = AASM::Core::Transition.new(event, opts)
118
-
119
- obj = double('object')
120
- allow(obj).to receive(:from).and_return(opts[:from])
121
- allow(obj).to receive(:to).and_return('blah')
122
-
123
- expect(st).not_to eq(obj)
124
- end
125
- end
126
-
127
- describe AASM::Core::Transition, '- when performing guard checks' do
128
- let(:state_machine) { AASM::StateMachine.new(:name) }
129
- let(:event) { AASM::Core::Event.new(:event, state_machine) }
130
-
131
- it 'should return true of there is no guard' do
132
- opts = {:from => 'foo', :to => 'bar'}
133
- st = AASM::Core::Transition.new(event, opts)
134
-
135
- expect(st.allowed?(nil)).to be_truthy
136
- end
137
-
138
- it 'should call the method on the object if guard is a symbol' do
139
- opts = {:from => 'foo', :to => 'bar', :guard => :test}
140
- st = AASM::Core::Transition.new(event, opts)
141
-
142
- obj = double('object')
143
- expect(obj).to receive(:test)
144
-
145
- expect(st.allowed?(obj)).to be false
146
- end
147
-
148
- it 'should call the method on the object if unless is a symbol' do
149
- opts = {:from => 'foo', :to => 'bar', :unless => :test}
150
- st = AASM::Core::Transition.new(event, opts)
151
-
152
- obj = double('object')
153
- expect(obj).to receive(:test)
154
-
155
- expect(st.allowed?(obj)).to be true
156
- end
157
-
158
- it 'should call the method on the object if guard is a string' do
159
- opts = {:from => 'foo', :to => 'bar', :guard => 'test'}
160
- st = AASM::Core::Transition.new(event, opts)
161
-
162
- obj = double('object')
163
- expect(obj).to receive(:test)
164
-
165
- expect(st.allowed?(obj)).to be false
166
- end
167
-
168
- it 'should call the method on the object if unless is a string' do
169
- opts = {:from => 'foo', :to => 'bar', :unless => 'test'}
170
- st = AASM::Core::Transition.new(event, opts)
171
-
172
- obj = double('object')
173
- expect(obj).to receive(:test)
174
-
175
- expect(st.allowed?(obj)).to be true
176
- end
177
-
178
- it 'should call the proc passing the object if the guard is a proc' do
179
- opts = {:from => 'foo', :to => 'bar', :guard => Proc.new { test }}
180
- st = AASM::Core::Transition.new(event, opts)
181
-
182
- obj = double('object')
183
- expect(obj).to receive(:test)
184
-
185
- expect(st.allowed?(obj)).to be false
186
- end
187
- end
188
-
189
- describe AASM::Core::Transition, '- when executing the transition with a Proc' do
190
- let(:state_machine) { AASM::StateMachine.new(:name) }
191
- let(:event) { AASM::Core::Event.new(:event, state_machine) }
192
-
193
- it 'should call a Proc on the object with args' do
194
- opts = {:from => 'foo', :to => 'bar', :after => Proc.new {|a| test(a) }}
195
- st = AASM::Core::Transition.new(event, opts)
196
- args = {:arg1 => '1', :arg2 => '2'}
197
- obj = double('object', :aasm => 'aasm')
198
-
199
- expect(obj).to receive(:test).with(args)
200
-
201
- st.execute(obj, args)
202
- end
203
-
204
- it 'should call a Proc on the object without args' do
205
- # in order to test that the Proc has been called, we make sure
206
- # that after running the :after callback the prc_object is set
207
- prc_object = nil
208
- prc = Proc.new { prc_object = self }
209
-
210
- opts = {:from => 'foo', :to => 'bar', :after => prc }
211
- st = AASM::Core::Transition.new(event, opts)
212
- args = {:arg1 => '1', :arg2 => '2'}
213
- obj = double('object', :aasm => 'aasm')
214
-
215
- st.execute(obj, args)
216
- expect(prc_object).to eql obj
217
- end
218
- end
219
-
220
- describe AASM::Core::Transition, '- when executing the transition with an :after method call' do
221
- let(:state_machine) { AASM::StateMachine.new(:name) }
222
- let(:event) { AASM::Core::Event.new(:event, state_machine) }
223
-
224
- it 'should accept a String for the method name' do
225
- opts = {:from => 'foo', :to => 'bar', :after => 'test'}
226
- st = AASM::Core::Transition.new(event, opts)
227
- args = {:arg1 => '1', :arg2 => '2'}
228
- obj = double('object', :aasm => 'aasm')
229
-
230
- expect(obj).to receive(:test)
231
-
232
- st.execute(obj, args)
233
- end
234
-
235
- it 'should accept a Symbol for the method name' do
236
- opts = {:from => 'foo', :to => 'bar', :after => :test}
237
- st = AASM::Core::Transition.new(event, opts)
238
- args = {:arg1 => '1', :arg2 => '2'}
239
- obj = double('object', :aasm => 'aasm')
240
-
241
- expect(obj).to receive(:test)
242
-
243
- st.execute(obj, args)
244
- end
245
-
246
- it 'should pass args if the target method accepts them' do
247
- opts = {:from => 'foo', :to => 'bar', :after => :test}
248
- st = AASM::Core::Transition.new(event, opts)
249
- args = {:arg1 => '1', :arg2 => '2'}
250
- obj = double('object', :aasm => 'aasm')
251
-
252
- def obj.test(args)
253
- "arg1: #{args[:arg1]} arg2: #{args[:arg2]}"
254
- end
255
-
256
- return_value = st.execute(obj, args)
257
-
258
- expect(return_value).to eq('arg1: 1 arg2: 2')
259
- end
260
-
261
- it 'should NOT pass args if the target method does NOT accept them' do
262
- opts = {:from => 'foo', :to => 'bar', :after => :test}
263
- st = AASM::Core::Transition.new(event, opts)
264
- args = {:arg1 => '1', :arg2 => '2'}
265
- obj = double('object', :aasm => 'aasm')
266
-
267
- def obj.test
268
- 'success'
269
- end
270
-
271
- return_value = st.execute(obj, args)
272
-
273
- expect(return_value).to eq('success')
274
- end
275
-
276
- it 'should allow accessing the from_state and the to_state' do
277
- opts = {:from => 'foo', :to => 'bar', :after => :test}
278
- transition = AASM::Core::Transition.new(event, opts)
279
- args = {:arg1 => '1', :arg2 => '2'}
280
- obj = double('object', :aasm => AASM::InstanceBase.new('object'))
281
-
282
- def obj.test(args)
283
- "from: #{aasm.from_state} to: #{aasm.to_state}"
284
- end
285
-
286
- return_value = transition.execute(obj, args)
287
-
288
- expect(return_value).to eq('from: foo to: bar')
289
- end
290
-
291
- end