aasm 4.2.0 → 4.3.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 (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
@@ -12,3 +12,18 @@ class Thief < ActiveRecord::Base
12
12
  end
13
13
  attr_accessor :skilled, :aasm_state
14
14
  end
15
+
16
+ class MultipleThief < ActiveRecord::Base
17
+ if ActiveRecord::VERSION::MAJOR >= 3
18
+ self.table_name = 'multiple_thieves'
19
+ else
20
+ set_table_name "multiple_thieves"
21
+ end
22
+ include AASM
23
+ aasm :left, :column => :aasm_state do
24
+ state :rich
25
+ state :jailed
26
+ initial_state Proc.new {|thief| thief.skilled ? :rich : :jailed }
27
+ end
28
+ attr_accessor :skilled, :aasm_state
29
+ end
@@ -17,3 +17,23 @@ class WithEnum < ActiveRecord::Base
17
17
  end
18
18
  end
19
19
  end
20
+
21
+ class MultipleWithEnum < ActiveRecord::Base
22
+ include AASM
23
+
24
+ # Fake this column for testing purposes
25
+ attr_accessor :aasm_state
26
+
27
+ def self.test
28
+ {}
29
+ end
30
+
31
+ aasm :left, :enum => :test do
32
+ state :opened
33
+ state :closed
34
+
35
+ event :view do
36
+ transitions :to => :read, :from => [:needs_attention]
37
+ end
38
+ end
39
+ end
@@ -13,3 +13,19 @@ class WithFalseEnum < ActiveRecord::Base
13
13
  end
14
14
  end
15
15
  end
16
+
17
+ class MultipleWithFalseEnum < ActiveRecord::Base
18
+ include AASM
19
+
20
+ # Fake this column for testing purposes
21
+ attr_accessor :aasm_state
22
+
23
+ aasm :left, :enum => false do
24
+ state :opened
25
+ state :closed
26
+
27
+ event :view do
28
+ transitions :to => :read, :from => [:needs_attention]
29
+ end
30
+ end
31
+ end
@@ -17,3 +17,23 @@ class WithTrueEnum < ActiveRecord::Base
17
17
  end
18
18
  end
19
19
  end
20
+
21
+ class MultipleWithTrueEnum < ActiveRecord::Base
22
+ include AASM
23
+
24
+ # Fake this column for testing purposes
25
+ attr_accessor :aasm_state
26
+
27
+ def value
28
+ 'value'
29
+ end
30
+
31
+ aasm :left, :enum => true do
32
+ state :opened
33
+ state :closed
34
+
35
+ event :view do
36
+ transitions :to => :read, :from => [:needs_attention]
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,25 @@
1
+ class BasicTwoStateMachinesExample
2
+ include AASM
3
+
4
+ aasm :search do
5
+ state :initialised, :initial => true
6
+ state :queried
7
+ state :requested
8
+
9
+ event :query do
10
+ transitions :from => [:initialised, :requested], :to => :queried
11
+ end
12
+ event :request do
13
+ transitions :from => :queried, :to => :requested
14
+ end
15
+ end
16
+
17
+ aasm :sync do
18
+ state :unsynced, :initial => true
19
+ state :synced
20
+
21
+ event :sync do
22
+ transitions :from => :unsynced, :to => :synced
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,75 @@
1
+ module Callbacks
2
+ class BasicMultiple
3
+ include AASM
4
+
5
+ def initialize(options={})
6
+ @fail_event_guard = options[:fail_event_guard]
7
+ @fail_transition_guard = options[:fail_transition_guard]
8
+ @log = options[:log]
9
+ reset_data
10
+ end
11
+
12
+ def reset_data
13
+ @data = []
14
+ end
15
+
16
+ def data
17
+ @data.join(' ')
18
+ end
19
+
20
+ aasm(:left) do
21
+ state :open, :initial => true,
22
+ :before_enter => :before_enter_open,
23
+ :enter => :enter_open,
24
+ :after_enter => :after_enter_open,
25
+ :before_exit => :before_exit_open,
26
+ :exit => :exit_open,
27
+ :after_exit => :after_exit_open
28
+
29
+ state :closed,
30
+ :before_enter => :before_enter_closed,
31
+ :enter => :enter_closed,
32
+ :after_enter => :after_enter_closed,
33
+ :before_exit => :before_exit_closed,
34
+ :exit => :exit_closed,
35
+ :after_exit => :after_exit_closed
36
+
37
+ event :left_close, :before => :before_event, :after => :after_event, :guard => :event_guard do
38
+ transitions :to => :closed, :from => [:open], :guard => :transition_guard, :after => :after_transition
39
+ end
40
+
41
+ event :left_open, :before => :before_event, :after => :after_event do
42
+ transitions :to => :open, :from => :closed
43
+ end
44
+ end
45
+
46
+ def log(text)
47
+ @data << text
48
+ puts text if @log
49
+ end
50
+
51
+ def aasm_write_state(*args); log("aasm_write_state(#{args.inspect})"); true; end
52
+
53
+ def before_enter_open; log('before_enter_open'); end
54
+ def enter_open; log('enter_open'); end
55
+ def before_exit_open; log('before_exit_open'); end
56
+ def after_enter_open; log('after_enter_open'); end
57
+ def exit_open; log('exit_open'); end
58
+ def after_exit_open; log('after_exit_open'); end
59
+
60
+ def before_enter_closed; log('before_enter_closed'); end
61
+ def enter_closed; log('enter_closed'); end
62
+ def before_exit_closed; log('before_exit_closed'); end
63
+ def exit_closed; log('exit_closed'); end
64
+ def after_enter_closed; log('after_enter_closed'); end
65
+ def after_exit_closed; log('after_exit_closed'); end
66
+
67
+ def event_guard; log('event_guard'); !@fail_event_guard; end
68
+ def transition_guard; log('transition_guard'); !@fail_transition_guard; end
69
+
70
+ def after_transition; log('after_transition'); end
71
+
72
+ def before_event; log('before_event'); end
73
+ def after_event; log('after_event'); end
74
+ end
75
+ end
@@ -0,0 +1,66 @@
1
+ module Callbacks
2
+ class GuardWithinBlockMultiple
3
+ include AASM
4
+
5
+ def initialize(options={})
6
+ @fail_event_guard = options[:fail_event_guard]
7
+ @fail_transition_guard = options[:fail_transition_guard]
8
+ @log = options[:log]
9
+ end
10
+
11
+ aasm(:left) do
12
+ state :open, :initial => true,
13
+ :before_enter => :before_enter_open,
14
+ :enter => :enter_open,
15
+ :after_enter => :after_enter_open,
16
+ :before_exit => :before_exit_open,
17
+ :exit => :exit_open,
18
+ :after_exit => :after_exit_open
19
+
20
+ state :closed,
21
+ :before_enter => :before_enter_closed,
22
+ :enter => :enter_closed,
23
+ :after_enter => :after_enter_closed,
24
+ :before_exit => :before_exit_closed,
25
+ :exit => :exit_closed,
26
+ :after_exit => :after_exit_closed
27
+
28
+ event :close, :before => :before, :after => :after, :guard => :event_guard do
29
+ transitions :to => :closed, :from => [:open], :after => :transitioning do
30
+ guard do
31
+ transition_guard
32
+ end
33
+ end
34
+ end
35
+
36
+ event :open, :before => :before, :after => :after do
37
+ transitions :to => :open, :from => :closed
38
+ end
39
+ end
40
+
41
+ def log(text)
42
+ puts text if @log
43
+ end
44
+
45
+ def before_enter_open; log('before_enter_open'); end
46
+ def enter_open; log('enter_open'); end
47
+ def before_exit_open; log('before_exit_open'); end
48
+ def after_enter_open; log('after_enter_open'); end
49
+ def exit_open; log('exit_open'); end
50
+ def after_exit_open; log('after_exit_open'); end
51
+
52
+ def before_enter_closed; log('before_enter_closed'); end
53
+ def enter_closed; log('enter_closed'); end
54
+ def before_exit_closed; log('before_exit_closed'); end
55
+ def exit_closed; log('exit_closed'); end
56
+ def after_enter_closed; log('after_enter_closed'); end
57
+ def after_exit_closed; log('after_exit_closed'); end
58
+
59
+ def event_guard; log('event_guard'); !@fail_event_guard; end
60
+ def transition_guard; log('transition_guard'); !@fail_transition_guard; end
61
+ def transitioning; log('transitioning'); end
62
+
63
+ def before; log('before'); end
64
+ def after; log('after'); end
65
+ end
66
+ end
@@ -0,0 +1,65 @@
1
+ module Callbacks
2
+ class MultipleTransitionsTransitionGuardMultiple
3
+ include AASM
4
+
5
+ def initialize(options={})
6
+ @fail_event_guard = options[:fail_event_guard]
7
+ @fail_transition_guard = options[:fail_transition_guard]
8
+ @log = options[:log]
9
+ end
10
+
11
+ aasm(:left) do
12
+ state :open, :initial => true,
13
+ :before_enter => :before_enter_open,
14
+ :enter => :enter_open,
15
+ :after_enter => :after_enter_open,
16
+ :before_exit => :before_exit_open,
17
+ :exit => :exit_open,
18
+ :after_exit => :after_exit_open
19
+
20
+ state :closed,
21
+ :before_enter => :before_enter_closed,
22
+ :enter => :enter_closed,
23
+ :after_enter => :after_enter_closed,
24
+ :before_exit => :before_exit_closed,
25
+ :exit => :exit_closed,
26
+ :after_exit => :after_exit_closed
27
+
28
+ state :failed
29
+
30
+ event :close, :before => :before, :after => :after, :guard => :event_guard do
31
+ transitions :to => :closed, :from => [:open], :guard => :transition_guard, :after => :transitioning
32
+ transitions :to => :failed, :from => [:open]
33
+ end
34
+
35
+ event :open, :before => :before, :after => :after do
36
+ transitions :to => :open, :from => :closed
37
+ end
38
+ end
39
+
40
+ def log(text)
41
+ puts text if @log
42
+ end
43
+
44
+ def before_enter_open; log('before_enter_open'); end
45
+ def enter_open; log('enter_open'); end
46
+ def before_exit_open; log('before_exit_open'); end
47
+ def after_enter_open; log('after_enter_open'); end
48
+ def exit_open; log('exit_open'); end
49
+ def after_exit_open; log('after_exit_open'); end
50
+
51
+ def before_enter_closed; log('before_enter_closed'); end
52
+ def enter_closed; log('enter_closed'); end
53
+ def before_exit_closed; log('before_exit_closed'); end
54
+ def exit_closed; log('exit_closed'); end
55
+ def after_enter_closed; log('after_enter_closed'); end
56
+ def after_exit_closed; log('after_exit_closed'); end
57
+
58
+ def event_guard; log('event_guard'); !@fail_event_guard; end
59
+ def transition_guard; log('transition_guard'); !@fail_transition_guard; end
60
+ def transitioning; log('transitioning'); end
61
+
62
+ def before; log('before'); end
63
+ def after; log('after'); end
64
+ end
65
+ end
@@ -0,0 +1,44 @@
1
+ module Callbacks
2
+ class PrivateMethodMultiple
3
+ include AASM
4
+
5
+ def initialize(options={})
6
+ @fail_event_guard = options[:fail_event_guard]
7
+ @fail_transition_guard = options[:fail_transition_guard]
8
+ @log = options[:log]
9
+ reset_data
10
+ end
11
+
12
+ def reset_data
13
+ @data = []
14
+ end
15
+
16
+ def data
17
+ @data.join(' ')
18
+ end
19
+
20
+ aasm(:left) do
21
+ state :open, :initial => true
22
+ state :closed
23
+
24
+ event :close, :after => :after_event do
25
+ transitions :to => :closed, :from => [:open]
26
+ end
27
+
28
+ event :open, :after => :after_event do
29
+ transitions :to => :open, :from => :closed
30
+ end
31
+ end
32
+
33
+ def log(text)
34
+ @data << text
35
+ puts text if @log
36
+ end
37
+
38
+ def aasm_write_state(*args); log('aasm_write_state'); true; end
39
+
40
+ private
41
+
42
+ def after_event; log('after_event'); end
43
+ end
44
+ end
@@ -0,0 +1,61 @@
1
+ module Callbacks
2
+ class WithArgsMultiple
3
+ include AASM
4
+
5
+ def initialize(options={})
6
+ @log = options[:log]
7
+ reset_data
8
+ end
9
+
10
+ def reset_data
11
+ @data = []
12
+ end
13
+
14
+ def data
15
+ @data.join(' ')
16
+ end
17
+
18
+ aasm(:left) do
19
+ state :open, :initial => true,
20
+ :before_enter => :before_enter_open,
21
+ :after_enter => :after_enter_open,
22
+ :before_exit => :before_exit_open,
23
+ :after_exit => :after_exit_open
24
+
25
+ state :closed,
26
+ :before_enter => :before_enter_closed,
27
+ :after_enter => :after_enter_closed,
28
+ :before_exit => :before_exit_closed,
29
+ :after_exit => :after_exit_closed
30
+
31
+ event :close, :before => :before, :after => :after do
32
+ transitions :to => :closed, :from => [:open], :after => :transition_proc
33
+ end
34
+
35
+ event :open, :before => :before, :after => :after do
36
+ transitions :to => :open, :from => :closed
37
+ end
38
+ end
39
+
40
+ def log(text)
41
+ @data << text
42
+ puts text if @log
43
+ end
44
+
45
+ def aasm_write_state(*args); log('aasm_write_state'); true; end
46
+
47
+ def before_enter_open(*args); log("before_enter_open(#{args.map(&:inspect).join(',')})"); end
48
+ def before_exit_open(*args); log("before_exit_open(#{args.map(&:inspect).join(',')})"); end
49
+ def after_enter_open(*args); log("after_enter_open(#{args.map(&:inspect).join(',')})"); end
50
+ def after_exit_open(*args); log("after_exit_open(#{args.map(&:inspect).join(',')})"); end
51
+
52
+ def before_enter_closed(*args); log("before_enter_closed(#{args.map(&:inspect).join(',')})"); end
53
+ def before_exit_closed(*args); log("before_enter_closed(#{args.map(&:inspect).join(',')})"); end
54
+ def after_enter_closed(*args); log("after_enter_closed(#{args.map(&:inspect).join(',')})"); end
55
+ def after_exit_closed(*args); log("after_exit_closed(#{args.map(&:inspect).join(',')})"); end
56
+
57
+ def before(arg1, *args); log("before(#{arg1.inspect},#{args.map(&:inspect).join(',')})"); end
58
+ def transition_proc(arg1, arg2); log("transition_proc(#{arg1.inspect},#{arg2.inspect})"); end
59
+ def after(*args); log("after(#{args.map(&:inspect).join(',')})"); end
60
+ end
61
+ end
@@ -0,0 +1,26 @@
1
+ module Callbacks
2
+ class WithStateArgMultiple
3
+
4
+ include AASM
5
+
6
+ aasm(:left) do
7
+ state :open, :inital => true
8
+ state :closed
9
+ state :out_to_lunch
10
+
11
+ event :close, :before => :before_method, :after => :after_method do
12
+ transitions :to => :closed, :from => [:open], :after => :transition_method
13
+ transitions :to => :out_to_lunch, :from => [:open], :after => :transition_method2
14
+ end
15
+ end
16
+
17
+ def before_method(arg); end
18
+
19
+ def after_method(arg); end
20
+
21
+ def transition_method(arg); end
22
+
23
+ def transition_method2(arg); end
24
+
25
+ end
26
+ end