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,552 +0,0 @@
1
- require 'active_record'
2
- require 'spec_helper'
3
- Dir[File.dirname(__FILE__) + "/../../models/active_record/*.rb"].sort.each do |f|
4
- require File.expand_path(f)
5
- end
6
-
7
- load_schema
8
-
9
- # if you want to see the statements while running the spec enable the following line
10
- # require 'logger'
11
- # ActiveRecord::Base.logger = Logger.new(STDERR)
12
-
13
- describe "instance methods" do
14
- let(:gate) {Gate.new}
15
-
16
- it "should respond to aasm persistence methods" do
17
- expect(gate).to respond_to(:aasm_read_state)
18
- expect(gate).to respond_to(:aasm_write_state)
19
- expect(gate).to respond_to(:aasm_write_state_without_persistence)
20
- end
21
-
22
- describe "aasm_column_looks_like_enum" do
23
- subject { lambda{ gate.send(:aasm_column_looks_like_enum) } }
24
-
25
- let(:column_name) { "value" }
26
- let(:columns_hash) { Hash[column_name, column] }
27
-
28
- before :each do
29
- allow(gate.class.aasm).to receive(:attribute_name).and_return(column_name.to_sym)
30
- allow(gate.class).to receive(:columns_hash).and_return(columns_hash)
31
- end
32
-
33
- context "when AASM column has integer type" do
34
- let(:column) { double(Object, type: :integer) }
35
-
36
- it "returns true" do
37
- expect(subject.call).to be_truthy
38
- end
39
- end
40
-
41
- context "when AASM column has string type" do
42
- let(:column) { double(Object, type: :string) }
43
-
44
- it "returns false" do
45
- expect(subject.call).to be_falsey
46
- end
47
- end
48
- end
49
-
50
- describe "aasm_guess_enum_method" do
51
- subject { lambda{ gate.send(:aasm_guess_enum_method) } }
52
-
53
- before :each do
54
- allow(gate.class.aasm).to receive(:attribute_name).and_return(:value)
55
- end
56
-
57
- it "pluralizes AASM column name" do
58
- expect(subject.call).to eq :values
59
- end
60
- end
61
-
62
- describe "aasm_enum" do
63
- context "when AASM enum setting contains an explicit enum method name" do
64
- let(:with_enum) { WithEnum.new }
65
-
66
- it "returns whatever value was set in AASM config" do
67
- expect(with_enum.send(:aasm_enum)).to eq :test
68
- end
69
- end
70
-
71
- context "when AASM enum setting is simply set to true" do
72
- let(:with_true_enum) { WithTrueEnum.new }
73
- before :each do
74
- allow(WithTrueEnum.aasm).to receive(:attribute_name).and_return(:value)
75
- end
76
-
77
- it "infers enum method name from pluralized column name" do
78
- expect(with_true_enum.send(:aasm_enum)).to eq :values
79
- end
80
- end
81
-
82
- context "when AASM enum setting is explicitly disabled" do
83
- let(:with_false_enum) { WithFalseEnum.new }
84
-
85
- it "returns nil" do
86
- expect(with_false_enum.send(:aasm_enum)).to be_nil
87
- end
88
- end
89
-
90
- context "when AASM enum setting is not enabled" do
91
- before :each do
92
- allow(Gate.aasm).to receive(:attribute_name).and_return(:value)
93
- end
94
-
95
- context "when AASM column looks like enum" do
96
- before :each do
97
- allow(gate).to receive(:aasm_column_looks_like_enum).and_return(true)
98
- end
99
-
100
- it "infers enum method name from pluralized column name" do
101
- expect(gate.send(:aasm_enum)).to eq :values
102
- end
103
- end
104
-
105
- context "when AASM column doesn't look like enum'" do
106
- before :each do
107
- allow(gate).to receive(:aasm_column_looks_like_enum)
108
- .and_return(false)
109
- end
110
-
111
- it "returns nil, as we're not using enum" do
112
- expect(gate.send(:aasm_enum)).to be_nil
113
- end
114
- end
115
- end
116
- end
117
-
118
- context "when AASM is configured to use enum" do
119
- let(:state_sym) { :running }
120
- let(:state_code) { 2 }
121
- let(:enum_name) { :states }
122
- let(:enum) { Hash[state_sym, state_code] }
123
-
124
- before :each do
125
- allow(gate).to receive(:aasm_enum).and_return(enum_name)
126
- allow(gate).to receive(:aasm_write_attribute)
127
- allow(gate).to receive(:write_attribute)
128
-
129
- allow(Gate).to receive(enum_name).and_return(enum)
130
- end
131
-
132
- describe "aasm_write_state" do
133
- context "when AASM is configured to skip validations on save" do
134
- before :each do
135
- allow(gate).to receive(:aasm_skipping_validations).and_return(true)
136
- end
137
-
138
- it "passes state code instead of state symbol to update_all" do
139
- # stub_chain does not allow us to give expectations on call
140
- # parameters in the middle of the chain, so we need to use
141
- # intermediate object instead.
142
- obj = double(Object, update_all: 1)
143
- allow(Gate).to receive(:where).and_return(obj)
144
-
145
- gate.aasm_write_state state_sym
146
-
147
- expect(obj).to have_received(:update_all)
148
- .with(Hash[gate.class.aasm.attribute_name, state_code])
149
- end
150
- end
151
-
152
- context "when AASM is not skipping validations" do
153
- it "delegates state update to the helper method" do
154
- # Let's pretend that validation is passed
155
- allow(gate).to receive(:save).and_return(true)
156
-
157
- gate.aasm_write_state state_sym
158
-
159
- expect(gate).to have_received(:aasm_write_attribute).with(state_sym, :default)
160
- expect(gate).to_not have_received :write_attribute
161
- end
162
- end
163
- end
164
-
165
- describe "aasm_write_state_without_persistence" do
166
- it "delegates state update to the helper method" do
167
- gate.aasm_write_state_without_persistence state_sym
168
-
169
- expect(gate).to have_received(:aasm_write_attribute).with(state_sym, :default)
170
- expect(gate).to_not have_received :write_attribute
171
- end
172
- end
173
-
174
- describe "aasm_raw_attribute_value" do
175
- it "converts state symbol to state code" do
176
- expect(gate.send(:aasm_raw_attribute_value, state_sym))
177
- .to eq state_code
178
- end
179
- end
180
- end
181
-
182
- context "when AASM is configured to use string field" do
183
- let(:state_sym) { :running }
184
-
185
- before :each do
186
- allow(gate).to receive(:aasm_enum).and_return(nil)
187
- end
188
-
189
- describe "aasm_raw_attribute_value" do
190
- it "converts state symbol to string" do
191
- expect(gate.send(:aasm_raw_attribute_value, state_sym))
192
- .to eq state_sym.to_s
193
- end
194
- end
195
- end
196
-
197
- describe "aasm_write_attribute helper method" do
198
- let(:sym) { :sym }
199
- let(:value) { 42 }
200
-
201
- before :each do
202
- allow(gate).to receive(:write_attribute)
203
- allow(gate).to receive(:aasm_raw_attribute_value).and_return(value)
204
-
205
- gate.send(:aasm_write_attribute, sym)
206
- end
207
-
208
- it "generates attribute value using a helper method" do
209
- expect(gate).to have_received(:aasm_raw_attribute_value).with(sym, :default)
210
- end
211
-
212
- it "writes attribute to the model" do
213
- expect(gate).to have_received(:write_attribute).with(:aasm_state, value)
214
- end
215
- end
216
-
217
- it "should return the initial state when new and the aasm field is nil" do
218
- expect(gate.aasm.current_state).to eq(:opened)
219
- end
220
-
221
- it "should return the aasm column when new and the aasm field is not nil" do
222
- gate.aasm_state = "closed"
223
- expect(gate.aasm.current_state).to eq(:closed)
224
- end
225
-
226
- it "should return the aasm column when not new and the aasm.attribute_name is not nil" do
227
- allow(gate).to receive(:new_record?).and_return(false)
228
- gate.aasm_state = "state"
229
- expect(gate.aasm.current_state).to eq(:state)
230
- end
231
-
232
- it "should allow a nil state" do
233
- allow(gate).to receive(:new_record?).and_return(false)
234
- gate.aasm_state = nil
235
- expect(gate.aasm.current_state).to be_nil
236
- end
237
-
238
- context 'on initialization' do
239
- it "should initialize the aasm state" do
240
- expect(Gate.new.aasm_state).to eql 'opened'
241
- expect(Gate.new.aasm.current_state).to eql :opened
242
- end
243
-
244
- it "should not initialize the aasm state if it has not been loaded" do
245
- # we have to create a gate in the database, for which we only want to
246
- # load the id, and not the state
247
- gate = Gate.create!
248
-
249
- # then we just load the gate ids
250
- Gate.select(:id).where(id: gate.id).first
251
- end
252
- end
253
-
254
- end
255
-
256
- if ActiveRecord::VERSION::MAJOR < 4 && ActiveRecord::VERSION::MINOR < 2 # won't work with Rails >= 4.2
257
- describe "direct state column access" do
258
- it "accepts false states" do
259
- f = FalseState.create!
260
- expect(f.aasm_state).to eql false
261
- expect {
262
- f.aasm.events.map(&:name)
263
- }.to_not raise_error
264
- end
265
- end
266
- end
267
-
268
- describe 'subclasses' do
269
- it "should have the same states as its parent class" do
270
- expect(DerivateNewDsl.aasm.states).to eq(SimpleNewDsl.aasm.states)
271
- end
272
-
273
- it "should have the same events as its parent class" do
274
- expect(DerivateNewDsl.aasm.events).to eq(SimpleNewDsl.aasm.events)
275
- end
276
-
277
- it "should have the same column as its parent even for the new dsl" do
278
- expect(SimpleNewDsl.aasm.attribute_name).to eq(:status)
279
- expect(DerivateNewDsl.aasm.attribute_name).to eq(:status)
280
- end
281
- end
282
-
283
- describe "named scopes with the new DSL" do
284
- context "Does not already respond_to? the scope name" do
285
- it "should add a scope" do
286
- expect(SimpleNewDsl).to respond_to(:unknown_scope)
287
- expect(SimpleNewDsl.unknown_scope.is_a?(ActiveRecord::Relation)).to be_truthy
288
- end
289
- end
290
-
291
- context "Already respond_to? the scope name" do
292
- it "should not add a scope" do
293
- expect(SimpleNewDsl).to respond_to(:new)
294
- expect(SimpleNewDsl.new.class).to eq(SimpleNewDsl)
295
- end
296
- end
297
-
298
- it "does not create scopes if requested" do
299
- expect(NoScope).not_to respond_to(:pending)
300
- end
301
-
302
- context "result of scope" do
303
- let!(:dsl1) { SimpleNewDsl.create!(status: :new) }
304
- let!(:dsl2) { SimpleNewDsl.create!(status: :unknown_scope) }
305
-
306
- after do
307
- SimpleNewDsl.destroy_all
308
- end
309
-
310
- it "created scope works as where(name: :scope_name)" do
311
- expect(SimpleNewDsl.unknown_scope).to contain_exactly(dsl2)
312
- end
313
- end
314
- end # scopes
315
-
316
- describe "direct assignment" do
317
- it "is allowed by default" do
318
- obj = NoScope.create
319
- expect(obj.aasm_state.to_sym).to eql :pending
320
-
321
- obj.aasm_state = :running
322
- expect(obj.aasm_state.to_sym).to eql :running
323
- end
324
-
325
- it "is forbidden if configured" do
326
- obj = NoDirectAssignment.create
327
- expect(obj.aasm_state.to_sym).to eql :pending
328
-
329
- expect {obj.aasm_state = :running}.to raise_error(AASM::NoDirectAssignmentError)
330
- expect(obj.aasm_state.to_sym).to eql :pending
331
- end
332
-
333
- it 'can be turned off and on again' do
334
- obj = NoDirectAssignment.create
335
- expect(obj.aasm_state.to_sym).to eql :pending
336
-
337
- expect {obj.aasm_state = :running}.to raise_error(AASM::NoDirectAssignmentError)
338
- expect(obj.aasm_state.to_sym).to eql :pending
339
-
340
- # allow it temporarily
341
- NoDirectAssignment.aasm.state_machine.config.no_direct_assignment = false
342
- obj.aasm_state = :pending
343
- expect(obj.aasm_state.to_sym).to eql :pending
344
-
345
- # and forbid it again
346
- NoDirectAssignment.aasm.state_machine.config.no_direct_assignment = true
347
- expect {obj.aasm_state = :running}.to raise_error(AASM::NoDirectAssignmentError)
348
- expect(obj.aasm_state.to_sym).to eql :pending
349
- end
350
- end # direct assignment
351
-
352
- describe 'initial states' do
353
-
354
- it 'should support conditions' do
355
- expect(Thief.new(:skilled => true).aasm.current_state).to eq(:rich)
356
- expect(Thief.new(:skilled => false).aasm.current_state).to eq(:jailed)
357
- end
358
- end
359
-
360
- describe 'transitions with persistence' do
361
-
362
- it "should work for valid models" do
363
- valid_object = Validator.create(:name => 'name')
364
- expect(valid_object).to be_sleeping
365
- valid_object.status = :running
366
- expect(valid_object).to be_running
367
- end
368
-
369
- it 'should not store states for invalid models' do
370
- validator = Validator.create(:name => 'name')
371
- expect(validator).to be_valid
372
- expect(validator).to be_sleeping
373
-
374
- validator.name = nil
375
- expect(validator).not_to be_valid
376
- expect(validator.run!).to be_falsey
377
- expect(validator).to be_sleeping
378
-
379
- validator.reload
380
- expect(validator).not_to be_running
381
- expect(validator).to be_sleeping
382
-
383
- validator.name = 'another name'
384
- expect(validator).to be_valid
385
- expect(validator.run!).to be_truthy
386
- expect(validator).to be_running
387
-
388
- validator.reload
389
- expect(validator).to be_running
390
- expect(validator).not_to be_sleeping
391
- end
392
-
393
- it 'should store states for invalid models if configured' do
394
- persistor = InvalidPersistor.create(:name => 'name')
395
- expect(persistor).to be_valid
396
- expect(persistor).to be_sleeping
397
-
398
- persistor.name = nil
399
- expect(persistor).not_to be_valid
400
- expect(persistor.run!).to be_truthy
401
- expect(persistor).to be_running
402
-
403
- persistor = InvalidPersistor.find(persistor.id)
404
- persistor.valid?
405
- expect(persistor).to be_valid
406
- expect(persistor).to be_running
407
- expect(persistor).not_to be_sleeping
408
-
409
- persistor.reload
410
- expect(persistor).to be_running
411
- expect(persistor).not_to be_sleeping
412
- end
413
-
414
- describe 'transactions' do
415
- let(:worker) { Worker.create!(:name => 'worker', :status => 'sleeping') }
416
- let(:transactor) { Transactor.create!(:name => 'transactor', :worker => worker) }
417
-
418
- it 'should rollback all changes' do
419
- expect(transactor).to be_sleeping
420
- expect(worker.status).to eq('sleeping')
421
-
422
- expect {transactor.run!}.to raise_error(StandardError, 'failed on purpose')
423
- expect(transactor).to be_running
424
- expect(worker.reload.status).to eq('sleeping')
425
- end
426
-
427
- context "nested transactions" do
428
- it "should rollback all changes in nested transaction" do
429
- expect(transactor).to be_sleeping
430
- expect(worker.status).to eq('sleeping')
431
-
432
- Worker.transaction do
433
- expect { transactor.run! }.to raise_error(StandardError, 'failed on purpose')
434
- end
435
-
436
- expect(transactor).to be_running
437
- expect(worker.reload.status).to eq('sleeping')
438
- end
439
-
440
- it "should only rollback changes in the main transaction not the nested one" do
441
- # change configuration to not require new transaction
442
- AASM::StateMachine[Transactor][:default].config.requires_new_transaction = false
443
-
444
- expect(transactor).to be_sleeping
445
- expect(worker.status).to eq('sleeping')
446
-
447
- Worker.transaction do
448
- expect { transactor.run! }.to raise_error(StandardError, 'failed on purpose')
449
- end
450
-
451
- expect(transactor).to be_running
452
- expect(worker.reload.status).to eq('running')
453
- end
454
- end
455
-
456
- describe "after_commit callback" do
457
- it "should fire :after_commit if transaction was successful" do
458
- validator = Validator.create(:name => 'name')
459
- expect(validator).to be_sleeping
460
-
461
- validator.run!
462
- expect(validator).to be_running
463
- expect(validator.name).to eq("name changed")
464
-
465
- validator.sleep!("sleeper")
466
- expect(validator).to be_sleeping
467
- expect(validator.name).to eq("sleeper")
468
- end
469
-
470
- it "should not fire :after_commit if transaction failed" do
471
- validator = Validator.create(:name => 'name')
472
- expect { validator.fail! }.to raise_error(StandardError, 'failed on purpose')
473
- expect(validator.name).to eq("name")
474
- end
475
-
476
- it "should not fire if not saving" do
477
- validator = Validator.create(:name => 'name')
478
- expect(validator).to be_sleeping
479
- validator.run
480
- expect(validator).to be_running
481
- expect(validator.name).to eq("name")
482
- end
483
-
484
- end
485
-
486
- context "when not persisting" do
487
- it 'should not rollback all changes' do
488
- expect(transactor).to be_sleeping
489
- expect(worker.status).to eq('sleeping')
490
-
491
- # Notice here we're calling "run" and not "run!" with a bang.
492
- expect {transactor.run}.to raise_error(StandardError, 'failed on purpose')
493
- expect(transactor).to be_running
494
- expect(worker.reload.status).to eq('running')
495
- end
496
-
497
- it 'should not create a database transaction' do
498
- expect(transactor.class).not_to receive(:transaction)
499
- expect {transactor.run}.to raise_error(StandardError, 'failed on purpose')
500
- end
501
- end
502
- end
503
- end
504
-
505
- describe "invalid states with persistence" do
506
-
507
- it "should not store states" do
508
- validator = Validator.create(:name => 'name')
509
- validator.status = 'invalid_state'
510
- expect(validator.save).to be_falsey
511
- expect {validator.save!}.to raise_error(ActiveRecord::RecordInvalid)
512
-
513
- validator.reload
514
- expect(validator).to be_sleeping
515
- end
516
-
517
- it "should store invalid states if configured" do
518
- persistor = InvalidPersistor.create(:name => 'name')
519
- persistor.status = 'invalid_state'
520
- expect(persistor.save).to be_truthy
521
-
522
- persistor.reload
523
- expect(persistor.status).to eq('invalid_state')
524
- end
525
-
526
- end
527
-
528
- describe 'basic example with two state machines' do
529
- let(:example) { BasicActiveRecordTwoStateMachinesExample.new }
530
-
531
- it 'should initialise properly' do
532
- expect(example.aasm(:search).current_state).to eql :initialised
533
- expect(example.aasm(:sync).current_state).to eql :unsynced
534
- end
535
- end
536
-
537
- describe 'testing the README examples' do
538
- it 'Usage' do
539
- job = ReadmeJob.new
540
-
541
- expect(job.sleeping?).to eql true
542
- expect(job.may_run?).to eql true
543
-
544
- job.run
545
-
546
- expect(job.running?).to eql true
547
- expect(job.sleeping?).to eql false
548
- expect(job.may_run?).to eql false
549
-
550
- expect { job.run }.to raise_error(AASM::InvalidTransition)
551
- end
552
- end
@@ -1,146 +0,0 @@
1
- describe 'mongo_mapper' do
2
- begin
3
- require 'mongo_mapper'
4
- require 'logger'
5
- require 'spec_helper'
6
-
7
- Dir[File.dirname(__FILE__) + "/../../models/mongo_mapper/*.rb"].sort.each do |f|
8
- require File.expand_path(f)
9
- end
10
-
11
- before(:all) do
12
- config = {
13
- 'test' => {
14
- 'database' => "mongo_mapper_#{Process.pid}"
15
- }
16
- }
17
-
18
- MongoMapper.setup(config, 'test') #, :logger => Logger.new(STDERR))
19
- end
20
-
21
- after do
22
- # Clear Out all non-system Mongo collections between tests
23
- MongoMapper.database.collections.each do |collection|
24
- collection.drop unless collection.capped? || (collection.name =~ /\Asystem/)
25
- end
26
- end
27
-
28
- describe "named scopes with the old DSL" do
29
-
30
- context "Does not already respond_to? the scope name" do
31
- it "should add a scope" do
32
- expect(SimpleMongoMapperMultiple).to respond_to(:unknown_scope)
33
- expect(SimpleMongoMapperMultiple.unknown_scope.class).to eq(MongoMapper::Plugins::Querying::DecoratedPluckyQuery)
34
- #expect(SimpleMongoMapperMultiple.unknown_scope.is_a?(ActiveRecord::Relation)).to be_truthy
35
- end
36
- end
37
-
38
- context "Already respond_to? the scope name" do
39
- it "should not add a scope" do
40
- expect(SimpleMongoMapperMultiple).to respond_to(:next)
41
- expect(SimpleMongoMapperMultiple.new.class).to eq(SimpleMongoMapperMultiple)
42
- end
43
- end
44
-
45
- end
46
-
47
- describe "named scopes with the new DSL" do
48
-
49
- context "Does not already respond_to? the scope name" do
50
- it "should add a scope" do
51
- expect(SimpleNewDslMongoMapperMultiple).to respond_to(:unknown_scope)
52
- expect(SimpleNewDslMongoMapperMultiple.unknown_scope.class).to eq(MongoMapper::Plugins::Querying::DecoratedPluckyQuery)
53
- end
54
- end
55
-
56
- context "Already respond_to? the scope name" do
57
- it "should not add a scope" do
58
- expect(SimpleNewDslMongoMapperMultiple).to respond_to(:next)
59
- expect(SimpleNewDslMongoMapperMultiple.new.class).to eq(SimpleNewDslMongoMapperMultiple)
60
- end
61
- end
62
-
63
- it "does not create scopes if requested" do
64
- expect(NoScopeMongoMapperMultiple).not_to respond_to(:ignored_scope)
65
- end
66
-
67
- end
68
-
69
- describe "instance methods" do
70
-
71
- let(:simple) {SimpleNewDslMongoMapperMultiple.new}
72
-
73
- it "should call aasm_ensure_initial_state on validation before create" do
74
- expect(SimpleNewDslMongoMapperMultiple.aasm(:left).initial_state).to eq(:unknown_scope)
75
- expect(SimpleNewDslMongoMapperMultiple.aasm(:left).attribute_name).to eq(:status)
76
- expect(simple.status).to eq(nil)
77
- simple.valid?
78
- expect(simple.status).to eq('unknown_scope')
79
- end
80
-
81
- it "should call aasm_ensure_initial_state before create, even if skipping validations" do
82
- expect(simple.status).to eq(nil)
83
- simple.save(:validate => false)
84
- expect(simple.status).to eq('unknown_scope')
85
- end
86
- end
87
-
88
- describe "complex example" do
89
- it "works" do
90
- record = ComplexMongoMapperExample.new
91
- expect(record.aasm(:left).current_state).to eql :one
92
- expect(record.left).to be_nil
93
- expect(record.aasm(:right).current_state).to eql :alpha
94
- expect(record.right).to be_nil
95
-
96
- record.save!
97
- expect_aasm_states record, :one, :alpha
98
- record.reload
99
- expect_aasm_states record, :one, :alpha
100
-
101
- record.increment!
102
- expect_aasm_states record, :two, :alpha
103
- record.reload
104
- expect_aasm_states record, :two, :alpha
105
-
106
- record.level_up!
107
- expect_aasm_states record, :two, :beta
108
- record.reload
109
- expect_aasm_states record, :two, :beta
110
-
111
- record.increment!
112
- expect { record.increment! }.to raise_error(AASM::InvalidTransition)
113
- expect_aasm_states record, :three, :beta
114
- record.reload
115
- expect_aasm_states record, :three, :beta
116
-
117
- record.level_up!
118
- expect_aasm_states record, :three, :gamma
119
- record.reload
120
- expect_aasm_states record, :three, :gamma
121
-
122
- record.level_down # without saving
123
- expect_aasm_states record, :three, :beta
124
- record.reload
125
- expect_aasm_states record, :three, :gamma
126
-
127
- record.level_down # without saving
128
- expect_aasm_states record, :three, :beta
129
- record.reset!
130
- expect_aasm_states record, :one, :beta
131
- end
132
-
133
- def expect_aasm_states(record, left_state, right_state)
134
- expect(record.aasm(:left).current_state).to eql left_state.to_sym
135
- expect(record.left).to eql left_state.to_s
136
- expect(record.aasm(:right).current_state).to eql right_state.to_sym
137
- expect(record.right).to eql right_state.to_s
138
- end
139
- end
140
-
141
- rescue LoadError
142
- puts "--------------------------------------------------------------------------"
143
- puts "Not running MongoMapper specs because mongo_mapper gem is not installed!!!"
144
- puts "--------------------------------------------------------------------------"
145
- end
146
- end