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,295 +0,0 @@
1
- require 'spec_helper'
2
- Dir[File.dirname(__FILE__) + "/../models/callbacks/*.rb"].sort.each { |f| require File.expand_path(f) }
3
-
4
- describe 'callbacks for the new DSL' do
5
-
6
- it "be called in order" do
7
- show_debug_log = false
8
-
9
- callback = Callbacks::BasicMultiple.new(:log => show_debug_log)
10
- callback.aasm(:left).current_state
11
-
12
- unless show_debug_log
13
- expect(callback).to receive(:before_event).once.ordered
14
- expect(callback).to receive(:event_guard).once.ordered.and_return(true)
15
- expect(callback).to receive(:transition_guard).once.ordered.and_return(true)
16
- expect(callback).to receive(:before_exit_open).once.ordered # these should be before the state changes
17
- expect(callback).to receive(:exit_open).once.ordered
18
- # expect(callback).to receive(:event_guard).once.ordered.and_return(true)
19
- # expect(callback).to receive(:transition_guard).once.ordered.and_return(true)
20
- expect(callback).to receive(:after_transition).once.ordered
21
- expect(callback).to receive(:before_enter_closed).once.ordered
22
- expect(callback).to receive(:enter_closed).once.ordered
23
- expect(callback).to receive(:aasm_write_state).with(:closed, :left).once.ordered.and_return(true) # this is when the state changes
24
- expect(callback).to receive(:after_exit_open).once.ordered # these should be after the state changes
25
- expect(callback).to receive(:after_enter_closed).once.ordered
26
- expect(callback).to receive(:after_event).once.ordered
27
- end
28
-
29
- # puts "------- close!"
30
- callback.left_close!
31
- end
32
-
33
- it "does not run any state callback if the event guard fails" do
34
- callback = Callbacks::BasicMultiple.new(:log => false)
35
- callback.aasm(:left).current_state
36
-
37
- expect(callback).to receive(:before_event).once.ordered
38
- expect(callback).to receive(:event_guard).once.ordered.and_return(false)
39
- expect(callback).to_not receive(:transition_guard)
40
- expect(callback).to_not receive(:before_exit_open)
41
- expect(callback).to_not receive(:exit_open)
42
- expect(callback).to_not receive(:after_transition)
43
- expect(callback).to_not receive(:before_enter_closed)
44
- expect(callback).to_not receive(:enter_closed)
45
- expect(callback).to_not receive(:aasm_write_state)
46
- expect(callback).to_not receive(:after_exit_open)
47
- expect(callback).to_not receive(:after_enter_closed)
48
- expect(callback).to_not receive(:after_event)
49
-
50
- expect {
51
- callback.left_close!
52
- }.to raise_error(AASM::InvalidTransition)
53
- end
54
-
55
- it "handles private callback methods as well" do
56
- show_debug_log = false
57
-
58
- callback = Callbacks::PrivateMethodMultiple.new(:log => show_debug_log)
59
- callback.aasm(:left).current_state
60
-
61
- # puts "------- close!"
62
- expect {
63
- callback.close!
64
- }.to_not raise_error
65
- end
66
-
67
- context "if the transition guard fails" do
68
- it "does not run any state callback if guard is defined inline" do
69
- show_debug_log = false
70
- callback = Callbacks::BasicMultiple.new(:log => show_debug_log, :fail_transition_guard => true)
71
- callback.aasm(:left).current_state
72
-
73
- unless show_debug_log
74
- expect(callback).to receive(:before_event).once.ordered
75
- expect(callback).to receive(:event_guard).once.ordered.and_return(true)
76
- expect(callback).to receive(:transition_guard).once.ordered.and_return(false)
77
- expect(callback).to_not receive(:before_exit_open)
78
- expect(callback).to_not receive(:exit_open)
79
- expect(callback).to_not receive(:after_transition)
80
- expect(callback).to_not receive(:before_enter_closed)
81
- expect(callback).to_not receive(:enter_closed)
82
- expect(callback).to_not receive(:aasm_write_state)
83
- expect(callback).to_not receive(:after_exit_open)
84
- expect(callback).to_not receive(:after_enter_closed)
85
- expect(callback).to_not receive(:after_event)
86
- end
87
-
88
- expect {
89
- callback.left_close!
90
- }.to raise_error(AASM::InvalidTransition)
91
- end
92
-
93
- it "does not run transition_guard twice for multiple permitted transitions" do
94
- show_debug_log = false
95
- callback = Callbacks::MultipleTransitionsTransitionGuardMultiple.new(:log => show_debug_log, :fail_transition_guard => true)
96
- callback.aasm(:left).current_state
97
-
98
- unless show_debug_log
99
- expect(callback).to receive(:before).once.ordered
100
- expect(callback).to receive(:event_guard).once.ordered.and_return(true)
101
- expect(callback).to receive(:transition_guard).once.ordered.and_return(false)
102
- expect(callback).to receive(:event_guard).once.ordered.and_return(true)
103
- expect(callback).to receive(:before_exit_open).once.ordered
104
- expect(callback).to receive(:exit_open).once.ordered
105
- expect(callback).to receive(:aasm_write_state).once.ordered.and_return(true) # this is when the state changes
106
- expect(callback).to receive(:after_exit_open).once.ordered
107
- expect(callback).to receive(:after).once.ordered
108
-
109
- expect(callback).to_not receive(:transitioning)
110
- expect(callback).to_not receive(:before_enter_closed)
111
- expect(callback).to_not receive(:enter_closed)
112
- expect(callback).to_not receive(:after_enter_closed)
113
- end
114
-
115
- callback.close!
116
- expect(callback.aasm(:left).current_state).to eql :failed
117
- end
118
-
119
- it "does not run any state callback if guard is defined with block" do
120
- callback = Callbacks::GuardWithinBlockMultiple.new #(:log => true, :fail_transition_guard => true)
121
- callback.aasm(:left).current_state
122
-
123
- expect(callback).to receive(:before).once.ordered
124
- expect(callback).to receive(:event_guard).once.ordered.and_return(true)
125
- expect(callback).to receive(:transition_guard).once.ordered.and_return(false)
126
- expect(callback).to_not receive(:before_exit_open)
127
- expect(callback).to_not receive(:exit_open)
128
- expect(callback).to_not receive(:transitioning)
129
- expect(callback).to_not receive(:before_enter_closed)
130
- expect(callback).to_not receive(:enter_closed)
131
- expect(callback).to_not receive(:aasm_write_state)
132
- expect(callback).to_not receive(:after_exit_open)
133
- expect(callback).to_not receive(:after_enter_closed)
134
- expect(callback).to_not receive(:after)
135
-
136
- expect {
137
- callback.close!
138
- }.to raise_error(AASM::InvalidTransition)
139
- end
140
- end
141
-
142
- it "should properly pass arguments" do
143
- cb = Callbacks::WithArgsMultiple.new(:log => false)
144
- cb.aasm(:left).current_state
145
-
146
- cb.reset_data
147
- cb.close!(:arg1, :arg2)
148
- expect(cb.data).to eql 'before(:arg1,:arg2) before_exit_open(:arg1,:arg2) transition_proc(:arg1,:arg2) before_enter_closed(:arg1,:arg2) aasm_write_state after_exit_open(:arg1,:arg2) after_enter_closed(:arg1,:arg2) after(:arg1,:arg2)'
149
- end
150
-
151
- it "should call the callbacks given the to-state as argument" do
152
- cb = Callbacks::WithStateArgMultiple.new
153
- expect(cb).to receive(:before_method).with(:arg1).once.ordered
154
- expect(cb).to receive(:transition_method).never
155
- expect(cb).to receive(:transition_method2).with(:arg1).once.ordered
156
- expect(cb).to receive(:after_method).with(:arg1).once.ordered
157
- cb.close!(:out_to_lunch, :arg1)
158
-
159
- cb = Callbacks::WithStateArgMultiple.new
160
- some_object = double('some object')
161
- expect(cb).to receive(:before_method).with(some_object).once.ordered
162
- expect(cb).to receive(:transition_method2).with(some_object).once.ordered
163
- expect(cb).to receive(:after_method).with(some_object).once.ordered
164
- cb.close!(:out_to_lunch, some_object)
165
- end
166
-
167
- it "should call the proper methods just with arguments" do
168
- cb = Callbacks::WithStateArgMultiple.new
169
- expect(cb).to receive(:before_method).with(:arg1).once.ordered
170
- expect(cb).to receive(:transition_method).with(:arg1).once.ordered
171
- expect(cb).to receive(:transition_method).never
172
- expect(cb).to receive(:after_method).with(:arg1).once.ordered
173
- cb.close!(:arg1)
174
-
175
- cb = Callbacks::WithStateArgMultiple.new
176
- some_object = double('some object')
177
- expect(cb).to receive(:before_method).with(some_object).once.ordered
178
- expect(cb).to receive(:transition_method).with(some_object).once.ordered
179
- expect(cb).to receive(:transition_method).never
180
- expect(cb).to receive(:after_method).with(some_object).once.ordered
181
- cb.close!(some_object)
182
- end
183
- end # callbacks for the new DSL
184
-
185
- describe 'event callbacks' do
186
- describe "with an error callback defined" do
187
- before do
188
- class FooCallbackMultiple
189
- # this hack is needed to allow testing of parameters, since RSpec
190
- # destroys a method's arity when mocked
191
- attr_accessor :data
192
-
193
- aasm(:left) do
194
- event :safe_close, :success => :success_callback, :error => :error_callback do
195
- transitions :to => :closed, :from => [:open]
196
- end
197
- end
198
- end
199
-
200
- @foo = FooCallbackMultiple.new
201
- end
202
-
203
- context "error_callback defined" do
204
- it "should run error_callback if an exception is raised" do
205
- def @foo.error_callback(e)
206
- @data = [e]
207
- end
208
-
209
- allow(@foo).to receive(:before_enter).and_raise(e = StandardError.new)
210
-
211
- @foo.safe_close!
212
- expect(@foo.data).to eql [e]
213
- end
214
-
215
- it "should run error_callback without parameters if callback does not support any" do
216
- def @foo.error_callback(e)
217
- @data = []
218
- end
219
-
220
- allow(@foo).to receive(:before_enter).and_raise(e = StandardError.new)
221
-
222
- @foo.safe_close!('arg1', 'arg2')
223
- expect(@foo.data).to eql []
224
- end
225
-
226
- it "should run error_callback with parameters if callback supports them" do
227
- def @foo.error_callback(e, arg1, arg2)
228
- @data = [arg1, arg2]
229
- end
230
-
231
- allow(@foo).to receive(:before_enter).and_raise(e = StandardError.new)
232
-
233
- @foo.safe_close!('arg1', 'arg2')
234
- expect(@foo.data).to eql ['arg1', 'arg2']
235
- end
236
- end
237
-
238
- it "should raise NoMethodError if exception is raised and error_callback is declared but not defined" do
239
- allow(@foo).to receive(:before_enter).and_raise(StandardError)
240
- expect{@foo.safe_close!}.to raise_error(NoMethodError)
241
- end
242
-
243
- it "should propagate an error if no error callback is declared" do
244
- allow(@foo).to receive(:before_enter).and_raise("Cannot enter safe")
245
- expect{@foo.close!}.to raise_error(StandardError, "Cannot enter safe")
246
- end
247
- end
248
-
249
- describe "with aasm_event_fired defined" do
250
- before do
251
- @foo = FooMultiple.new
252
- def @foo.aasm_event_fired(event, from, to); end
253
- end
254
-
255
- it 'should call it for successful bang fire' do
256
- expect(@foo).to receive(:aasm_event_fired).with(:close, :open, :closed)
257
- @foo.close!
258
- end
259
-
260
- it 'should call it for successful non-bang fire' do
261
- expect(@foo).to receive(:aasm_event_fired)
262
- @foo.close
263
- end
264
-
265
- it 'should not call it for failing bang fire' do
266
- allow(@foo.aasm(:left)).to receive(:set_current_state_with_persistence).and_return(false)
267
- expect(@foo).not_to receive(:aasm_event_fired)
268
- @foo.close!
269
- end
270
- end
271
-
272
- describe "with aasm_event_failed defined" do
273
- before do
274
- @foo = FooMultiple.new
275
- def @foo.aasm_event_failed(event, from); end
276
- end
277
-
278
- it 'should call it when transition failed for bang fire' do
279
- expect(@foo).to receive(:aasm_event_failed).with(:null, :open)
280
- expect {@foo.null!}.to raise_error(AASM::InvalidTransition)
281
- end
282
-
283
- it 'should call it when transition failed for non-bang fire' do
284
- expect(@foo).to receive(:aasm_event_failed).with(:null, :open)
285
- expect {@foo.null}.to raise_error(AASM::InvalidTransition)
286
- end
287
-
288
- it 'should not call it if persist fails for bang fire' do
289
- allow(@foo.aasm(:left)).to receive(:set_current_state_with_persistence).and_return(false)
290
- expect(@foo).to receive(:aasm_event_failed)
291
- @foo.close!
292
- end
293
- end
294
-
295
- end # event callbacks
@@ -1,296 +0,0 @@
1
- require 'spec_helper'
2
- Dir[File.dirname(__FILE__) + "/../models/callbacks/*.rb"].sort.each { |f| require File.expand_path(f) }
3
-
4
- describe 'callbacks for the new DSL' do
5
-
6
- it "be called in order" do
7
- show_debug_log = false
8
-
9
- callback = Callbacks::Basic.new(:log => show_debug_log)
10
- callback.aasm.current_state
11
-
12
- unless show_debug_log
13
- expect(callback).to receive(:before_event).once.ordered
14
- expect(callback).to receive(:event_guard).once.ordered.and_return(true)
15
- expect(callback).to receive(:transition_guard).once.ordered.and_return(true)
16
- expect(callback).to receive(:before_exit_open).once.ordered # these should be before the state changes
17
- expect(callback).to receive(:exit_open).once.ordered
18
- # expect(callback).to receive(:event_guard).once.ordered.and_return(true)
19
- # expect(callback).to receive(:transition_guard).once.ordered.and_return(true)
20
- expect(callback).to receive(:after_all_transitions).once.ordered
21
- expect(callback).to receive(:after_transition).once.ordered
22
- expect(callback).to receive(:before_enter_closed).once.ordered
23
- expect(callback).to receive(:enter_closed).once.ordered
24
- expect(callback).to receive(:aasm_write_state).once.ordered.and_return(true) # this is when the state changes
25
- expect(callback).to receive(:after_exit_open).once.ordered # these should be after the state changes
26
- expect(callback).to receive(:after_enter_closed).once.ordered
27
- expect(callback).to receive(:after_event).once.ordered
28
- end
29
-
30
- # puts "------- close!"
31
- callback.close!
32
- end
33
-
34
- it "does not run any state callback if the event guard fails" do
35
- callback = Callbacks::Basic.new(:log => false)
36
- callback.aasm.current_state
37
-
38
- expect(callback).to receive(:before_event).once.ordered
39
- expect(callback).to receive(:event_guard).once.ordered.and_return(false)
40
- expect(callback).to_not receive(:transition_guard)
41
- expect(callback).to_not receive(:before_exit_open)
42
- expect(callback).to_not receive(:exit_open)
43
- expect(callback).to_not receive(:after_transition)
44
- expect(callback).to_not receive(:before_enter_closed)
45
- expect(callback).to_not receive(:enter_closed)
46
- expect(callback).to_not receive(:aasm_write_state)
47
- expect(callback).to_not receive(:after_exit_open)
48
- expect(callback).to_not receive(:after_enter_closed)
49
- expect(callback).to_not receive(:after_event)
50
-
51
- expect {
52
- callback.close!
53
- }.to raise_error(AASM::InvalidTransition)
54
- end
55
-
56
- it "handles private callback methods as well" do
57
- show_debug_log = false
58
-
59
- callback = Callbacks::PrivateMethod.new(:log => show_debug_log)
60
- callback.aasm.current_state
61
-
62
- # puts "------- close!"
63
- expect {
64
- callback.close!
65
- }.to_not raise_error
66
- end
67
-
68
- context "if the transition guard fails" do
69
- it "does not run any state callback if guard is defined inline" do
70
- show_debug_log = false
71
- callback = Callbacks::Basic.new(:log => show_debug_log, :fail_transition_guard => true)
72
- callback.aasm.current_state
73
-
74
- unless show_debug_log
75
- expect(callback).to receive(:before_event).once.ordered
76
- expect(callback).to receive(:event_guard).once.ordered.and_return(true)
77
- expect(callback).to receive(:transition_guard).once.ordered.and_return(false)
78
- expect(callback).to_not receive(:before_exit_open)
79
- expect(callback).to_not receive(:exit_open)
80
- expect(callback).to_not receive(:after_transition)
81
- expect(callback).to_not receive(:before_enter_closed)
82
- expect(callback).to_not receive(:enter_closed)
83
- expect(callback).to_not receive(:aasm_write_state)
84
- expect(callback).to_not receive(:after_exit_open)
85
- expect(callback).to_not receive(:after_enter_closed)
86
- expect(callback).to_not receive(:after_event)
87
- end
88
-
89
- expect {
90
- callback.close!
91
- }.to raise_error(AASM::InvalidTransition)
92
- end
93
-
94
- it "does not run transition_guard twice for multiple permitted transitions" do
95
- show_debug_log = false
96
- callback = Callbacks::MultipleTransitionsTransitionGuard.new(:log => show_debug_log, :fail_transition_guard => true)
97
- callback.aasm.current_state
98
-
99
- unless show_debug_log
100
- expect(callback).to receive(:before).once.ordered
101
- expect(callback).to receive(:event_guard).once.ordered.and_return(true)
102
- expect(callback).to receive(:transition_guard).once.ordered.and_return(false)
103
- expect(callback).to receive(:event_guard).once.ordered.and_return(true)
104
- expect(callback).to receive(:before_exit_open).once.ordered
105
- expect(callback).to receive(:exit_open).once.ordered
106
- expect(callback).to receive(:aasm_write_state).once.ordered.and_return(true) # this is when the state changes
107
- expect(callback).to receive(:after_exit_open).once.ordered
108
- expect(callback).to receive(:after).once.ordered
109
-
110
- expect(callback).to_not receive(:transitioning)
111
- expect(callback).to_not receive(:before_enter_closed)
112
- expect(callback).to_not receive(:enter_closed)
113
- expect(callback).to_not receive(:after_enter_closed)
114
- end
115
-
116
- callback.close!
117
- expect(callback.aasm.current_state).to eql :failed
118
- end
119
-
120
- it "does not run any state callback if guard is defined with block" do
121
- callback = Callbacks::GuardWithinBlock.new #(:log => true, :fail_transition_guard => true)
122
- callback.aasm.current_state
123
-
124
- expect(callback).to receive(:before).once.ordered
125
- expect(callback).to receive(:event_guard).once.ordered.and_return(true)
126
- expect(callback).to receive(:transition_guard).once.ordered.and_return(false)
127
- expect(callback).to_not receive(:before_exit_open)
128
- expect(callback).to_not receive(:exit_open)
129
- expect(callback).to_not receive(:transitioning)
130
- expect(callback).to_not receive(:before_enter_closed)
131
- expect(callback).to_not receive(:enter_closed)
132
- expect(callback).to_not receive(:aasm_write_state)
133
- expect(callback).to_not receive(:after_exit_open)
134
- expect(callback).to_not receive(:after_enter_closed)
135
- expect(callback).to_not receive(:after)
136
-
137
- expect {
138
- callback.close!
139
- }.to raise_error(AASM::InvalidTransition)
140
- end
141
- end
142
-
143
- it "should properly pass arguments" do
144
- cb = Callbacks::WithArgs.new(:log => false)
145
- cb.aasm.current_state
146
-
147
- cb.reset_data
148
- cb.close!(:arg1, :arg2)
149
- expect(cb.data).to eql 'before(:arg1,:arg2) before_exit_open(:arg1,:arg2) transition_proc(:arg1,:arg2) before_enter_closed(:arg1,:arg2) aasm_write_state after_exit_open(:arg1,:arg2) after_enter_closed(:arg1,:arg2) after(:arg1,:arg2)'
150
- end
151
-
152
- it "should call the callbacks given the to-state as argument" do
153
- cb = Callbacks::WithStateArg.new
154
- expect(cb).to receive(:before_method).with(:arg1).once.ordered
155
- expect(cb).to receive(:transition_method).never
156
- expect(cb).to receive(:transition_method2).with(:arg1).once.ordered
157
- expect(cb).to receive(:after_method).with(:arg1).once.ordered
158
- cb.close!(:out_to_lunch, :arg1)
159
-
160
- cb = Callbacks::WithStateArg.new
161
- some_object = double('some object')
162
- expect(cb).to receive(:before_method).with(some_object).once.ordered
163
- expect(cb).to receive(:transition_method2).with(some_object).once.ordered
164
- expect(cb).to receive(:after_method).with(some_object).once.ordered
165
- cb.close!(:out_to_lunch, some_object)
166
- end
167
-
168
- it "should call the proper methods just with arguments" do
169
- cb = Callbacks::WithStateArg.new
170
- expect(cb).to receive(:before_method).with(:arg1).once.ordered
171
- expect(cb).to receive(:transition_method).with(:arg1).once.ordered
172
- expect(cb).to receive(:transition_method).never
173
- expect(cb).to receive(:after_method).with(:arg1).once.ordered
174
- cb.close!(:arg1)
175
-
176
- cb = Callbacks::WithStateArg.new
177
- some_object = double('some object')
178
- expect(cb).to receive(:before_method).with(some_object).once.ordered
179
- expect(cb).to receive(:transition_method).with(some_object).once.ordered
180
- expect(cb).to receive(:transition_method).never
181
- expect(cb).to receive(:after_method).with(some_object).once.ordered
182
- cb.close!(some_object)
183
- end
184
- end
185
-
186
- describe 'event callbacks' do
187
- describe "with an error callback defined" do
188
- before do
189
- class Foo
190
- # this hack is needed to allow testing of parameters, since RSpec
191
- # destroys a method's arity when mocked
192
- attr_accessor :data
193
-
194
- aasm do
195
- event :safe_close, :success => :success_callback, :error => :error_callback do
196
- transitions :to => :closed, :from => [:open]
197
- end
198
- end
199
- end
200
-
201
- @foo = Foo.new
202
- end
203
-
204
- context "error_callback defined" do
205
- it "should run error_callback if an exception is raised" do
206
- def @foo.error_callback(e)
207
- @data = [e]
208
- end
209
-
210
- allow(@foo).to receive(:before_enter).and_raise(e = StandardError.new)
211
-
212
- @foo.safe_close!
213
- expect(@foo.data).to eql [e]
214
- end
215
-
216
- it "should run error_callback without parameters if callback does not support any" do
217
- def @foo.error_callback(e)
218
- @data = []
219
- end
220
-
221
- allow(@foo).to receive(:before_enter).and_raise(e = StandardError.new)
222
-
223
- @foo.safe_close!('arg1', 'arg2')
224
- expect(@foo.data).to eql []
225
- end
226
-
227
- it "should run error_callback with parameters if callback supports them" do
228
- def @foo.error_callback(e, arg1, arg2)
229
- @data = [arg1, arg2]
230
- end
231
-
232
- allow(@foo).to receive(:before_enter).and_raise(e = StandardError.new)
233
-
234
- @foo.safe_close!('arg1', 'arg2')
235
- expect(@foo.data).to eql ['arg1', 'arg2']
236
- end
237
- end
238
-
239
- it "should raise NoMethodError if exception is raised and error_callback is declared but not defined" do
240
- allow(@foo).to receive(:before_enter).and_raise(StandardError)
241
- expect{@foo.safe_close!}.to raise_error(NoMethodError)
242
- end
243
-
244
- it "should propagate an error if no error callback is declared" do
245
- allow(@foo).to receive(:before_enter).and_raise("Cannot enter safe")
246
- expect{@foo.close!}.to raise_error(StandardError, "Cannot enter safe")
247
- end
248
- end
249
-
250
- describe "with aasm_event_fired defined" do
251
- before do
252
- @foo = Foo.new
253
- def @foo.aasm_event_fired(event, from, to); end
254
- end
255
-
256
- it 'should call it for successful bang fire' do
257
- expect(@foo).to receive(:aasm_event_fired).with(:close, :open, :closed)
258
- @foo.close!
259
- end
260
-
261
- it 'should call it for successful non-bang fire' do
262
- expect(@foo).to receive(:aasm_event_fired)
263
- @foo.close
264
- end
265
-
266
- it 'should not call it for failing bang fire' do
267
- allow(@foo.aasm).to receive(:set_current_state_with_persistence).and_return(false)
268
- expect(@foo).not_to receive(:aasm_event_fired)
269
- @foo.close!
270
- end
271
- end
272
-
273
- describe "with aasm_event_failed defined" do
274
- before do
275
- @foo = Foo.new
276
- def @foo.aasm_event_failed(event, from); end
277
- end
278
-
279
- it 'should call it when transition failed for bang fire' do
280
- expect(@foo).to receive(:aasm_event_failed).with(:null, :open)
281
- expect {@foo.null!}.to raise_error(AASM::InvalidTransition)
282
- end
283
-
284
- it 'should call it when transition failed for non-bang fire' do
285
- expect(@foo).to receive(:aasm_event_failed).with(:null, :open)
286
- expect {@foo.null}.to raise_error(AASM::InvalidTransition)
287
- end
288
-
289
- it 'should not call it if persist fails for bang fire' do
290
- allow(@foo.aasm).to receive(:set_current_state_with_persistence).and_return(false)
291
- expect(@foo).to receive(:aasm_event_failed)
292
- @foo.close!
293
- end
294
- end
295
-
296
- end
@@ -1,84 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe 'on initialization' do
4
- let(:auth) {ComplexExample.new}
5
-
6
- it 'should be in the pending state' do
7
- expect(auth.aasm.current_state).to eq(:pending)
8
- end
9
-
10
- it 'should have an activation code' do
11
- expect(auth.has_activation_code?).to be_truthy
12
- expect(auth.activation_code).not_to be_nil
13
- end
14
- end
15
-
16
- describe 'when being unsuspended' do
17
- let(:auth) {ComplexExample.new}
18
-
19
- it 'should be able to be unsuspended' do
20
- auth.activate!
21
- auth.suspend!
22
- expect(auth.may_unsuspend?).to be true
23
- end
24
-
25
- it 'should not be able to be unsuspended into active' do
26
- auth.suspend!
27
- expect(auth.may_unsuspend?(:active)).not_to be true
28
- end
29
-
30
- it 'should be able to be unsuspended into active if polite' do
31
- auth.suspend!
32
- expect(auth.may_wait?(:waiting, :please)).to be true
33
- auth.wait!(nil, :please)
34
- end
35
-
36
- it 'should not be able to be unsuspended into active if not polite' do
37
- auth.suspend!
38
- expect(auth.may_wait?(:waiting)).not_to be true
39
- expect(auth.may_wait?(:waiting, :rude)).not_to be true
40
- expect {auth.wait!(nil, :rude)}.to raise_error(AASM::InvalidTransition)
41
- expect {auth.wait!}.to raise_error(AASM::InvalidTransition)
42
- end
43
-
44
- it 'should not be able to be unpassified' do
45
- auth.activate!
46
- auth.suspend!
47
- auth.unsuspend!
48
-
49
- expect(auth.may_unpassify?).not_to be true
50
- expect {auth.unpassify!}.to raise_error(AASM::InvalidTransition)
51
- end
52
-
53
- it 'should be active if previously activated' do
54
- auth.activate!
55
- auth.suspend!
56
- auth.unsuspend!
57
-
58
- expect(auth.aasm.current_state).to eq(:active)
59
- end
60
-
61
- it 'should be pending if not previously activated, but an activation code is present' do
62
- auth.suspend!
63
- auth.unsuspend!
64
-
65
- expect(auth.aasm.current_state).to eq(:pending)
66
- end
67
-
68
- it 'should be passive if not previously activated and there is no activation code' do
69
- auth.activation_code = nil
70
- auth.suspend!
71
- auth.unsuspend!
72
-
73
- expect(auth.aasm.current_state).to eq(:passive)
74
- end
75
-
76
- it "should be able to fire known events" do
77
- expect(auth.aasm.may_fire_event?(:activate)).to be true
78
- end
79
-
80
- it "should not be able to fire unknown events" do
81
- expect(auth.aasm.may_fire_event?(:unknown)).to be false
82
- end
83
-
84
- end