aasm 4.11.1 → 5.2.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 (194) hide show
  1. checksums.yaml +5 -5
  2. data/.github/ISSUE_TEMPLATE/bug_report.md +27 -0
  3. data/.github/ISSUE_TEMPLATE/feature_request.md +20 -0
  4. data/.travis.yml +56 -23
  5. data/Appraisals +67 -0
  6. data/CHANGELOG.md +112 -0
  7. data/CONTRIBUTING.md +24 -0
  8. data/Dockerfile +44 -0
  9. data/Gemfile +3 -21
  10. data/Gemfile.lock_old +151 -0
  11. data/LICENSE +1 -1
  12. data/README.md +540 -139
  13. data/Rakefile +6 -1
  14. data/TESTING.md +25 -0
  15. data/aasm.gemspec +5 -0
  16. data/docker-compose.yml +40 -0
  17. data/gemfiles/norails.gemfile +10 -0
  18. data/gemfiles/rails_4.2.gemfile +13 -11
  19. data/gemfiles/rails_4.2_mongoid_5.gemfile +8 -11
  20. data/gemfiles/rails_4.2_nobrainer.gemfile +9 -0
  21. data/gemfiles/rails_5.0.gemfile +11 -18
  22. data/gemfiles/rails_5.0_nobrainer.gemfile +9 -0
  23. data/gemfiles/rails_5.1.gemfile +14 -0
  24. data/gemfiles/rails_5.2.gemfile +14 -0
  25. data/lib/aasm/aasm.rb +40 -29
  26. data/lib/aasm/base.rb +61 -11
  27. data/lib/aasm/configuration.rb +10 -0
  28. data/lib/aasm/core/event.rb +45 -37
  29. data/lib/aasm/core/invoker.rb +129 -0
  30. data/lib/aasm/core/invokers/base_invoker.rb +75 -0
  31. data/lib/aasm/core/invokers/class_invoker.rb +52 -0
  32. data/lib/aasm/core/invokers/literal_invoker.rb +47 -0
  33. data/lib/aasm/core/invokers/proc_invoker.rb +59 -0
  34. data/lib/aasm/core/state.rb +22 -13
  35. data/lib/aasm/core/transition.rb +17 -69
  36. data/lib/aasm/dsl_helper.rb +24 -22
  37. data/lib/aasm/errors.rb +4 -6
  38. data/lib/aasm/instance_base.rb +22 -4
  39. data/lib/aasm/localizer.rb +13 -3
  40. data/lib/aasm/minitest/allow_event.rb +13 -0
  41. data/lib/aasm/minitest/allow_transition_to.rb +13 -0
  42. data/lib/aasm/minitest/have_state.rb +13 -0
  43. data/lib/aasm/minitest/transition_from.rb +21 -0
  44. data/lib/aasm/minitest.rb +5 -0
  45. data/lib/aasm/minitest_spec.rb +15 -0
  46. data/lib/aasm/persistence/active_record_persistence.rb +49 -105
  47. data/lib/aasm/persistence/base.rb +20 -5
  48. data/lib/aasm/persistence/core_data_query_persistence.rb +2 -1
  49. data/lib/aasm/persistence/dynamoid_persistence.rb +1 -1
  50. data/lib/aasm/persistence/mongoid_persistence.rb +26 -32
  51. data/lib/aasm/persistence/no_brainer_persistence.rb +105 -0
  52. data/lib/aasm/persistence/orm.rb +154 -0
  53. data/lib/aasm/persistence/plain_persistence.rb +2 -1
  54. data/lib/aasm/persistence/redis_persistence.rb +16 -11
  55. data/lib/aasm/persistence/sequel_persistence.rb +36 -64
  56. data/lib/aasm/persistence.rb +3 -3
  57. data/lib/aasm/rspec/allow_event.rb +5 -1
  58. data/lib/aasm/rspec/allow_transition_to.rb +5 -1
  59. data/lib/aasm/rspec/transition_from.rb +5 -1
  60. data/lib/aasm/state_machine.rb +4 -2
  61. data/lib/aasm/state_machine_store.rb +5 -2
  62. data/lib/aasm/version.rb +1 -1
  63. data/lib/aasm.rb +5 -2
  64. data/lib/generators/aasm/orm_helpers.rb +6 -0
  65. data/lib/generators/active_record/aasm_generator.rb +3 -1
  66. data/lib/generators/active_record/templates/migration.rb +1 -1
  67. data/lib/generators/active_record/templates/migration_existing.rb +1 -1
  68. data/lib/generators/nobrainer/aasm_generator.rb +28 -0
  69. data/lib/motion-aasm.rb +3 -1
  70. data/spec/database.rb +20 -7
  71. data/spec/en.yml +0 -3
  72. data/spec/generators/active_record_generator_spec.rb +49 -40
  73. data/spec/generators/mongoid_generator_spec.rb +4 -6
  74. data/spec/generators/no_brainer_generator_spec.rb +29 -0
  75. data/spec/{en_deprecated_style.yml → localizer_test_model_deprecated_style.yml} +6 -3
  76. data/spec/localizer_test_model_new_style.yml +11 -0
  77. data/spec/models/active_record/active_record_callback.rb +93 -0
  78. data/spec/models/active_record/complex_active_record_example.rb +5 -1
  79. data/spec/models/active_record/instance_level_skip_validation_example.rb +19 -0
  80. data/spec/models/{invalid_persistor.rb → active_record/invalid_persistor.rb} +0 -2
  81. data/spec/models/active_record/localizer_test_model.rb +11 -3
  82. data/spec/models/active_record/namespaced.rb +16 -0
  83. data/spec/models/active_record/person.rb +23 -0
  84. data/spec/models/{silent_persistor.rb → active_record/silent_persistor.rb} +0 -2
  85. data/spec/models/active_record/simple_new_dsl.rb +15 -0
  86. data/spec/models/active_record/timestamp_example.rb +16 -0
  87. data/spec/models/{transactor.rb → active_record/transactor.rb} +25 -2
  88. data/spec/models/{validator.rb → active_record/validator.rb} +0 -2
  89. data/spec/models/active_record/work.rb +3 -0
  90. data/spec/models/{worker.rb → active_record/worker.rb} +0 -0
  91. data/spec/models/callbacks/basic.rb +5 -2
  92. data/spec/models/callbacks/with_state_arg.rb +5 -1
  93. data/spec/models/callbacks/with_state_arg_multiple.rb +4 -1
  94. data/spec/models/default_state.rb +1 -1
  95. data/spec/models/guard_arguments_check.rb +17 -0
  96. data/spec/models/guard_with_params.rb +1 -1
  97. data/spec/models/guardian_without_from_specified.rb +18 -0
  98. data/spec/models/mongoid/invalid_persistor_mongoid.rb +39 -0
  99. data/spec/models/mongoid/silent_persistor_mongoid.rb +39 -0
  100. data/spec/models/mongoid/timestamp_example_mongoid.rb +20 -0
  101. data/spec/models/mongoid/validator_mongoid.rb +100 -0
  102. data/spec/models/multiple_transitions_that_differ_only_by_guard.rb +31 -0
  103. data/spec/models/namespaced_multiple_example.rb +14 -0
  104. data/spec/models/nobrainer/complex_no_brainer_example.rb +36 -0
  105. data/spec/models/nobrainer/invalid_persistor_no_brainer.rb +39 -0
  106. data/spec/models/nobrainer/no_scope_no_brainer.rb +21 -0
  107. data/spec/models/nobrainer/nobrainer_relationships.rb +25 -0
  108. data/spec/models/nobrainer/silent_persistor_no_brainer.rb +39 -0
  109. data/spec/models/nobrainer/simple_new_dsl_nobrainer.rb +25 -0
  110. data/spec/models/{mongo_mapper/simple_mongo_mapper.rb → nobrainer/simple_no_brainer.rb} +8 -8
  111. data/spec/models/nobrainer/validator_no_brainer.rb +98 -0
  112. data/spec/models/parametrised_event.rb +7 -0
  113. data/spec/models/{mongo_mapper/complex_mongo_mapper_example.rb → redis/complex_redis_example.rb} +8 -5
  114. data/spec/models/redis/redis_multiple.rb +20 -0
  115. data/spec/models/redis/redis_simple.rb +20 -0
  116. data/spec/models/sequel/complex_sequel_example.rb +4 -3
  117. data/spec/models/sequel/invalid_persistor.rb +52 -0
  118. data/spec/models/sequel/sequel_multiple.rb +13 -13
  119. data/spec/models/sequel/sequel_simple.rb +13 -12
  120. data/spec/models/sequel/silent_persistor.rb +50 -0
  121. data/spec/models/sequel/transactor.rb +112 -0
  122. data/spec/models/sequel/validator.rb +93 -0
  123. data/spec/models/sequel/worker.rb +12 -0
  124. data/spec/models/simple_example.rb +8 -0
  125. data/spec/models/simple_example_with_guard_args.rb +17 -0
  126. data/spec/models/simple_multiple_example.rb +12 -0
  127. data/spec/models/sub_class.rb +34 -0
  128. data/spec/models/timestamps_example.rb +19 -0
  129. data/spec/models/timestamps_with_named_machine_example.rb +13 -0
  130. data/spec/spec_helper.rb +15 -33
  131. data/spec/spec_helpers/active_record.rb +8 -0
  132. data/spec/spec_helpers/dynamoid.rb +35 -0
  133. data/spec/spec_helpers/mongoid.rb +26 -0
  134. data/spec/spec_helpers/nobrainer.rb +15 -0
  135. data/spec/spec_helpers/redis.rb +18 -0
  136. data/spec/spec_helpers/remove_warnings.rb +1 -0
  137. data/spec/spec_helpers/sequel.rb +7 -0
  138. data/spec/unit/abstract_class_spec.rb +27 -0
  139. data/spec/unit/api_spec.rb +79 -72
  140. data/spec/unit/callback_multiple_spec.rb +7 -3
  141. data/spec/unit/callbacks_spec.rb +37 -2
  142. data/spec/unit/complex_example_spec.rb +12 -3
  143. data/spec/unit/complex_multiple_example_spec.rb +20 -4
  144. data/spec/unit/event_multiple_spec.rb +1 -1
  145. data/spec/unit/event_spec.rb +29 -4
  146. data/spec/unit/exception_spec.rb +1 -1
  147. data/spec/unit/guard_arguments_check_spec.rb +9 -0
  148. data/spec/unit/guard_spec.rb +17 -0
  149. data/spec/unit/guard_with_params_spec.rb +4 -0
  150. data/spec/unit/guard_without_from_specified_spec.rb +10 -0
  151. data/spec/unit/inspection_multiple_spec.rb +9 -5
  152. data/spec/unit/inspection_spec.rb +7 -3
  153. data/spec/unit/invoker_spec.rb +189 -0
  154. data/spec/unit/invokers/base_invoker_spec.rb +72 -0
  155. data/spec/unit/invokers/class_invoker_spec.rb +95 -0
  156. data/spec/unit/invokers/literal_invoker_spec.rb +86 -0
  157. data/spec/unit/invokers/proc_invoker_spec.rb +86 -0
  158. data/spec/unit/localizer_spec.rb +85 -52
  159. data/spec/unit/multiple_transitions_that_differ_only_by_guard_spec.rb +14 -0
  160. data/spec/unit/namespaced_multiple_example_spec.rb +22 -0
  161. data/spec/unit/override_warning_spec.rb +8 -0
  162. data/spec/unit/persistence/active_record_persistence_multiple_spec.rb +468 -447
  163. data/spec/unit/persistence/active_record_persistence_spec.rb +639 -486
  164. data/spec/unit/persistence/dynamoid_persistence_multiple_spec.rb +4 -9
  165. data/spec/unit/persistence/dynamoid_persistence_spec.rb +4 -9
  166. data/spec/unit/persistence/mongoid_persistence_multiple_spec.rb +83 -13
  167. data/spec/unit/persistence/mongoid_persistence_spec.rb +97 -13
  168. data/spec/unit/persistence/no_brainer_persistence_multiple_spec.rb +198 -0
  169. data/spec/unit/persistence/no_brainer_persistence_spec.rb +158 -0
  170. data/spec/unit/persistence/redis_persistence_multiple_spec.rb +88 -0
  171. data/spec/unit/persistence/redis_persistence_spec.rb +8 -32
  172. data/spec/unit/persistence/sequel_persistence_multiple_spec.rb +6 -11
  173. data/spec/unit/persistence/sequel_persistence_spec.rb +278 -10
  174. data/spec/unit/rspec_matcher_spec.rb +9 -0
  175. data/spec/unit/simple_example_spec.rb +15 -0
  176. data/spec/unit/simple_multiple_example_spec.rb +28 -0
  177. data/spec/unit/state_spec.rb +23 -7
  178. data/spec/unit/subclassing_multiple_spec.rb +37 -2
  179. data/spec/unit/subclassing_spec.rb +17 -2
  180. data/spec/unit/timestamps_spec.rb +32 -0
  181. data/spec/unit/transition_spec.rb +1 -1
  182. data/test/minitest_helper.rb +57 -0
  183. data/test/unit/minitest_matcher_test.rb +80 -0
  184. metadata +213 -37
  185. data/callbacks.txt +0 -51
  186. data/gemfiles/rails_3.2_stable.gemfile +0 -15
  187. data/gemfiles/rails_4.0.gemfile +0 -16
  188. data/gemfiles/rails_4.0_mongo_mapper.gemfile +0 -16
  189. data/gemfiles/rails_4.2_mongo_mapper.gemfile +0 -17
  190. data/lib/aasm/persistence/mongo_mapper_persistence.rb +0 -163
  191. data/spec/models/mongo_mapper/no_scope_mongo_mapper.rb +0 -21
  192. data/spec/models/mongo_mapper/simple_new_dsl_mongo_mapper.rb +0 -25
  193. data/spec/unit/persistence/mongo_mapper_persistence_multiple_spec.rb +0 -149
  194. data/spec/unit/persistence/mongo_mapper_persistence_spec.rb +0 -96
@@ -1,8 +1,7 @@
1
- describe 'dynamoid' do
2
- begin
3
- require 'dynamoid'
4
- require 'logger'
5
- require 'spec_helper'
1
+ require 'spec_helper'
2
+
3
+ if defined?(Dynamoid)
4
+ describe 'dynamoid' do
6
5
 
7
6
  Dir[File.dirname(__FILE__) + "/../../models/dynamoid/*.rb"].sort.each do |f|
8
7
  require File.expand_path(f)
@@ -132,9 +131,5 @@ describe 'dynamoid' do
132
131
  end
133
132
  end
134
133
 
135
- rescue LoadError
136
- puts "------------------------------------------------------------------------"
137
- puts "Not running Dynamoid multiple-specs because dynamoid gem is not installed!!!"
138
- puts "------------------------------------------------------------------------"
139
134
  end
140
135
  end
@@ -1,8 +1,7 @@
1
- describe 'dynamoid' do
2
- begin
3
- require 'dynamoid'
4
- require 'logger'
5
- require 'spec_helper'
1
+ require 'spec_helper'
2
+
3
+ if defined?(Dynamoid)
4
+ describe 'dynamoid' do
6
5
 
7
6
  Dir[File.dirname(__FILE__) + "/../../models/dynamoid/*.rb"].sort.each do |f|
8
7
  require File.expand_path(f)
@@ -81,9 +80,5 @@ describe 'dynamoid' do
81
80
  end
82
81
  end
83
82
 
84
- rescue LoadError
85
- puts "------------------------------------------------------------------------"
86
- puts "Not running Dynamoid specs because dynamoid gem is not installed!!!"
87
- puts "------------------------------------------------------------------------"
88
83
  end
89
84
  end
@@ -1,8 +1,7 @@
1
- describe 'mongoid' do
2
- begin
3
- require 'mongoid'
4
- require 'logger'
5
- require 'spec_helper'
1
+ require 'spec_helper'
2
+
3
+ if defined?(Mongoid::Document)
4
+ describe 'mongoid' do
6
5
 
7
6
  Dir[File.dirname(__FILE__) + "/../../models/mongoid/*.rb"].sort.each do |f|
8
7
  require File.expand_path(f)
@@ -11,10 +10,6 @@ describe 'mongoid' do
11
10
  before(:all) do
12
11
  # if you want to see the statements while running the spec enable the following line
13
12
  # Mongoid.logger = Logger.new(STDERR)
14
-
15
- Mongoid.configure do |config|
16
- config.connect_to "mongoid_#{Process.pid}"
17
- end
18
13
  end
19
14
 
20
15
  after do
@@ -72,6 +67,85 @@ describe 'mongoid' do
72
67
 
73
68
  end
74
69
 
70
+ describe 'transitions with persistence' do
71
+
72
+ it "should work for valid models" do
73
+ valid_object = MultipleValidatorMongoid.create(:name => 'name')
74
+ expect(valid_object).to be_sleeping
75
+ valid_object.status = :running
76
+ expect(valid_object).to be_running
77
+ end
78
+
79
+ it 'should not store states for invalid models' do
80
+ validator = MultipleValidatorMongoid.create(:name => 'name')
81
+ expect(validator).to be_valid
82
+ expect(validator).to be_sleeping
83
+
84
+ validator.name = nil
85
+ expect(validator).not_to be_valid
86
+ expect { validator.run! }.to raise_error(Mongoid::Errors::Validations)
87
+ expect(validator).to be_sleeping
88
+
89
+ validator.reload
90
+ expect(validator).not_to be_running
91
+ expect(validator).to be_sleeping
92
+
93
+ validator.name = 'another name'
94
+ expect(validator).to be_valid
95
+ expect(validator.run!).to be_truthy
96
+ expect(validator).to be_running
97
+
98
+ validator.reload
99
+ expect(validator).to be_running
100
+ expect(validator).not_to be_sleeping
101
+ end
102
+
103
+ it 'should not store states for invalid models silently if configured' do
104
+ validator = MultipleSilentPersistorMongoid.create(:name => 'name')
105
+ expect(validator).to be_valid
106
+ expect(validator).to be_sleeping
107
+
108
+ validator.name = nil
109
+ expect(validator).not_to be_valid
110
+ expect(validator.run!).to be_falsey
111
+ expect(validator).to be_sleeping
112
+
113
+ validator.reload
114
+ expect(validator).not_to be_running
115
+ expect(validator).to be_sleeping
116
+
117
+ validator.name = 'another name'
118
+ expect(validator).to be_valid
119
+ expect(validator.run!).to be_truthy
120
+ expect(validator).to be_running
121
+
122
+ validator.reload
123
+ expect(validator).to be_running
124
+ expect(validator).not_to be_sleeping
125
+ end
126
+
127
+ it 'should store states for invalid models if configured' do
128
+ persistor = MultipleInvalidPersistorMongoid.create(:name => 'name')
129
+ expect(persistor).to be_valid
130
+ expect(persistor).to be_sleeping
131
+
132
+ persistor.name = nil
133
+ expect(persistor).not_to be_valid
134
+ expect(persistor.run!).to be_truthy
135
+ expect(persistor).to be_running
136
+
137
+ persistor = MultipleInvalidPersistorMongoid.find(persistor.id)
138
+ persistor.valid?
139
+ expect(persistor).to be_valid
140
+ expect(persistor).to be_running
141
+ expect(persistor).not_to be_sleeping
142
+
143
+ persistor.reload
144
+ expect(persistor).to be_running
145
+ expect(persistor).not_to be_sleeping
146
+ end
147
+ end
148
+
75
149
  describe "complex example" do
76
150
  it "works" do
77
151
  record = ComplexMongoidExample.new
@@ -122,9 +196,5 @@ describe 'mongoid' do
122
196
  end
123
197
  end
124
198
 
125
- rescue LoadError
126
- puts "--------------------------------------------------------------------------"
127
- puts "Not running Mongoid multiple-specs because mongoid gem is not installed!!!"
128
- puts "--------------------------------------------------------------------------"
129
199
  end
130
200
  end
@@ -1,8 +1,7 @@
1
- describe 'mongoid' do
2
- begin
3
- require 'mongoid'
4
- require 'logger'
5
- require 'spec_helper'
1
+ require 'spec_helper'
2
+
3
+ if defined?(Mongoid::Document)
4
+ describe 'mongoid' do
6
5
 
7
6
  Dir[File.dirname(__FILE__) + "/../../models/mongoid/*.rb"].sort.each do |f|
8
7
  require File.expand_path(f)
@@ -11,10 +10,6 @@ describe 'mongoid' do
11
10
  before(:all) do
12
11
  # if you want to see the statements while running the spec enable the following line
13
12
  # Mongoid.logger = Logger.new(STDERR)
14
-
15
- Mongoid.configure do |config|
16
- config.connect_to "mongoid_#{Process.pid}"
17
- end
18
13
  end
19
14
 
20
15
  after do
@@ -85,9 +80,98 @@ describe 'mongoid' do
85
80
 
86
81
  end
87
82
 
88
- rescue LoadError
89
- puts "--------------------------------------------------------------------------"
90
- puts "Not running Mongoid specs because mongoid gem is not installed!!!"
91
- puts "--------------------------------------------------------------------------"
83
+ describe 'transitions with persistence' do
84
+
85
+ it 'should work for valid models' do
86
+ valid_object = ValidatorMongoid.create(:name => 'name')
87
+ expect(valid_object).to be_sleeping
88
+ valid_object.status = :running
89
+ expect(valid_object).to be_running
90
+ end
91
+
92
+ it 'should not store states for invalid models' do
93
+ validator = ValidatorMongoid.create(:name => 'name')
94
+ expect(validator).to be_valid
95
+ expect(validator).to be_sleeping
96
+
97
+ validator.name = nil
98
+ expect(validator).not_to be_valid
99
+ expect { validator.run! }.to raise_error(Mongoid::Errors::Validations)
100
+ expect(validator).to be_sleeping
101
+
102
+ validator.reload
103
+ expect(validator).not_to be_running
104
+ expect(validator).to be_sleeping
105
+
106
+ validator.name = 'another name'
107
+ expect(validator).to be_valid
108
+ expect(validator.run!).to be_truthy
109
+ expect(validator).to be_running
110
+
111
+ validator.reload
112
+ expect(validator).to be_running
113
+ expect(validator).not_to be_sleeping
114
+ end
115
+
116
+ it 'should not store states for invalid models silently if configured' do
117
+ validator = SilentPersistorMongoid.create(:name => 'name')
118
+ expect(validator).to be_valid
119
+ expect(validator).to be_sleeping
120
+
121
+ validator.name = nil
122
+ expect(validator).not_to be_valid
123
+ expect(validator.run!).to be_falsey
124
+ expect(validator).to be_sleeping
125
+
126
+ validator.reload
127
+ expect(validator).not_to be_running
128
+ expect(validator).to be_sleeping
129
+
130
+ validator.name = 'another name'
131
+ expect(validator).to be_valid
132
+ expect(validator.run!).to be_truthy
133
+ expect(validator).to be_running
134
+
135
+ validator.reload
136
+ expect(validator).to be_running
137
+ expect(validator).not_to be_sleeping
138
+ end
139
+
140
+ it 'should store states for invalid models if configured' do
141
+ persistor = InvalidPersistorMongoid.create(:name => 'name')
142
+ expect(persistor).to be_valid
143
+ expect(persistor).to be_sleeping
144
+
145
+ persistor.name = nil
146
+
147
+ expect(persistor).not_to be_valid
148
+ expect(persistor.run!).to be_truthy
149
+ expect(persistor).to be_running
150
+
151
+ persistor = InvalidPersistorMongoid.find(persistor.id)
152
+
153
+ persistor.valid?
154
+ expect(persistor).to be_valid
155
+ expect(persistor).to be_running
156
+ expect(persistor).not_to be_sleeping
157
+
158
+ persistor.reload
159
+ expect(persistor).to be_running
160
+ expect(persistor).not_to be_sleeping
161
+ end
162
+ end
163
+
164
+ describe 'testing the timestamps option' do
165
+ let(:example) { TimestampExampleMongoid.create }
166
+
167
+ it 'should update existing timestamp fields' do
168
+ expect { example.open! }.to change { example.reload.opened_at }.from(nil).to(instance_of(::Time))
169
+ end
170
+
171
+ it 'should not fail if there is no corresponding timestamp field' do
172
+ expect { example.close! }.to change { example.reload.status }
173
+ end
174
+ end
175
+
92
176
  end
93
177
  end
@@ -0,0 +1,198 @@
1
+ require 'spec_helper'
2
+
3
+ if defined?(NoBrainer::Document)
4
+ describe 'nobrainer' do
5
+ Dir[File.dirname(__FILE__) + '/../../models/nobrainer/*.rb'].sort.each do |f|
6
+ require File.expand_path(f)
7
+ end
8
+
9
+ before(:all) do
10
+ # if you want to see the statements while running the spec enable the
11
+ # following line
12
+ # NoBrainer.configure do |config|
13
+ # config.logger = Logger.new(STDERR)
14
+ # end
15
+ end
16
+
17
+ after do
18
+ NoBrainer.purge!
19
+ end
20
+
21
+ describe 'named scopes with the old DSL' do
22
+ context 'Does not already respond_to? the scope name' do
23
+ it 'should add a scope for each state' do
24
+ expect(SimpleNoBrainerMultiple).to respond_to(:unknown_scope)
25
+ expect(SimpleNoBrainerMultiple).to respond_to(:another_unknown_scope)
26
+
27
+ expect(SimpleNoBrainerMultiple.unknown_scope.class).to eq(NoBrainer::Criteria)
28
+ expect(SimpleNoBrainerMultiple.another_unknown_scope.class).to eq(NoBrainer::Criteria)
29
+ end
30
+ end
31
+
32
+ context 'Already respond_to? the scope name' do
33
+ it 'should not add a scope' do
34
+ expect(SimpleNoBrainerMultiple).to respond_to(:new)
35
+ expect(SimpleNoBrainerMultiple.new.class).to eq(SimpleNoBrainerMultiple)
36
+ end
37
+ end
38
+
39
+ end
40
+
41
+ describe 'named scopes with the new DSL' do
42
+ context 'Does not already respond_to? the scope name' do
43
+ it 'should add a scope' do
44
+ expect(SimpleNewDslNoBrainerMultiple).to respond_to(:unknown_scope)
45
+ expect(SimpleNewDslNoBrainerMultiple.unknown_scope.class).to eq(NoBrainer::Criteria)
46
+ end
47
+ end
48
+
49
+ context 'Already respond_to? the scope name' do
50
+ it 'should not add a scope' do
51
+ expect(SimpleNewDslNoBrainerMultiple).to respond_to(:new)
52
+ expect(SimpleNewDslNoBrainerMultiple.new.class).to eq(SimpleNewDslNoBrainerMultiple)
53
+ end
54
+ end
55
+
56
+ it 'does not create scopes if requested' do
57
+ expect(NoScopeNoBrainerMultiple).not_to respond_to(:ignored_scope)
58
+ end
59
+ end
60
+
61
+ describe 'instance methods' do
62
+ let(:simple) { SimpleNewDslNoBrainerMultiple.new }
63
+
64
+ it 'should initialize the aasm state on instantiation' do
65
+ expect(SimpleNewDslNoBrainerMultiple.new.status).to eql 'unknown_scope'
66
+ expect(SimpleNewDslNoBrainerMultiple.new.aasm(:left).current_state).to eql :unknown_scope
67
+ end
68
+ end
69
+
70
+ describe 'transitions with persistence' do
71
+ it 'should work for valid models' do
72
+ valid_object = MultipleValidatorNoBrainer.create(name: 'name')
73
+ expect(valid_object).to be_sleeping
74
+ valid_object.status = :running
75
+ expect(valid_object).to be_running
76
+ end
77
+
78
+ it 'should not store states for invalid models' do
79
+ validator = MultipleValidatorNoBrainer.create(name: 'name')
80
+ expect(validator).to be_valid
81
+ expect(validator).to be_sleeping
82
+
83
+ validator.name = nil
84
+ expect(validator).not_to be_valid
85
+ expect { validator.run! }.to raise_error(NoBrainer::Error::DocumentInvalid)
86
+ expect(validator).to be_sleeping
87
+
88
+ validator.reload
89
+ expect(validator).not_to be_running
90
+ expect(validator).to be_sleeping
91
+
92
+ validator.name = 'another name'
93
+ expect(validator).to be_valid
94
+ expect(validator.run!).to be_truthy
95
+ expect(validator).to be_running
96
+
97
+ validator.reload
98
+ expect(validator).to be_running
99
+ expect(validator).not_to be_sleeping
100
+ end
101
+
102
+ it 'should not store states for invalid models silently if configured' do
103
+ validator = MultipleSilentPersistorNoBrainer.create(name: 'name')
104
+ expect(validator).to be_valid
105
+ expect(validator).to be_sleeping
106
+
107
+ validator.name = nil
108
+ expect(validator).not_to be_valid
109
+ expect(validator.run!).to be_falsey
110
+ expect(validator).to be_sleeping
111
+
112
+ validator.reload
113
+ expect(validator).not_to be_running
114
+ expect(validator).to be_sleeping
115
+
116
+ validator.name = 'another name'
117
+ expect(validator).to be_valid
118
+ expect(validator.run!).to be_truthy
119
+ expect(validator).to be_running
120
+
121
+ validator.reload
122
+ expect(validator).to be_running
123
+ expect(validator).not_to be_sleeping
124
+ end
125
+
126
+ it 'should store states for invalid models if configured' do
127
+ persistor = MultipleInvalidPersistorNoBrainer.create(name: 'name')
128
+ expect(persistor).to be_valid
129
+ expect(persistor).to be_sleeping
130
+
131
+ persistor.name = nil
132
+ expect(persistor).not_to be_valid
133
+ expect(persistor.run!).to be_truthy
134
+ expect(persistor).to be_running
135
+
136
+ persistor = MultipleInvalidPersistorNoBrainer.find(persistor.id)
137
+ persistor.valid?
138
+ expect(persistor).to be_valid
139
+ expect(persistor).to be_running
140
+ expect(persistor).not_to be_sleeping
141
+
142
+ persistor.reload
143
+ expect(persistor).to be_running
144
+ expect(persistor).not_to be_sleeping
145
+ end
146
+ end
147
+
148
+ describe 'complex example' do
149
+ it 'works' do
150
+ record = ComplexNoBrainerExample.new
151
+ expect_aasm_states record, :one, :alpha
152
+
153
+ record.save!
154
+ expect_aasm_states record, :one, :alpha
155
+ record.reload
156
+ expect_aasm_states record, :one, :alpha
157
+
158
+ record.increment!
159
+ expect_aasm_states record, :two, :alpha
160
+ record.reload
161
+ expect_aasm_states record, :two, :alpha
162
+
163
+ record.level_up!
164
+ expect_aasm_states record, :two, :beta
165
+ record.reload
166
+ expect_aasm_states record, :two, :beta
167
+
168
+ record.increment!
169
+ expect { record.increment! }.to raise_error(AASM::InvalidTransition)
170
+ expect_aasm_states record, :three, :beta
171
+ record.reload
172
+ expect_aasm_states record, :three, :beta
173
+
174
+ record.level_up!
175
+ expect_aasm_states record, :three, :gamma
176
+ record.reload
177
+ expect_aasm_states record, :three, :gamma
178
+
179
+ record.level_down # without saving
180
+ expect_aasm_states record, :three, :beta
181
+ record.reload
182
+ expect_aasm_states record, :three, :gamma
183
+
184
+ record.level_down # without saving
185
+ expect_aasm_states record, :three, :beta
186
+ record.reset!
187
+ expect_aasm_states record, :one, :beta
188
+ end
189
+
190
+ def expect_aasm_states(record, left_state, right_state)
191
+ expect(record.aasm(:left).current_state).to eql left_state.to_sym
192
+ expect(record.left).to eql left_state.to_s
193
+ expect(record.aasm(:right).current_state).to eql right_state.to_sym
194
+ expect(record.right).to eql right_state.to_s
195
+ end
196
+ end
197
+ end
198
+ end
@@ -0,0 +1,158 @@
1
+ require 'spec_helper'
2
+
3
+ if defined?(NoBrainer::Document)
4
+ describe 'nobrainer' do
5
+ Dir[File.dirname(__FILE__) + '/../../models/nobrainer/*.rb'].sort.each do |f|
6
+ require File.expand_path(f)
7
+ end
8
+
9
+ before(:all) do
10
+ # if you want to see the statements while running the spec enable the
11
+ # following line
12
+ # NoBrainer.configure do |config|
13
+ # config.logger = Logger.new(STDERR)
14
+ # end
15
+ end
16
+
17
+ after do
18
+ NoBrainer.purge!
19
+ end
20
+
21
+ describe 'named scopes with the old DSL' do
22
+ context 'Does not already respond_to? the scope name' do
23
+ it 'should add a scope for each state' do
24
+ expect(SimpleNoBrainer).to respond_to(:unknown_scope)
25
+ expect(SimpleNoBrainer).to respond_to(:another_unknown_scope)
26
+
27
+ expect(SimpleNoBrainer.unknown_scope.class).to eq(NoBrainer::Criteria)
28
+ expect(SimpleNoBrainer.another_unknown_scope.class).to eq(NoBrainer::Criteria)
29
+ end
30
+ end
31
+
32
+ context 'Already respond_to? the scope name' do
33
+ it 'should not add a scope' do
34
+ expect(SimpleNoBrainer).to respond_to(:new)
35
+ expect(SimpleNoBrainer.new.class).to eq(SimpleNoBrainer)
36
+ end
37
+ end
38
+ end
39
+
40
+ describe 'named scopes with the new DSL' do
41
+ context 'Does not already respond_to? the scope name' do
42
+ it 'should add a scope' do
43
+ expect(SimpleNewDslNoBrainer).to respond_to(:unknown_scope)
44
+ expect(SimpleNewDslNoBrainer.unknown_scope.class).to eq(NoBrainer::Criteria)
45
+ end
46
+ end
47
+
48
+ context 'Already respond_to? the scope name' do
49
+ it 'should not add a scope' do
50
+ expect(SimpleNewDslNoBrainer).to respond_to(:new)
51
+ expect(SimpleNewDslNoBrainer.new.class).to eq(SimpleNewDslNoBrainer)
52
+ end
53
+ end
54
+
55
+ it 'does not create scopes if requested' do
56
+ expect(NoScopeNoBrainer).not_to respond_to(:ignored_scope)
57
+ end
58
+ end
59
+
60
+ describe 'instance methods' do
61
+ let(:simple) { SimpleNewDslNoBrainer.new }
62
+
63
+ it 'should initialize the aasm state on instantiation' do
64
+ expect(SimpleNewDslNoBrainer.new.status).to eql 'unknown_scope'
65
+ expect(SimpleNewDslNoBrainer.new.aasm.current_state).to eql :unknown_scope
66
+ end
67
+ end
68
+
69
+ describe 'relations object' do
70
+ it 'should load relations object ids' do
71
+ parent = Parent.create
72
+ child_1 = Child.create(parent_id: parent.id)
73
+ child_2 = Child.create(parent_id: parent.id)
74
+ expect(parent.childs.pluck(:id, :status).map(&:id)).to eql [child_1.id, child_2.id]
75
+ end
76
+ end
77
+
78
+ describe 'transitions with persistence' do
79
+ it 'should work for valid models' do
80
+ valid_object = ValidatorNoBrainer.create(name: 'name')
81
+ expect(valid_object).to be_sleeping
82
+ valid_object.status = :running
83
+ expect(valid_object).to be_running
84
+ end
85
+
86
+ it 'should not store states for invalid models' do
87
+ validator = ValidatorNoBrainer.create(name: 'name')
88
+ expect(validator).to be_valid
89
+ expect(validator).to be_sleeping
90
+
91
+ validator.name = nil
92
+ expect(validator).not_to be_valid
93
+ expect { validator.run! }.to raise_error(NoBrainer::Error::DocumentInvalid)
94
+ expect(validator).to be_sleeping
95
+
96
+ validator.reload
97
+ expect(validator).not_to be_running
98
+ expect(validator).to be_sleeping
99
+
100
+ validator.name = 'another name'
101
+ expect(validator).to be_valid
102
+ expect(validator.run!).to be_truthy
103
+ expect(validator).to be_running
104
+
105
+ validator.reload
106
+ expect(validator).to be_running
107
+ expect(validator).not_to be_sleeping
108
+ end
109
+
110
+ it 'should not store states for invalid models silently if configured' do
111
+ validator = SilentPersistorNoBrainer.create(name: 'name')
112
+ expect(validator).to be_valid
113
+ expect(validator).to be_sleeping
114
+
115
+ validator.name = nil
116
+ expect(validator).not_to be_valid
117
+ expect(validator.run!).to be_falsey
118
+ expect(validator).to be_sleeping
119
+
120
+ validator.reload
121
+ expect(validator).not_to be_running
122
+ expect(validator).to be_sleeping
123
+
124
+ validator.name = 'another name'
125
+ expect(validator).to be_valid
126
+ expect(validator.run!).to be_truthy
127
+ expect(validator).to be_running
128
+
129
+ validator.reload
130
+ expect(validator).to be_running
131
+ expect(validator).not_to be_sleeping
132
+ end
133
+
134
+ it 'should store states for invalid models if configured' do
135
+ persistor = InvalidPersistorNoBrainer.create(name: 'name')
136
+ expect(persistor).to be_valid
137
+ expect(persistor).to be_sleeping
138
+
139
+ persistor.name = nil
140
+
141
+ expect(persistor).not_to be_valid
142
+ expect(persistor.run!).to be_truthy
143
+ expect(persistor).to be_running
144
+
145
+ persistor = InvalidPersistorNoBrainer.find(persistor.id)
146
+
147
+ persistor.valid?
148
+ expect(persistor).to be_valid
149
+ expect(persistor).to be_running
150
+ expect(persistor).not_to be_sleeping
151
+
152
+ persistor.reload
153
+ expect(persistor).to be_running
154
+ expect(persistor).not_to be_sleeping
155
+ end
156
+ end
157
+ end
158
+ end