aasm 4.2.0 → 4.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (97) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +4 -1
  3. data/Gemfile +2 -2
  4. data/PLANNED_CHANGES.md +24 -4
  5. data/README.md +75 -5
  6. data/lib/aasm/aasm.rb +50 -36
  7. data/lib/aasm/base.rb +36 -18
  8. data/lib/aasm/core/event.rb +6 -5
  9. data/lib/aasm/core/state.rb +3 -2
  10. data/lib/aasm/core/transition.rb +5 -4
  11. data/lib/aasm/errors.rb +7 -4
  12. data/lib/aasm/instance_base.rb +14 -13
  13. data/lib/aasm/localizer.rb +1 -1
  14. data/lib/aasm/persistence/active_record_persistence.rb +41 -66
  15. data/lib/aasm/persistence/base.rb +7 -7
  16. data/lib/aasm/persistence/mongo_mapper_persistence.rb +34 -51
  17. data/lib/aasm/persistence/mongoid_persistence.rb +15 -36
  18. data/lib/aasm/persistence/plain_persistence.rb +8 -7
  19. data/lib/aasm/persistence/sequel_persistence.rb +12 -10
  20. data/lib/aasm/state_machine.rb +11 -6
  21. data/lib/aasm/version.rb +1 -1
  22. data/spec/database.rb +27 -1
  23. data/spec/models/active_record/basic_active_record_two_state_machines_example.rb +25 -0
  24. data/spec/models/active_record/complex_active_record_example.rb +33 -0
  25. data/spec/models/active_record/derivate_new_dsl.rb +4 -0
  26. data/spec/models/active_record/false_state.rb +18 -0
  27. data/spec/models/active_record/gate.rb +20 -0
  28. data/spec/models/active_record/no_direct_assignment.rb +11 -0
  29. data/spec/models/active_record/no_scope.rb +11 -0
  30. data/spec/models/active_record/provided_and_persisted_state.rb +3 -3
  31. data/spec/models/active_record/simple_new_dsl.rb +9 -0
  32. data/spec/models/active_record/thief.rb +15 -0
  33. data/spec/models/active_record/with_enum.rb +20 -0
  34. data/spec/models/active_record/with_false_enum.rb +16 -0
  35. data/spec/models/active_record/with_true_enum.rb +20 -0
  36. data/spec/models/basic_two_state_machines_example.rb +25 -0
  37. data/spec/models/callbacks/basic_multiple.rb +75 -0
  38. data/spec/models/callbacks/guard_within_block_multiple.rb +66 -0
  39. data/spec/models/callbacks/multiple_transitions_transition_guard_multiple.rb +65 -0
  40. data/spec/models/callbacks/private_method_multiple.rb +44 -0
  41. data/spec/models/callbacks/with_args_multiple.rb +61 -0
  42. data/spec/models/callbacks/{with_state_args.rb → with_state_arg.rb} +0 -0
  43. data/spec/models/callbacks/with_state_arg_multiple.rb +26 -0
  44. data/spec/models/complex_example.rb +134 -0
  45. data/spec/models/conversation.rb +47 -1
  46. data/spec/models/foo.rb +57 -0
  47. data/spec/models/foo_callback_multiple.rb +45 -0
  48. data/spec/models/guardian_multiple.rb +48 -0
  49. data/spec/models/initial_state_proc.rb +16 -0
  50. data/spec/models/invalid_persistor.rb +15 -0
  51. data/spec/models/mongo_mapper/complex_mongo_mapper_example.rb +37 -0
  52. data/spec/models/mongo_mapper/no_scope_mongo_mapper.rb +11 -0
  53. data/spec/models/mongo_mapper/simple_mongo_mapper.rb +12 -0
  54. data/spec/models/mongo_mapper/simple_new_dsl_mongo_mapper.rb +13 -0
  55. data/spec/models/mongoid/complex_mongoid_example.rb +37 -0
  56. data/spec/models/mongoid/no_scope_mongoid.rb +11 -0
  57. data/spec/models/mongoid/simple_mongoid.rb +12 -0
  58. data/spec/models/mongoid/simple_new_dsl_mongoid.rb +13 -0
  59. data/spec/models/no_initial_state.rb +13 -0
  60. data/spec/models/parametrised_event.rb +1 -1
  61. data/spec/models/parametrised_event_multiple.rb +29 -0
  62. data/spec/models/provided_state.rb +3 -3
  63. data/spec/models/sequel/complex_sequel_example.rb +45 -0
  64. data/spec/models/sequel/sequel_multiple.rb +25 -0
  65. data/spec/models/sequel/sequel_simple.rb +25 -0
  66. data/spec/models/simple_multiple_example.rb +30 -0
  67. data/spec/models/sub_class.rb +4 -0
  68. data/spec/models/sub_class_with_more_states.rb +11 -0
  69. data/spec/models/super_class.rb +28 -0
  70. data/spec/models/transactor.rb +27 -0
  71. data/spec/models/valid_state_name.rb +12 -0
  72. data/spec/models/validator.rb +39 -0
  73. data/spec/unit/basic_two_state_machines_example_spec.rb +10 -0
  74. data/spec/unit/callback_multiple_spec.rb +295 -0
  75. data/spec/unit/callbacks_spec.rb +1 -1
  76. data/spec/unit/complex_multiple_example_spec.rb +99 -0
  77. data/spec/unit/edge_cases_spec.rb +16 -0
  78. data/spec/unit/event_multiple_spec.rb +73 -0
  79. data/spec/unit/event_spec.rb +11 -6
  80. data/spec/unit/guard_multiple_spec.rb +60 -0
  81. data/spec/unit/initial_state_multiple_spec.rb +15 -0
  82. data/spec/unit/inspection_multiple_spec.rb +201 -0
  83. data/spec/unit/persistence/active_record_persistence_multiple_spec.rb +560 -0
  84. data/spec/unit/persistence/active_record_persistence_spec.rb +17 -12
  85. data/spec/unit/persistence/mongo_mapper_persistence_multiple_spec.rb +146 -0
  86. data/spec/unit/persistence/{mongo_mapper_persistance_spec.rb → mongo_mapper_persistence_spec.rb} +7 -49
  87. data/spec/unit/persistence/mongoid_persistence_multiple_spec.rb +127 -0
  88. data/spec/unit/persistence/mongoid_persistence_spec.rb +79 -0
  89. data/spec/unit/persistence/sequel_persistence_multiple_spec.rb +153 -0
  90. data/spec/unit/persistence/sequel_persistence_spec.rb +7 -24
  91. data/spec/unit/reloading_spec.rb +1 -1
  92. data/spec/unit/simple_multiple_example_spec.rb +63 -0
  93. data/spec/unit/state_spec.rb +3 -1
  94. data/spec/unit/subclassing_multiple_spec.rb +39 -0
  95. data/spec/unit/transition_spec.rb +31 -22
  96. metadata +73 -9
  97. data/spec/unit/persistence/mongoid_persistance_spec.rb +0 -146
@@ -9,3 +9,15 @@ class SimpleMongoMapper
9
9
  state :next
10
10
  end
11
11
  end
12
+
13
+ class SimpleMongoMapperMultiple
14
+ include MongoMapper::Document
15
+ include AASM
16
+
17
+ key :status, String
18
+
19
+ aasm :left, column: :status do
20
+ state :unknown_scope
21
+ state :next
22
+ end
23
+ end
@@ -10,3 +10,16 @@ class SimpleNewDslMongoMapper
10
10
  state :next
11
11
  end
12
12
  end
13
+
14
+ class SimpleNewDslMongoMapperMultiple
15
+ include MongoMapper::Document
16
+ include AASM
17
+
18
+ key :status, String
19
+
20
+ aasm :left, :column => :status
21
+ aasm :left do
22
+ state :unknown_scope
23
+ state :next
24
+ end
25
+ end
@@ -0,0 +1,37 @@
1
+ class ComplexMongoidExample
2
+ include Mongoid::Document
3
+ include AASM
4
+
5
+ field :left, :type => String
6
+ field :right, :type => String
7
+
8
+ aasm :left, :column => 'left' do
9
+ state :one, :initial => true
10
+ state :two
11
+ state :three
12
+
13
+ event :increment do
14
+ transitions :from => :one, :to => :two
15
+ transitions :from => :two, :to => :three
16
+ end
17
+ event :reset do
18
+ transitions :from => :three, :to => :one
19
+ end
20
+ end
21
+
22
+ aasm :right, :column => 'right' do
23
+ state :alpha, :initial => true
24
+ state :beta
25
+ state :gamma
26
+
27
+ event :level_up do
28
+ transitions :from => :alpha, :to => :beta
29
+ transitions :from => :beta, :to => :gamma
30
+ end
31
+ event :level_down do
32
+ transitions :from => :gamma, :to => :beta
33
+ transitions :from => :beta, :to => :alpha
34
+ end
35
+ end
36
+
37
+ end
@@ -8,3 +8,14 @@ class NoScopeMongoid
8
8
  state :ignored_scope
9
9
  end
10
10
  end
11
+
12
+ class NoScopeMongoidMultiple
13
+ include Mongoid::Document
14
+ include AASM
15
+
16
+ field :status, :type => String
17
+
18
+ aasm :left, :create_scopes => false, :column => :status do
19
+ state :ignored_scope
20
+ end
21
+ end
@@ -9,3 +9,15 @@ class SimpleMongoid
9
9
  state :new
10
10
  end
11
11
  end
12
+
13
+ class SimpleMongoidMultiple
14
+ include Mongoid::Document
15
+ include AASM
16
+
17
+ field :status, :type => String
18
+
19
+ aasm :left, column: :status do
20
+ state :unknown_scope
21
+ state :new
22
+ end
23
+ end
@@ -10,3 +10,16 @@ class SimpleNewDslMongoid
10
10
  state :new
11
11
  end
12
12
  end
13
+
14
+ class SimpleNewDslMongoidMultiple
15
+ include Mongoid::Document
16
+ include AASM
17
+
18
+ field :status, :type => String
19
+
20
+ aasm :left, :column => :status
21
+ aasm :left do
22
+ state :unknown_scope, :initial => true
23
+ state :new
24
+ end
25
+ end
@@ -10,3 +10,16 @@ class NoInitialState
10
10
  end
11
11
  end
12
12
  end
13
+
14
+ class NoInitialStateMultiple
15
+ include AASM
16
+
17
+ aasm(:left) do
18
+ state :read
19
+ state :ended
20
+
21
+ event :foo do
22
+ transitions :to => :ended, :from => [:read]
23
+ end
24
+ end
25
+ end
@@ -18,7 +18,7 @@ class ParametrisedEvent
18
18
  end
19
19
  end
20
20
 
21
- def wear_clothes(shirt_color, trouser_type)
21
+ def wear_clothes(shirt_color, trouser_type=nil)
22
22
  end
23
23
 
24
24
  def condition_hair
@@ -0,0 +1,29 @@
1
+ class ParametrisedEventMultiple
2
+ include AASM
3
+ aasm(:left) do
4
+ state :sleeping, :initial => true
5
+ state :showering
6
+ state :working
7
+ state :dating
8
+ state :prettying_up
9
+
10
+ event :wakeup do
11
+ transitions :from => :sleeping, :to => [:showering, :working]
12
+ end
13
+
14
+ event :dress do
15
+ transitions :from => :sleeping, :to => :working, :after => :wear_clothes
16
+ transitions :from => :showering, :to => [:working, :dating], :after => Proc.new { |*args| wear_clothes(*args) }
17
+ transitions :from => :showering, :to => :prettying_up, :after => [:condition_hair, :fix_hair]
18
+ end
19
+ end
20
+
21
+ def wear_clothes(shirt_color, trouser_type=nil)
22
+ end
23
+
24
+ def condition_hair
25
+ end
26
+
27
+ def fix_hair
28
+ end
29
+ end
@@ -10,15 +10,15 @@ class ProvidedState
10
10
  end
11
11
  end
12
12
 
13
- def aasm_read_state
13
+ def aasm_read_state(*args)
14
14
  :beta
15
15
  end
16
16
 
17
- def aasm_write_state(new_state)
17
+ def aasm_write_state(new_state, *args)
18
18
  @persisted_store = new_state
19
19
  end
20
20
 
21
- def aasm_write_state_without_persistence(new_state)
21
+ def aasm_write_state_without_persistence(new_state, *args)
22
22
  @transient_store = new_state
23
23
  end
24
24
  end
@@ -0,0 +1,45 @@
1
+ db = Sequel.connect(SEQUEL_DB)
2
+
3
+ # if you want to see the statements while running the spec enable the following line
4
+ # db.loggers << Logger.new($stderr)
5
+ db.create_table(:complex_sequel_examples) do
6
+ primary_key :id
7
+ String :left
8
+ String :right
9
+ end
10
+
11
+ class ComplexSequelExample < Sequel::Model(db)
12
+ set_dataset(:complex_sequel_examples)
13
+
14
+ include AASM
15
+
16
+ aasm :left, :column => 'left' do
17
+ state :one, :initial => true
18
+ state :two
19
+ state :three
20
+
21
+ event :increment do
22
+ transitions :from => :one, :to => :two
23
+ transitions :from => :two, :to => :three
24
+ end
25
+ event :reset do
26
+ transitions :from => :three, :to => :one
27
+ end
28
+ end
29
+
30
+ aasm :right, :column => 'right' do
31
+ state :alpha, :initial => true
32
+ state :beta
33
+ state :gamma
34
+
35
+ event :level_up do
36
+ transitions :from => :alpha, :to => :beta
37
+ transitions :from => :beta, :to => :gamma
38
+ end
39
+ event :level_down do
40
+ transitions :from => :gamma, :to => :beta
41
+ transitions :from => :beta, :to => :alpha
42
+ end
43
+ end
44
+
45
+ end
@@ -0,0 +1,25 @@
1
+ db = Sequel.connect(SEQUEL_DB)
2
+
3
+ # if you want to see the statements while running the spec enable the following line
4
+ # db.loggers << Logger.new($stderr)
5
+ db.create_table(:multiples) do
6
+ primary_key :id
7
+ String :status
8
+ end
9
+
10
+ class SequelMultiple < Sequel::Model(db)
11
+ set_dataset(:multiples)
12
+ include AASM
13
+
14
+ attr_accessor :default
15
+
16
+ aasm :left, :column => :status
17
+ aasm :left do
18
+ state :alpha, :initial => true
19
+ state :beta
20
+ state :gamma
21
+ event :release do
22
+ transitions :from => [:alpha, :beta, :gamma], :to => :beta
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,25 @@
1
+ db = Sequel.connect(SEQUEL_DB)
2
+
3
+ # if you want to see the statements while running the spec enable the following line
4
+ # db.loggers << Logger.new($stderr)
5
+ db.create_table(:simples) do
6
+ primary_key :id
7
+ String :status
8
+ end
9
+
10
+ class SequelSimple < Sequel::Model(db)
11
+ set_dataset(:simples)
12
+ include AASM
13
+
14
+ attr_accessor :default
15
+
16
+ aasm :column => :status
17
+ aasm do
18
+ state :alpha, :initial => true
19
+ state :beta
20
+ state :gamma
21
+ event :release do
22
+ transitions :from => [:alpha, :beta, :gamma], :to => :beta
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,30 @@
1
+ class SimpleMultipleExample
2
+ include AASM
3
+ aasm(:move) do
4
+ state :standing, :initial => true
5
+ state :walking
6
+ state :running
7
+
8
+ event :walk do
9
+ transitions :from => :standing, :to => :walking
10
+ end
11
+ event :run do
12
+ transitions :from => [:standing, :walking], :to => :running
13
+ end
14
+ event :hold do
15
+ transitions :from => [:walking, :running], :to => :standing
16
+ end
17
+ end
18
+
19
+ aasm(:work) do
20
+ state :sleeping, :initial => true
21
+ state :processing
22
+
23
+ event :start do
24
+ transitions :from => :sleeping, :to => :processing
25
+ end
26
+ event :stop do
27
+ transitions :from => :processing, :to => :sleeping
28
+ end
29
+ end
30
+ end
@@ -1,3 +1,7 @@
1
1
  require_relative 'super_class'
2
+
2
3
  class SubClass < SuperClass
3
4
  end
5
+
6
+ class SubClassMultiple < SuperClassMultiple
7
+ end
@@ -1,7 +1,18 @@
1
1
  require_relative 'super_class'
2
+
2
3
  class SubClassWithMoreStates < SuperClass
3
4
  include AASM
4
5
  aasm do
5
6
  state :foo
6
7
  end
7
8
  end
9
+
10
+ class SubClassWithMoreStatesMultiple < SuperClassMultiple
11
+ include AASM
12
+ aasm(:left) do
13
+ state :foo
14
+ end
15
+ aasm(:right) do
16
+ state :archived
17
+ end
18
+ end
@@ -16,3 +16,31 @@ class SuperClass
16
16
  end
17
17
  end
18
18
  end
19
+
20
+ class SuperClassMultiple
21
+ include AASM
22
+
23
+ aasm(:left) do
24
+ state :read
25
+ state :ended
26
+
27
+ event :foo do
28
+ transitions :to => :ended, :from => [:read]
29
+ end
30
+ end
31
+
32
+ aasm(:right) do
33
+ state :opened
34
+ state :closed
35
+
36
+ event :close do
37
+ transitions :to => :closed, :from => [:opened]
38
+ end
39
+ end
40
+
41
+ def update_state
42
+ if may_foo?
43
+ foo!
44
+ end
45
+ end
46
+ end
@@ -1,4 +1,5 @@
1
1
  require 'active_record'
2
+
2
3
  class Transactor < ActiveRecord::Base
3
4
 
4
5
  belongs_to :worker
@@ -24,3 +25,29 @@ private
24
25
  end
25
26
 
26
27
  end
28
+
29
+ class MultipleTransactor < ActiveRecord::Base
30
+
31
+ belongs_to :worker
32
+
33
+ include AASM
34
+ aasm :left, :column => :status do
35
+ state :sleeping, :initial => true
36
+ state :running, :before_enter => :start_worker, :after_enter => :fail
37
+
38
+ event :run do
39
+ transitions :to => :running, :from => :sleeping
40
+ end
41
+ end
42
+
43
+ private
44
+
45
+ def start_worker
46
+ worker.update_attribute(:status, 'running')
47
+ end
48
+
49
+ def fail
50
+ raise StandardError.new('failed on purpose')
51
+ end
52
+
53
+ end
@@ -9,3 +9,15 @@ class ValidStateName
9
9
  end
10
10
  end
11
11
  end
12
+
13
+ class ValidStateNameMultiple
14
+ include AASM
15
+ aasm(:left) do
16
+ state :invalid, :initial => true
17
+ state :valid
18
+
19
+ event :valid do
20
+ transitions :to => :valid, :from => [:invalid]
21
+ end
22
+ end
23
+ end
@@ -38,3 +38,42 @@ class Validator < ActiveRecord::Base
38
38
  raise StandardError.new('failed on purpose')
39
39
  end
40
40
  end
41
+
42
+ class MultipleValidator < ActiveRecord::Base
43
+
44
+ include AASM
45
+ aasm :left, :column => :status do
46
+ state :sleeping, :initial => true
47
+ state :running
48
+ state :failed, :after_enter => :fail
49
+
50
+ event :run, :after_commit => :change_name! do
51
+ transitions :to => :running, :from => :sleeping
52
+ end
53
+ event :sleep do
54
+ after_commit do |name|
55
+ change_name_on_sleep name
56
+ end
57
+ transitions :to => :sleeping, :from => :running
58
+ end
59
+ event :fail do
60
+ transitions :to => :failed, :from => [:sleeping, :running]
61
+ end
62
+ end
63
+
64
+ validates_presence_of :name
65
+
66
+ def change_name!
67
+ self.name = "name changed"
68
+ save!
69
+ end
70
+
71
+ def change_name_on_sleep name
72
+ self.name = name
73
+ save!
74
+ end
75
+
76
+ def fail
77
+ raise StandardError.new('failed on purpose')
78
+ end
79
+ end