aasm 5.0.2 → 5.0.7

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 (44) 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 +42 -11
  5. data/Appraisals +17 -2
  6. data/CHANGELOG.md +33 -0
  7. data/Dockerfile +1 -6
  8. data/README.md +118 -99
  9. data/aasm.gemspec +3 -0
  10. data/gemfiles/norails.gemfile +10 -0
  11. data/gemfiles/rails_5.0.gemfile +1 -1
  12. data/gemfiles/rails_5.1.gemfile +1 -1
  13. data/gemfiles/rails_5.2.gemfile +13 -0
  14. data/lib/aasm/aasm.rb +29 -27
  15. data/lib/aasm/base.rb +25 -7
  16. data/lib/aasm/core/event.rb +3 -3
  17. data/lib/aasm/instance_base.rb +15 -3
  18. data/lib/aasm/persistence/active_record_persistence.rb +10 -1
  19. data/lib/aasm/persistence/base.rb +1 -1
  20. data/lib/aasm/persistence/core_data_query_persistence.rb +2 -1
  21. data/lib/aasm/persistence/dynamoid_persistence.rb +1 -1
  22. data/lib/aasm/persistence/mongoid_persistence.rb +1 -1
  23. data/lib/aasm/persistence/no_brainer_persistence.rb +1 -1
  24. data/lib/aasm/persistence/orm.rb +23 -19
  25. data/lib/aasm/persistence/redis_persistence.rb +1 -1
  26. data/lib/aasm/rspec/transition_from.rb +5 -1
  27. data/lib/aasm/version.rb +1 -1
  28. data/spec/database.rb +8 -0
  29. data/spec/models/active_record/instance_level_skip_validation_example.rb +19 -0
  30. data/spec/models/active_record/person.rb +23 -0
  31. data/spec/models/callbacks/with_state_arg.rb +5 -1
  32. data/spec/models/callbacks/with_state_arg_multiple.rb +4 -1
  33. data/spec/models/simple_example.rb +6 -0
  34. data/spec/spec_helper.rb +10 -0
  35. data/spec/unit/abstract_class_spec.rb +27 -0
  36. data/spec/unit/callback_multiple_spec.rb +4 -0
  37. data/spec/unit/callbacks_spec.rb +4 -0
  38. data/spec/unit/complex_example_spec.rb +0 -1
  39. data/spec/unit/event_spec.rb +13 -0
  40. data/spec/unit/persistence/active_record_persistence_multiple_spec.rb +4 -4
  41. data/spec/unit/persistence/active_record_persistence_spec.rb +58 -4
  42. data/spec/unit/rspec_matcher_spec.rb +3 -0
  43. data/spec/unit/simple_example_spec.rb +15 -0
  44. metadata +54 -2
@@ -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
@@ -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
@@ -3,11 +3,17 @@ class SimpleExample
3
3
  aasm do
4
4
  state :initialised, :initial => true
5
5
  state :filled_out
6
+ state :denied
6
7
  state :authorised
7
8
 
8
9
  event :fill_out do
9
10
  transitions :from => :initialised, :to => :filled_out
10
11
  end
12
+
13
+ event :deny do
14
+ transitions from: :initialised, to: :denied
15
+ end
16
+
11
17
  event :authorise do
12
18
  transitions :from => :filled_out, :to => :authorised
13
19
  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
@@ -315,7 +315,9 @@ describe 'callbacks for the new DSL' do
315
315
  expect(cb).to receive(:before_method).with(:arg1).once.ordered
316
316
  expect(cb).to receive(:transition_method).with(:arg1).once.ordered
317
317
  expect(cb).to receive(:transition_method).never
318
+ expect(cb).to receive(:before_success_method).with(:arg1).once.ordered
318
319
  expect(cb).to receive(:success_method).with(:arg1).once.ordered
320
+ expect(cb).to receive(:success_method3).with(:arg1).once.ordered
319
321
  expect(cb).to receive(:success_method).never
320
322
  expect(cb).to receive(:after_method).with(:arg1).once.ordered
321
323
  cb.close!(:arg1)
@@ -325,7 +327,9 @@ describe 'callbacks for the new DSL' do
325
327
  expect(cb).to receive(:before_method).with(some_object).once.ordered
326
328
  expect(cb).to receive(:transition_method).with(some_object).once.ordered
327
329
  expect(cb).to receive(:transition_method).never
330
+ expect(cb).to receive(:before_success_method).with(some_object).once.ordered
328
331
  expect(cb).to receive(:success_method).with(some_object).once.ordered
332
+ expect(cb).to receive(:success_method3).with(some_object).once.ordered
329
333
  expect(cb).to receive(:success_method).never
330
334
  expect(cb).to receive(:after_method).with(some_object).once.ordered
331
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
 
@@ -613,6 +613,38 @@ if defined?(ActiveRecord)
613
613
  expect(validator).to be_running
614
614
  expect(validator.name).to eq("name")
615
615
  end
616
+
617
+ context "nested transaction" do
618
+ it "should fire :after_commit if root transaction was successful" do
619
+ validator = Validator.create(:name => 'name')
620
+ expect(validator).to be_sleeping
621
+
622
+ validator.transaction do
623
+ validator.run!
624
+ expect(validator.name).to eq("name")
625
+ expect(validator).to be_running
626
+ end
627
+
628
+ expect(validator.name).to eq("name changed")
629
+ expect(validator.reload).to be_running
630
+ end
631
+ end
632
+
633
+ it "should not fire :after_commit if root transaction failed" do
634
+ validator = Validator.create(:name => 'name')
635
+ expect(validator).to be_sleeping
636
+
637
+ validator.transaction do
638
+ validator.run!
639
+ expect(validator.name).to eq("name")
640
+ expect(validator).to be_running
641
+
642
+ raise ActiveRecord::Rollback, "failed on purpose"
643
+ end
644
+
645
+ expect(validator.name).to eq("name")
646
+ expect(validator.reload).to be_sleeping
647
+ end
616
648
  end
617
649
 
618
650
  describe 'before and after transaction callbacks' do
@@ -748,4 +780,26 @@ if defined?(ActiveRecord)
748
780
  expect { job.run }.to raise_error(AASM::InvalidTransition)
749
781
  end
750
782
  end
783
+
784
+ describe 'testing the instance_level skip validation with _without_validation method' do
785
+ let(:example) do
786
+ obj = InstanceLevelSkipValidationExample.new(state: 'new')
787
+ obj.save(validate: false)
788
+ obj
789
+ end
790
+
791
+ it 'should be able to change the state with invalid record' do
792
+ expect(example.valid?).to be_falsey
793
+ expect(example.complete!).to be_falsey
794
+ expect(example.complete_without_validation!).to be_truthy
795
+ expect(example.state).to eq('complete')
796
+ end
797
+
798
+ it 'shouldn\'t affect the behaviour of existing method after calling _without_validation! method' do
799
+ expect(example.set_draft!).to be_falsey
800
+ expect(example.set_draft_without_validation!).to be_truthy
801
+ expect(example.state).to eq('draft')
802
+ expect(example.complete!).to be_falsey
803
+ end
804
+ end
751
805
  end
@@ -8,14 +8,17 @@ describe 'state machine' do
8
8
  it "works for simple state machines" do
9
9
  expect(simple).to transition_from(:initialised).to(:filled_out).on_event(:fill_out)
10
10
  expect(simple).to_not transition_from(:initialised).to(:authorised).on_event(:fill_out)
11
+ expect(simple).to_not transition_from(:authorised).to(:filled_out).on_event(:fill_out)
11
12
  end
12
13
 
13
14
  it "works for multiple state machines" do
14
15
  expect(multiple).to transition_from(:standing).to(:walking).on_event(:walk).on(:move)
15
16
  expect(multiple).to_not transition_from(:standing).to(:running).on_event(:walk).on(:move)
17
+ expect(multiple).to_not transition_from(:running).to(:walking).on_event(:walk).on(:move)
16
18
 
17
19
  expect(multiple).to transition_from(:sleeping).to(:processing).on_event(:start).on(:work)
18
20
  expect(multiple).to_not transition_from(:sleeping).to(:sleeping).on_event(:start).on(:work)
21
+ expect(multiple).to_not transition_from(:processing).to(:sleeping).on_event(:start).on(:work)
19
22
  end
20
23
  end
21
24
 
@@ -23,6 +23,21 @@ describe 'state machine' do
23
23
  expect(simple).to be_authorised
24
24
  end
25
25
 
26
+ it 'shows the permitted transitions' do
27
+ expect(simple.aasm.permitted_transitions).to eq(
28
+ [
29
+ { event: :fill_out, state: :filled_out },
30
+ { event: :deny, state: :denied }
31
+ ]
32
+ )
33
+
34
+ simple.fill_out!
35
+ expect(simple.aasm.permitted_transitions).to eq([{ event: :authorise, state: :authorised }])
36
+
37
+ simple.authorise
38
+ expect(simple.aasm.permitted_transitions).to eq([])
39
+ end
40
+
26
41
  it 'denies transitions to other states' do
27
42
  expect {simple.authorise}.to raise_error(AASM::InvalidTransition)
28
43
  expect {simple.authorise!}.to raise_error(AASM::InvalidTransition)
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.2
4
+ version: 5.0.7
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: 2019-03-08 00:00:00.000000000 Z
12
+ date: 2020-03-04 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: concurrent-ruby
@@ -25,6 +25,20 @@ dependencies:
25
25
  - - "~>"
26
26
  - !ruby/object:Gem::Version
27
27
  version: '1.0'
28
+ - !ruby/object:Gem::Dependency
29
+ name: after_commit_action
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - "~>"
33
+ - !ruby/object:Gem::Version
34
+ version: '1.0'
35
+ type: :runtime
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - "~>"
40
+ - !ruby/object:Gem::Version
41
+ version: '1.0'
28
42
  - !ruby/object:Gem::Dependency
29
43
  name: rake
30
44
  requirement: !ruby/object:Gem::Requirement
@@ -95,6 +109,34 @@ dependencies:
95
109
  - - ">="
96
110
  - !ruby/object:Gem::Version
97
111
  version: '0'
112
+ - !ruby/object:Gem::Dependency
113
+ name: simplecov
114
+ requirement: !ruby/object:Gem::Requirement
115
+ requirements:
116
+ - - ">="
117
+ - !ruby/object:Gem::Version
118
+ version: '0'
119
+ type: :development
120
+ prerelease: false
121
+ version_requirements: !ruby/object:Gem::Requirement
122
+ requirements:
123
+ - - ">="
124
+ - !ruby/object:Gem::Version
125
+ version: '0'
126
+ - !ruby/object:Gem::Dependency
127
+ name: codecov
128
+ requirement: !ruby/object:Gem::Requirement
129
+ requirements:
130
+ - - ">="
131
+ - !ruby/object:Gem::Version
132
+ version: 0.1.10
133
+ type: :development
134
+ prerelease: false
135
+ version_requirements: !ruby/object:Gem::Requirement
136
+ requirements:
137
+ - - ">="
138
+ - !ruby/object:Gem::Version
139
+ version: 0.1.10
98
140
  - !ruby/object:Gem::Dependency
99
141
  name: pry
100
142
  requirement: !ruby/object:Gem::Requirement
@@ -117,6 +159,8 @@ extensions: []
117
159
  extra_rdoc_files: []
118
160
  files:
119
161
  - ".document"
162
+ - ".github/ISSUE_TEMPLATE/bug_report.md"
163
+ - ".github/ISSUE_TEMPLATE/feature_request.md"
120
164
  - ".gitignore"
121
165
  - ".travis.yml"
122
166
  - API
@@ -137,6 +181,7 @@ files:
137
181
  - aasm.gemspec
138
182
  - callbacks.txt
139
183
  - docker-compose.yml
184
+ - gemfiles/norails.gemfile
140
185
  - gemfiles/rails_3.2.gemfile
141
186
  - gemfiles/rails_4.2.gemfile
142
187
  - gemfiles/rails_4.2_mongoid_5.gemfile
@@ -144,6 +189,7 @@ files:
144
189
  - gemfiles/rails_5.0.gemfile
145
190
  - gemfiles/rails_5.0_nobrainer.gemfile
146
191
  - gemfiles/rails_5.1.gemfile
192
+ - gemfiles/rails_5.2.gemfile
147
193
  - lib/aasm.rb
148
194
  - lib/aasm/aasm.rb
149
195
  - lib/aasm/base.rb
@@ -205,11 +251,13 @@ files:
205
251
  - spec/models/active_record/derivate_new_dsl.rb
206
252
  - spec/models/active_record/false_state.rb
207
253
  - spec/models/active_record/gate.rb
254
+ - spec/models/active_record/instance_level_skip_validation_example.rb
208
255
  - spec/models/active_record/invalid_persistor.rb
209
256
  - spec/models/active_record/localizer_test_model.rb
210
257
  - spec/models/active_record/no_direct_assignment.rb
211
258
  - spec/models/active_record/no_scope.rb
212
259
  - spec/models/active_record/persisted_state.rb
260
+ - spec/models/active_record/person.rb
213
261
  - spec/models/active_record/provided_and_persisted_state.rb
214
262
  - spec/models/active_record/reader.rb
215
263
  - spec/models/active_record/readme_job.rb
@@ -312,6 +360,7 @@ files:
312
360
  - spec/spec_helpers/redis.rb
313
361
  - spec/spec_helpers/remove_warnings.rb
314
362
  - spec/spec_helpers/sequel.rb
363
+ - spec/unit/abstract_class_spec.rb
315
364
  - spec/unit/api_spec.rb
316
365
  - spec/unit/basic_two_state_machines_example_spec.rb
317
366
  - spec/unit/callback_multiple_spec.rb
@@ -406,11 +455,13 @@ test_files:
406
455
  - spec/models/active_record/derivate_new_dsl.rb
407
456
  - spec/models/active_record/false_state.rb
408
457
  - spec/models/active_record/gate.rb
458
+ - spec/models/active_record/instance_level_skip_validation_example.rb
409
459
  - spec/models/active_record/invalid_persistor.rb
410
460
  - spec/models/active_record/localizer_test_model.rb
411
461
  - spec/models/active_record/no_direct_assignment.rb
412
462
  - spec/models/active_record/no_scope.rb
413
463
  - spec/models/active_record/persisted_state.rb
464
+ - spec/models/active_record/person.rb
414
465
  - spec/models/active_record/provided_and_persisted_state.rb
415
466
  - spec/models/active_record/reader.rb
416
467
  - spec/models/active_record/readme_job.rb
@@ -513,6 +564,7 @@ test_files:
513
564
  - spec/spec_helpers/redis.rb
514
565
  - spec/spec_helpers/remove_warnings.rb
515
566
  - spec/spec_helpers/sequel.rb
567
+ - spec/unit/abstract_class_spec.rb
516
568
  - spec/unit/api_spec.rb
517
569
  - spec/unit/basic_two_state_machines_example_spec.rb
518
570
  - spec/unit/callback_multiple_spec.rb