aasm 5.0.1 → 5.0.6

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 (50) hide show
  1. checksums.yaml +4 -4
  2. data/.github/ISSUE_TEMPLATE/bug_report.md +27 -0
  3. data/.github/ISSUE_TEMPLATE/feature_request.md +20 -0
  4. data/.travis.yml +41 -13
  5. data/Appraisals +18 -13
  6. data/CHANGELOG.md +37 -0
  7. data/Gemfile +1 -1
  8. data/README.md +132 -92
  9. data/aasm.gemspec +2 -0
  10. data/gemfiles/norails.gemfile +10 -0
  11. data/gemfiles/rails_3.2.gemfile +2 -1
  12. data/gemfiles/rails_4.2.gemfile +1 -1
  13. data/gemfiles/rails_4.2_mongoid_5.gemfile +1 -1
  14. data/gemfiles/rails_4.2_nobrainer.gemfile +1 -1
  15. data/gemfiles/rails_5.0.gemfile +2 -2
  16. data/gemfiles/rails_5.0_nobrainer.gemfile +1 -1
  17. data/gemfiles/rails_5.1.gemfile +2 -2
  18. data/gemfiles/rails_5.2.gemfile +13 -0
  19. data/lib/aasm/aasm.rb +29 -27
  20. data/lib/aasm/base.rb +25 -7
  21. data/lib/aasm/core/event.rb +9 -4
  22. data/lib/aasm/errors.rb +2 -1
  23. data/lib/aasm/instance_base.rb +4 -3
  24. data/lib/aasm/persistence/active_record_persistence.rb +2 -1
  25. data/lib/aasm/persistence/base.rb +1 -1
  26. data/lib/aasm/persistence/core_data_query_persistence.rb +2 -1
  27. data/lib/aasm/persistence/dynamoid_persistence.rb +1 -1
  28. data/lib/aasm/persistence/mongoid_persistence.rb +1 -1
  29. data/lib/aasm/persistence/no_brainer_persistence.rb +1 -1
  30. data/lib/aasm/persistence/redis_persistence.rb +1 -1
  31. data/lib/aasm/version.rb +1 -1
  32. data/lib/generators/aasm/orm_helpers.rb +6 -0
  33. data/lib/generators/active_record/aasm_generator.rb +3 -1
  34. data/spec/database.rb +12 -0
  35. data/spec/generators/active_record_generator_spec.rb +6 -0
  36. data/spec/models/active_record/instance_level_skip_validation_example.rb +19 -0
  37. data/spec/models/active_record/person.rb +23 -0
  38. data/spec/models/active_record/work.rb +3 -0
  39. data/spec/models/callbacks/with_state_arg.rb +5 -1
  40. data/spec/models/callbacks/with_state_arg_multiple.rb +4 -1
  41. data/spec/spec_helper.rb +10 -0
  42. data/spec/unit/abstract_class_spec.rb +27 -0
  43. data/spec/unit/callback_multiple_spec.rb +4 -0
  44. data/spec/unit/callbacks_spec.rb +30 -0
  45. data/spec/unit/complex_example_spec.rb +0 -1
  46. data/spec/unit/event_spec.rb +13 -0
  47. data/spec/unit/persistence/active_record_persistence_multiple_spec.rb +4 -4
  48. data/spec/unit/persistence/active_record_persistence_spec.rb +26 -4
  49. metadata +42 -3
  50. data/gemfiles/rails_4.0.gemfile +0 -15
@@ -43,5 +43,11 @@ if defined?(ActiveRecord)
43
43
  assert_migration "db/migrate/add_state_to_jobs.rb"
44
44
  end
45
45
 
46
+ it "dont add column if column is already exists" do
47
+ require 'models/active_record/work.rb'
48
+ load_schema
49
+ run_generator %w(work status)
50
+ assert_no_migration "db/migrate/add_status_to_jobs.rb"
51
+ end
46
52
  end
47
53
  end
@@ -0,0 +1,19 @@
1
+ class InstanceLevelSkipValidationExample < ActiveRecord::Base
2
+ include AASM
3
+
4
+ aasm :state do
5
+ state :new, :initial => true
6
+ state :draft
7
+ state :complete
8
+
9
+ event :set_draft do
10
+ transitions from: :new, to: :draft
11
+ end
12
+
13
+ event :complete do
14
+ transitions from: %i[draft new], to: :complete
15
+ end
16
+ end
17
+
18
+ validates :some_string, presence: true
19
+ end
@@ -0,0 +1,23 @@
1
+ class Base < ActiveRecord::Base
2
+ include AASM
3
+
4
+ aasm column: 'status' do
5
+ state :inactive, initial: true
6
+ state :active
7
+
8
+ event :activate do
9
+ transitions from: :inactive, to: :active
10
+ end
11
+
12
+ event :deactivate do
13
+ transitions from: :active, to: :inactive
14
+ end
15
+ end
16
+
17
+ self.abstract_class = true
18
+ self.table_name = 'users'
19
+ end
20
+
21
+
22
+ class Person < Base
23
+ end
@@ -0,0 +1,3 @@
1
+ class Work < ActiveRecord::Base
2
+ include AASM
3
+ end
@@ -8,7 +8,7 @@ module Callbacks
8
8
  state :closed
9
9
  state :out_to_lunch
10
10
 
11
- event :close, :before => :before_method, :after => :after_method do
11
+ event :close, :before => :before_method, :after => :after_method, :before_success => :before_success_method, :success => :success_method3 do
12
12
  transitions :to => :closed, :from => [:open], :after => :transition_method, :success => :success_method
13
13
  transitions :to => :out_to_lunch, :from => [:open], :after => :transition_method2, :success => :success_method2
14
14
  end
@@ -16,6 +16,8 @@ module Callbacks
16
16
 
17
17
  def before_method(arg); end
18
18
 
19
+ def before_success_method(arg); end
20
+
19
21
  def after_method(arg); end
20
22
 
21
23
  def transition_method(arg); end
@@ -26,5 +28,7 @@ module Callbacks
26
28
 
27
29
  def success_method2(arg); end
28
30
 
31
+ def success_method3(arg); end
32
+
29
33
  end
30
34
  end
@@ -8,7 +8,7 @@ module Callbacks
8
8
  state :closed
9
9
  state :out_to_lunch
10
10
 
11
- event :close, :before => :before_method, :after => :after_method do
11
+ event :close, :before => :before_method, :after => :after_method, :before_success => :before_success_method, :success => :success_method do
12
12
  transitions :to => :closed, :from => [:open], :after => :transition_method
13
13
  transitions :to => :out_to_lunch, :from => [:open], :after => :transition_method2
14
14
  end
@@ -16,11 +16,14 @@ module Callbacks
16
16
 
17
17
  def before_method(arg); end
18
18
 
19
+ def before_success_method(arg); end
20
+
19
21
  def after_method(arg); end
20
22
 
21
23
  def transition_method(arg); end
22
24
 
23
25
  def transition_method2(arg); end
24
26
 
27
+ def success_method(arg); end
25
28
  end
26
29
  end
@@ -1,3 +1,13 @@
1
+ require 'simplecov'
2
+ SimpleCov.start do
3
+ add_filter '/spec/'
4
+ end
5
+
6
+ if ENV['CI'] == 'true'
7
+ require 'codecov'
8
+ SimpleCov.formatter = SimpleCov::Formatter::Codecov
9
+ end
10
+
1
11
  $LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__)))
2
12
  $LOAD_PATH.unshift(File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib')))
3
13
  require 'aasm'
@@ -0,0 +1,27 @@
1
+ require 'spec_helper'
2
+ if defined?(ActiveRecord)
3
+ require 'models/active_record/person'
4
+
5
+ load_schema
6
+ describe 'Abstract subclassing' do
7
+
8
+ it 'should have the parent states' do
9
+ Person.aasm.states.each do |state|
10
+ expect(Base.aasm.states).to include(state)
11
+ end
12
+ expect(Person.aasm.states).to eq(Base.aasm.states)
13
+ end
14
+
15
+ it 'should have the same events as its parent' do
16
+ expect(Base.aasm.events).to eq(Person.aasm.events)
17
+ end
18
+
19
+ it 'should not break aasm methods when super class is abstract_class' do
20
+ person = Person.new
21
+ person.status = 'active'
22
+ person.deactivate!
23
+ expect(person.aasm.current_state).to eq(:inactive)
24
+ end
25
+
26
+ end
27
+ end
@@ -154,6 +154,8 @@ describe 'callbacks for the new DSL' do
154
154
  expect(cb).to receive(:before_method).with(:arg1).once.ordered
155
155
  expect(cb).to receive(:transition_method).never
156
156
  expect(cb).to receive(:transition_method2).with(:arg1).once.ordered
157
+ expect(cb).to receive(:before_success_method).with(:arg1).once.ordered
158
+ expect(cb).to receive(:success_method).with(:arg1).once.ordered
157
159
  expect(cb).to receive(:after_method).with(:arg1).once.ordered
158
160
  cb.close!(:out_to_lunch, :arg1)
159
161
 
@@ -161,6 +163,8 @@ describe 'callbacks for the new DSL' do
161
163
  some_object = double('some object')
162
164
  expect(cb).to receive(:before_method).with(some_object).once.ordered
163
165
  expect(cb).to receive(:transition_method2).with(some_object).once.ordered
166
+ expect(cb).to receive(:before_success_method).with(some_object).once.ordered
167
+ expect(cb).to receive(:success_method).with(some_object).once.ordered
164
168
  expect(cb).to receive(:after_method).with(some_object).once.ordered
165
169
  cb.close!(:out_to_lunch, some_object)
166
170
  end
@@ -203,6 +203,32 @@ describe 'callbacks for the new DSL' do
203
203
  }.to raise_error(AASM::InvalidTransition)
204
204
  end
205
205
 
206
+ it "does not propagate failures to next attempt of same transition" do
207
+ callback = Callbacks::Basic.new(:log => false, :fail_transition_guard => true)
208
+
209
+ expect {
210
+ callback.close!
211
+ }.to raise_error(AASM::InvalidTransition, "Event 'close' cannot transition from 'open'. Failed callback(s): [:transition_guard].")
212
+
213
+ expect {
214
+ callback.close!
215
+ }.to raise_error(AASM::InvalidTransition, "Event 'close' cannot transition from 'open'. Failed callback(s): [:transition_guard].")
216
+ end
217
+
218
+ it "does not propagate failures to next attempt of same event when no transition is applicable" do
219
+ callback = Callbacks::Basic.new(:log => false, :fail_transition_guard => true)
220
+
221
+ expect {
222
+ callback.close!
223
+ }.to raise_error(AASM::InvalidTransition, "Event 'close' cannot transition from 'open'. Failed callback(s): [:transition_guard].")
224
+
225
+ callback.aasm.current_state = :closed
226
+
227
+ expect {
228
+ callback.close!
229
+ }.to raise_error(AASM::InvalidTransition, "Event 'close' cannot transition from 'closed'.")
230
+ end
231
+
206
232
  it "does not run transition_guard twice for multiple permitted transitions" do
207
233
  show_debug_log = false
208
234
  callback = Callbacks::MultipleTransitionsTransitionGuard.new(:log => show_debug_log, :fail_transition_guard => true)
@@ -289,7 +315,9 @@ describe 'callbacks for the new DSL' do
289
315
  expect(cb).to receive(:before_method).with(:arg1).once.ordered
290
316
  expect(cb).to receive(:transition_method).with(:arg1).once.ordered
291
317
  expect(cb).to receive(:transition_method).never
318
+ expect(cb).to receive(:before_success_method).with(:arg1).once.ordered
292
319
  expect(cb).to receive(:success_method).with(:arg1).once.ordered
320
+ expect(cb).to receive(:success_method3).with(:arg1).once.ordered
293
321
  expect(cb).to receive(:success_method).never
294
322
  expect(cb).to receive(:after_method).with(:arg1).once.ordered
295
323
  cb.close!(:arg1)
@@ -299,7 +327,9 @@ describe 'callbacks for the new DSL' do
299
327
  expect(cb).to receive(:before_method).with(some_object).once.ordered
300
328
  expect(cb).to receive(:transition_method).with(some_object).once.ordered
301
329
  expect(cb).to receive(:transition_method).never
330
+ expect(cb).to receive(:before_success_method).with(some_object).once.ordered
302
331
  expect(cb).to receive(:success_method).with(some_object).once.ordered
332
+ expect(cb).to receive(:success_method3).with(some_object).once.ordered
303
333
  expect(cb).to receive(:success_method).never
304
334
  expect(cb).to receive(:after_method).with(some_object).once.ordered
305
335
  cb.close!(some_object)
@@ -90,5 +90,4 @@ describe 'when being unsuspended' do
90
90
  it "should not be able to fire unknown events" do
91
91
  expect(auth.aasm.may_fire_event?(:unknown)).to be false
92
92
  end
93
-
94
93
  end
@@ -294,6 +294,19 @@ describe 'current event' do
294
294
  pe.wakeup!
295
295
  expect(pe.aasm.current_event).to eql :wakeup!
296
296
  end
297
+
298
+ describe "when calling events with fire/fire!" do
299
+ it "fire should populate aasm.current_event and transition (sleeping to showering)" do
300
+ pe.aasm.fire(:wakeup)
301
+ expect(pe.aasm.current_event).to eq :wakeup
302
+ expect(pe.aasm.current_state).to eq :showering
303
+ end
304
+ it "fire! should populate aasm.current_event and transition (sleeping to showering)" do
305
+ pe.aasm.fire!(:wakeup)
306
+ expect(pe.aasm.current_event).to eq :wakeup!
307
+ expect(pe.aasm.current_state).to eq :showering
308
+ end
309
+ end
297
310
  end
298
311
 
299
312
  describe 'parametrised events' do
@@ -359,13 +359,13 @@ if defined?(ActiveRecord)
359
359
 
360
360
  # allow it temporarily
361
361
  MultipleNoDirectAssignment.aasm(:left).state_machine.config.no_direct_assignment = false
362
- obj.aasm_state = :pending
363
- expect(obj.aasm_state.to_sym).to eql :pending
362
+ obj.aasm_state = :running
363
+ expect(obj.aasm_state.to_sym).to eql :running
364
364
 
365
365
  # and forbid it again
366
366
  MultipleNoDirectAssignment.aasm(:left).state_machine.config.no_direct_assignment = true
367
- expect {obj.aasm_state = :running}.to raise_error(AASM::NoDirectAssignmentError)
368
- expect(obj.aasm_state.to_sym).to eql :pending
367
+ expect {obj.aasm_state = :pending}.to raise_error(AASM::NoDirectAssignmentError)
368
+ expect(obj.aasm_state.to_sym).to eql :running
369
369
  end
370
370
  end # direct assignment
371
371
 
@@ -393,13 +393,13 @@ if defined?(ActiveRecord)
393
393
 
394
394
  # allow it temporarily
395
395
  NoDirectAssignment.aasm.state_machine.config.no_direct_assignment = false
396
- obj.aasm_state = :pending
397
- expect(obj.aasm_state.to_sym).to eql :pending
396
+ obj.aasm_state = :running
397
+ expect(obj.aasm_state.to_sym).to eql :running
398
398
 
399
399
  # and forbid it again
400
400
  NoDirectAssignment.aasm.state_machine.config.no_direct_assignment = true
401
- expect {obj.aasm_state = :running}.to raise_error(AASM::NoDirectAssignmentError)
402
- expect(obj.aasm_state.to_sym).to eql :pending
401
+ expect {obj.aasm_state = :pending}.to raise_error(AASM::NoDirectAssignmentError)
402
+ expect(obj.aasm_state.to_sym).to eql :running
403
403
  end
404
404
  end # direct assignment
405
405
 
@@ -748,4 +748,26 @@ if defined?(ActiveRecord)
748
748
  expect { job.run }.to raise_error(AASM::InvalidTransition)
749
749
  end
750
750
  end
751
+
752
+ describe 'testing the instance_level skip validation with _without_validation method' do
753
+ let(:example) do
754
+ obj = InstanceLevelSkipValidationExample.new(state: 'new')
755
+ obj.save(validate: false)
756
+ obj
757
+ end
758
+
759
+ it 'should be able to change the state with invalid record' do
760
+ expect(example.valid?).to be_falsey
761
+ expect(example.complete!).to be_falsey
762
+ expect(example.complete_without_validation!).to be_truthy
763
+ expect(example.state).to eq('complete')
764
+ end
765
+
766
+ it 'shouldn\'t affect the behaviour of existing method after calling _without_validation! method' do
767
+ expect(example.set_draft!).to be_falsey
768
+ expect(example.set_draft_without_validation!).to be_truthy
769
+ expect(example.state).to eq('draft')
770
+ expect(example.complete!).to be_falsey
771
+ end
772
+ end
751
773
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: aasm
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.0.1
4
+ version: 5.0.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Thorsten Boettger
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2018-09-07 00:00:00.000000000 Z
12
+ date: 2019-09-04 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: concurrent-ruby
@@ -95,6 +95,34 @@ dependencies:
95
95
  - - ">="
96
96
  - !ruby/object:Gem::Version
97
97
  version: '0'
98
+ - !ruby/object:Gem::Dependency
99
+ name: simplecov
100
+ requirement: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - ">="
103
+ - !ruby/object:Gem::Version
104
+ version: '0'
105
+ type: :development
106
+ prerelease: false
107
+ version_requirements: !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - ">="
110
+ - !ruby/object:Gem::Version
111
+ version: '0'
112
+ - !ruby/object:Gem::Dependency
113
+ name: codecov
114
+ requirement: !ruby/object:Gem::Requirement
115
+ requirements:
116
+ - - ">="
117
+ - !ruby/object:Gem::Version
118
+ version: 0.1.10
119
+ type: :development
120
+ prerelease: false
121
+ version_requirements: !ruby/object:Gem::Requirement
122
+ requirements:
123
+ - - ">="
124
+ - !ruby/object:Gem::Version
125
+ version: 0.1.10
98
126
  - !ruby/object:Gem::Dependency
99
127
  name: pry
100
128
  requirement: !ruby/object:Gem::Requirement
@@ -117,6 +145,8 @@ extensions: []
117
145
  extra_rdoc_files: []
118
146
  files:
119
147
  - ".document"
148
+ - ".github/ISSUE_TEMPLATE/bug_report.md"
149
+ - ".github/ISSUE_TEMPLATE/feature_request.md"
120
150
  - ".gitignore"
121
151
  - ".travis.yml"
122
152
  - API
@@ -137,14 +167,15 @@ files:
137
167
  - aasm.gemspec
138
168
  - callbacks.txt
139
169
  - docker-compose.yml
170
+ - gemfiles/norails.gemfile
140
171
  - gemfiles/rails_3.2.gemfile
141
- - gemfiles/rails_4.0.gemfile
142
172
  - gemfiles/rails_4.2.gemfile
143
173
  - gemfiles/rails_4.2_mongoid_5.gemfile
144
174
  - gemfiles/rails_4.2_nobrainer.gemfile
145
175
  - gemfiles/rails_5.0.gemfile
146
176
  - gemfiles/rails_5.0_nobrainer.gemfile
147
177
  - gemfiles/rails_5.1.gemfile
178
+ - gemfiles/rails_5.2.gemfile
148
179
  - lib/aasm.rb
149
180
  - lib/aasm/aasm.rb
150
181
  - lib/aasm/base.rb
@@ -206,11 +237,13 @@ files:
206
237
  - spec/models/active_record/derivate_new_dsl.rb
207
238
  - spec/models/active_record/false_state.rb
208
239
  - spec/models/active_record/gate.rb
240
+ - spec/models/active_record/instance_level_skip_validation_example.rb
209
241
  - spec/models/active_record/invalid_persistor.rb
210
242
  - spec/models/active_record/localizer_test_model.rb
211
243
  - spec/models/active_record/no_direct_assignment.rb
212
244
  - spec/models/active_record/no_scope.rb
213
245
  - spec/models/active_record/persisted_state.rb
246
+ - spec/models/active_record/person.rb
214
247
  - spec/models/active_record/provided_and_persisted_state.rb
215
248
  - spec/models/active_record/reader.rb
216
249
  - spec/models/active_record/readme_job.rb
@@ -224,6 +257,7 @@ files:
224
257
  - spec/models/active_record/with_enum_without_column.rb
225
258
  - spec/models/active_record/with_false_enum.rb
226
259
  - spec/models/active_record/with_true_enum.rb
260
+ - spec/models/active_record/work.rb
227
261
  - spec/models/active_record/worker.rb
228
262
  - spec/models/active_record/writer.rb
229
263
  - spec/models/basic_two_state_machines_example.rb
@@ -312,6 +346,7 @@ files:
312
346
  - spec/spec_helpers/redis.rb
313
347
  - spec/spec_helpers/remove_warnings.rb
314
348
  - spec/spec_helpers/sequel.rb
349
+ - spec/unit/abstract_class_spec.rb
315
350
  - spec/unit/api_spec.rb
316
351
  - spec/unit/basic_two_state_machines_example_spec.rb
317
352
  - spec/unit/callback_multiple_spec.rb
@@ -406,11 +441,13 @@ test_files:
406
441
  - spec/models/active_record/derivate_new_dsl.rb
407
442
  - spec/models/active_record/false_state.rb
408
443
  - spec/models/active_record/gate.rb
444
+ - spec/models/active_record/instance_level_skip_validation_example.rb
409
445
  - spec/models/active_record/invalid_persistor.rb
410
446
  - spec/models/active_record/localizer_test_model.rb
411
447
  - spec/models/active_record/no_direct_assignment.rb
412
448
  - spec/models/active_record/no_scope.rb
413
449
  - spec/models/active_record/persisted_state.rb
450
+ - spec/models/active_record/person.rb
414
451
  - spec/models/active_record/provided_and_persisted_state.rb
415
452
  - spec/models/active_record/reader.rb
416
453
  - spec/models/active_record/readme_job.rb
@@ -424,6 +461,7 @@ test_files:
424
461
  - spec/models/active_record/with_enum_without_column.rb
425
462
  - spec/models/active_record/with_false_enum.rb
426
463
  - spec/models/active_record/with_true_enum.rb
464
+ - spec/models/active_record/work.rb
427
465
  - spec/models/active_record/worker.rb
428
466
  - spec/models/active_record/writer.rb
429
467
  - spec/models/basic_two_state_machines_example.rb
@@ -512,6 +550,7 @@ test_files:
512
550
  - spec/spec_helpers/redis.rb
513
551
  - spec/spec_helpers/remove_warnings.rb
514
552
  - spec/spec_helpers/sequel.rb
553
+ - spec/unit/abstract_class_spec.rb
515
554
  - spec/unit/api_spec.rb
516
555
  - spec/unit/basic_two_state_machines_example_spec.rb
517
556
  - spec/unit/callback_multiple_spec.rb