state_machine 1.1.2 → 1.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 (240) hide show
  1. data/.gitignore +7 -11
  2. data/.travis.yml +49 -7
  3. data/Appraisals +255 -87
  4. data/CHANGELOG.md +30 -0
  5. data/README.md +142 -21
  6. data/Rakefile +1 -11
  7. data/examples/Gemfile +5 -0
  8. data/examples/Gemfile.lock +14 -0
  9. data/examples/auto_shop.rb +2 -0
  10. data/examples/car.rb +2 -0
  11. data/examples/doc/AutoShop.html +2856 -0
  12. data/examples/doc/AutoShop_state.png +0 -0
  13. data/examples/doc/Car.html +919 -0
  14. data/examples/doc/Car_state.png +0 -0
  15. data/examples/doc/TrafficLight.html +2230 -0
  16. data/examples/doc/TrafficLight_state.png +0 -0
  17. data/examples/doc/Vehicle.html +7921 -0
  18. data/examples/doc/Vehicle_state.png +0 -0
  19. data/examples/doc/_index.html +136 -0
  20. data/examples/doc/class_list.html +47 -0
  21. data/examples/doc/css/common.css +1 -0
  22. data/examples/doc/css/full_list.css +55 -0
  23. data/examples/doc/css/style.css +322 -0
  24. data/examples/doc/file_list.html +46 -0
  25. data/examples/doc/frames.html +13 -0
  26. data/examples/doc/index.html +136 -0
  27. data/examples/doc/js/app.js +205 -0
  28. data/examples/doc/js/full_list.js +173 -0
  29. data/examples/doc/js/jquery.js +16 -0
  30. data/examples/doc/method_list.html +734 -0
  31. data/examples/doc/top-level-namespace.html +105 -0
  32. data/examples/rails-rest/migration.rb +1 -5
  33. data/examples/rails-rest/view__form.html.erb +34 -0
  34. data/examples/rails-rest/view_edit.html.erb +2 -21
  35. data/examples/rails-rest/view_index.html.erb +6 -4
  36. data/examples/rails-rest/view_new.html.erb +2 -11
  37. data/examples/rails-rest/view_show.html.erb +5 -3
  38. data/examples/traffic_light.rb +2 -0
  39. data/examples/vehicle.rb +2 -0
  40. data/gemfiles/active_model-3.0.0.gemfile.lock +9 -6
  41. data/gemfiles/active_model-3.0.5.gemfile.lock +10 -7
  42. data/gemfiles/active_model-3.1.1.gemfile.lock +12 -10
  43. data/gemfiles/{active_model-3.2.0.gemfile → active_model-3.2.1.gemfile} +1 -1
  44. data/gemfiles/{graphviz-0.9.0.gemfile → active_model-3.2.12.gemfile} +1 -1
  45. data/gemfiles/active_model-3.2.12.gemfile.lock +36 -0
  46. data/gemfiles/{active_record-3.2.0.gemfile → active_model-3.2.13.rc1.gemfile} +1 -2
  47. data/gemfiles/active_model-3.2.13.rc1.gemfile.lock +36 -0
  48. data/gemfiles/active_model-4.0.0.gemfile +9 -0
  49. data/gemfiles/active_model-4.0.0.gemfile.lock +78 -0
  50. data/gemfiles/active_record-2.0.0.gemfile +2 -1
  51. data/gemfiles/active_record-2.0.0.gemfile.lock +15 -6
  52. data/gemfiles/active_record-2.0.5.gemfile +2 -1
  53. data/gemfiles/active_record-2.0.5.gemfile.lock +15 -6
  54. data/gemfiles/active_record-2.1.0.gemfile +2 -1
  55. data/gemfiles/active_record-2.1.0.gemfile.lock +15 -6
  56. data/gemfiles/active_record-2.1.2.gemfile +2 -1
  57. data/gemfiles/active_record-2.1.2.gemfile.lock +15 -6
  58. data/gemfiles/active_record-2.2.3.gemfile +2 -1
  59. data/gemfiles/active_record-2.2.3.gemfile.lock +15 -6
  60. data/gemfiles/active_record-2.3.12.gemfile +2 -1
  61. data/gemfiles/active_record-2.3.12.gemfile.lock +15 -6
  62. data/gemfiles/active_record-2.3.5.gemfile +9 -0
  63. data/gemfiles/active_record-2.3.5.gemfile.lock +39 -0
  64. data/gemfiles/active_record-3.0.0.gemfile +2 -1
  65. data/gemfiles/active_record-3.0.0.gemfile.lock +18 -11
  66. data/gemfiles/active_record-3.0.5.gemfile +2 -1
  67. data/gemfiles/active_record-3.0.5.gemfile.lock +19 -12
  68. data/gemfiles/active_record-3.1.1.gemfile +2 -1
  69. data/gemfiles/active_record-3.1.1.gemfile.lock +22 -16
  70. data/gemfiles/active_record-3.2.12.gemfile +9 -0
  71. data/gemfiles/active_record-3.2.12.gemfile.lock +51 -0
  72. data/gemfiles/active_record-3.2.13.rc1.gemfile +9 -0
  73. data/gemfiles/active_record-3.2.13.rc1.gemfile.lock +51 -0
  74. data/gemfiles/active_record-4.0.0.gemfile +11 -0
  75. data/gemfiles/active_record-4.0.0.gemfile.lock +83 -0
  76. data/gemfiles/data_mapper-0.10.2.gemfile +1 -0
  77. data/gemfiles/data_mapper-0.10.2.gemfile.lock +13 -9
  78. data/gemfiles/data_mapper-0.9.11.gemfile +1 -0
  79. data/gemfiles/data_mapper-0.9.11.gemfile.lock +31 -7
  80. data/gemfiles/data_mapper-0.9.4.gemfile.lock +25 -14
  81. data/gemfiles/data_mapper-0.9.7.gemfile +1 -0
  82. data/gemfiles/data_mapper-0.9.7.gemfile.lock +27 -15
  83. data/gemfiles/data_mapper-1.0.0.gemfile.lock +20 -17
  84. data/gemfiles/data_mapper-1.0.1.gemfile.lock +20 -17
  85. data/gemfiles/data_mapper-1.0.2.gemfile.lock +20 -17
  86. data/gemfiles/data_mapper-1.1.0.gemfile.lock +19 -16
  87. data/gemfiles/data_mapper-1.2.0.gemfile.lock +19 -16
  88. data/gemfiles/default.gemfile.lock +8 -5
  89. data/gemfiles/graphviz-0.9.17.gemfile +7 -0
  90. data/gemfiles/graphviz-0.9.17.gemfile.lock +29 -0
  91. data/gemfiles/graphviz-0.9.21.gemfile.lock +7 -4
  92. data/gemfiles/graphviz-1.0.0.gemfile.lock +7 -4
  93. data/gemfiles/graphviz-1.0.3.gemfile +7 -0
  94. data/gemfiles/graphviz-1.0.3.gemfile.lock +29 -0
  95. data/gemfiles/graphviz-1.0.8.gemfile +7 -0
  96. data/gemfiles/graphviz-1.0.8.gemfile.lock +29 -0
  97. data/gemfiles/mongo_mapper-0.10.0.gemfile +1 -0
  98. data/gemfiles/mongo_mapper-0.10.0.gemfile.lock +14 -11
  99. data/gemfiles/mongo_mapper-0.11.1.gemfile +7 -0
  100. data/gemfiles/mongo_mapper-0.11.1.gemfile.lock +44 -0
  101. data/gemfiles/mongo_mapper-0.11.2.gemfile +9 -0
  102. data/gemfiles/mongo_mapper-0.11.2.gemfile.lock +48 -0
  103. data/gemfiles/mongo_mapper-0.12.0.gemfile +9 -0
  104. data/gemfiles/mongo_mapper-0.12.0.gemfile.lock +48 -0
  105. data/gemfiles/mongo_mapper-0.5.5.gemfile.lock +7 -4
  106. data/gemfiles/mongo_mapper-0.5.8.gemfile.lock +7 -4
  107. data/gemfiles/mongo_mapper-0.6.0.gemfile.lock +7 -4
  108. data/gemfiles/mongo_mapper-0.6.10.gemfile.lock +7 -4
  109. data/gemfiles/mongo_mapper-0.7.0.gemfile.lock +7 -4
  110. data/gemfiles/mongo_mapper-0.7.5.gemfile.lock +7 -4
  111. data/gemfiles/mongo_mapper-0.8.0.gemfile.lock +7 -4
  112. data/gemfiles/mongo_mapper-0.8.3.gemfile.lock +7 -4
  113. data/gemfiles/mongo_mapper-0.8.4.gemfile.lock +7 -4
  114. data/gemfiles/mongo_mapper-0.8.6.gemfile.lock +7 -4
  115. data/gemfiles/mongo_mapper-0.9.0.gemfile.lock +7 -4
  116. data/gemfiles/mongoid-2.0.0.gemfile +2 -0
  117. data/gemfiles/mongoid-2.0.0.gemfile.lock +22 -18
  118. data/gemfiles/mongoid-2.1.4.gemfile +2 -0
  119. data/gemfiles/mongoid-2.1.4.gemfile.lock +21 -17
  120. data/gemfiles/mongoid-2.2.4.gemfile +2 -0
  121. data/gemfiles/mongoid-2.2.4.gemfile.lock +21 -17
  122. data/gemfiles/mongoid-2.3.3.gemfile +2 -0
  123. data/gemfiles/mongoid-2.3.3.gemfile.lock +21 -17
  124. data/gemfiles/mongoid-2.4.0.gemfile +9 -0
  125. data/gemfiles/mongoid-2.4.0.gemfile.lock +47 -0
  126. data/gemfiles/mongoid-2.4.10.gemfile +9 -0
  127. data/gemfiles/mongoid-2.4.10.gemfile.lock +47 -0
  128. data/gemfiles/mongoid-2.5.2.gemfile +9 -0
  129. data/gemfiles/mongoid-2.5.2.gemfile.lock +47 -0
  130. data/gemfiles/mongoid-2.6.0.gemfile +9 -0
  131. data/gemfiles/mongoid-2.6.0.gemfile.lock +47 -0
  132. data/gemfiles/mongoid-3.0.0.gemfile +8 -0
  133. data/gemfiles/mongoid-3.0.0.gemfile.lock +45 -0
  134. data/gemfiles/mongoid-3.0.22.gemfile +8 -0
  135. data/gemfiles/mongoid-3.0.22.gemfile.lock +45 -0
  136. data/gemfiles/mongoid-3.1.0.gemfile +8 -0
  137. data/gemfiles/mongoid-3.1.0.gemfile.lock +45 -0
  138. data/gemfiles/sequel-2.11.0.gemfile +2 -1
  139. data/gemfiles/sequel-2.11.0.gemfile.lock +11 -6
  140. data/gemfiles/sequel-2.12.0.gemfile +2 -1
  141. data/gemfiles/sequel-2.12.0.gemfile.lock +11 -6
  142. data/gemfiles/sequel-2.8.0.gemfile +2 -1
  143. data/gemfiles/sequel-2.8.0.gemfile.lock +11 -6
  144. data/gemfiles/sequel-3.0.0.gemfile +2 -1
  145. data/gemfiles/sequel-3.0.0.gemfile.lock +11 -6
  146. data/gemfiles/sequel-3.10.0.gemfile +9 -0
  147. data/gemfiles/sequel-3.10.0.gemfile.lock +33 -0
  148. data/gemfiles/sequel-3.13.0.gemfile +2 -1
  149. data/gemfiles/sequel-3.13.0.gemfile.lock +11 -6
  150. data/gemfiles/sequel-3.14.0.gemfile +2 -1
  151. data/gemfiles/sequel-3.14.0.gemfile.lock +11 -6
  152. data/gemfiles/sequel-3.23.0.gemfile +2 -1
  153. data/gemfiles/sequel-3.23.0.gemfile.lock +11 -6
  154. data/gemfiles/sequel-3.24.0.gemfile +2 -1
  155. data/gemfiles/sequel-3.24.0.gemfile.lock +11 -6
  156. data/gemfiles/sequel-3.29.0.gemfile +2 -1
  157. data/gemfiles/sequel-3.29.0.gemfile.lock +11 -6
  158. data/gemfiles/sequel-3.34.0.gemfile +9 -0
  159. data/gemfiles/sequel-3.34.0.gemfile.lock +33 -0
  160. data/gemfiles/sequel-3.35.0.gemfile +9 -0
  161. data/gemfiles/sequel-3.35.0.gemfile.lock +33 -0
  162. data/gemfiles/sequel-3.4.0.gemfile +9 -0
  163. data/gemfiles/sequel-3.4.0.gemfile.lock +33 -0
  164. data/gemfiles/sequel-3.44.0.gemfile +9 -0
  165. data/gemfiles/sequel-3.44.0.gemfile.lock +33 -0
  166. data/lib/state_machine.rb +6 -0
  167. data/lib/state_machine/branch.rb +9 -8
  168. data/lib/state_machine/callback.rb +2 -2
  169. data/lib/state_machine/core.rb +10 -0
  170. data/lib/state_machine/core_ext.rb +1 -0
  171. data/lib/state_machine/eval_helpers.rb +5 -3
  172. data/lib/state_machine/event.rb +17 -6
  173. data/lib/state_machine/graph.rb +92 -0
  174. data/lib/state_machine/integrations.rb +13 -1
  175. data/lib/state_machine/integrations/active_model.rb +14 -20
  176. data/lib/state_machine/integrations/active_model/observer.rb +3 -3
  177. data/lib/state_machine/integrations/active_model/observer_update.rb +42 -0
  178. data/lib/state_machine/integrations/active_record.rb +52 -25
  179. data/lib/state_machine/integrations/active_record/locale.rb +1 -1
  180. data/lib/state_machine/integrations/active_record/versions.rb +1 -17
  181. data/lib/state_machine/integrations/base.rb +15 -6
  182. data/lib/state_machine/integrations/data_mapper.rb +98 -35
  183. data/lib/state_machine/integrations/data_mapper/versions.rb +46 -8
  184. data/lib/state_machine/integrations/mongo_mapper.rb +39 -12
  185. data/lib/state_machine/integrations/mongo_mapper/locale.rb +1 -1
  186. data/lib/state_machine/integrations/mongo_mapper/versions.rb +3 -20
  187. data/lib/state_machine/integrations/mongoid.rb +52 -14
  188. data/lib/state_machine/integrations/mongoid/locale.rb +1 -1
  189. data/lib/state_machine/integrations/mongoid/versions.rb +52 -26
  190. data/lib/state_machine/integrations/sequel.rb +82 -33
  191. data/lib/state_machine/integrations/sequel/versions.rb +19 -44
  192. data/lib/state_machine/machine.rb +99 -59
  193. data/lib/state_machine/machine_collection.rb +1 -2
  194. data/lib/state_machine/macro_methods.rb +29 -0
  195. data/lib/state_machine/node_collection.rb +1 -1
  196. data/lib/state_machine/state.rb +18 -10
  197. data/lib/state_machine/state_context.rb +2 -2
  198. data/lib/state_machine/transition.rb +8 -1
  199. data/lib/state_machine/transition_collection.rb +2 -1
  200. data/lib/state_machine/version.rb +1 -1
  201. data/lib/state_machine/yard.rb +8 -0
  202. data/lib/state_machine/yard/handlers.rb +12 -0
  203. data/lib/state_machine/yard/handlers/base.rb +32 -0
  204. data/lib/state_machine/yard/handlers/event.rb +25 -0
  205. data/lib/state_machine/yard/handlers/machine.rb +344 -0
  206. data/lib/state_machine/yard/handlers/state.rb +25 -0
  207. data/lib/state_machine/yard/handlers/transition.rb +47 -0
  208. data/lib/state_machine/yard/templates.rb +3 -0
  209. data/lib/state_machine/yard/templates/default/class/html/setup.rb +30 -0
  210. data/lib/state_machine/yard/templates/default/class/html/state_machines.erb +12 -0
  211. data/lib/tasks/state_machine.rb +2 -1
  212. data/lib/yard-state_machine.rb +2 -0
  213. data/state_machine.gemspec +4 -3
  214. data/test/files/switch.rb +4 -0
  215. data/test/test_helper.rb +5 -0
  216. data/test/unit/branch_test.rb +117 -36
  217. data/test/unit/callback_test.rb +5 -2
  218. data/test/unit/eval_helpers_test.rb +49 -1
  219. data/test/unit/event_collection_test.rb +3 -1
  220. data/test/unit/event_test.rb +182 -12
  221. data/test/unit/graph_test.rb +98 -0
  222. data/test/unit/integrations/active_model_test.rb +82 -12
  223. data/test/unit/integrations/active_record_test.rb +393 -37
  224. data/test/unit/integrations/base_test.rb +7 -2
  225. data/test/unit/integrations/data_mapper_test.rb +326 -72
  226. data/test/unit/integrations/mongo_mapper_test.rb +338 -44
  227. data/test/unit/integrations/mongoid_test.rb +606 -98
  228. data/test/unit/integrations/sequel_test.rb +429 -102
  229. data/test/unit/integrations_test.rb +28 -6
  230. data/test/unit/machine_collection_test.rb +6 -2
  231. data/test/unit/machine_test.rb +134 -82
  232. data/test/unit/node_collection_test.rb +2 -2
  233. data/test/unit/path_test.rb +1 -1
  234. data/test/unit/state_test.rb +65 -21
  235. data/test/unit/transition_collection_test.rb +43 -23
  236. data/test/unit/transition_test.rb +8 -2
  237. metadata +303 -221
  238. data/gemfiles/active_model-3.2.0.gemfile.lock +0 -32
  239. data/gemfiles/active_record-3.2.0.gemfile.lock +0 -43
  240. data/gemfiles/graphviz-0.9.0.gemfile.lock +0 -26
@@ -5,35 +5,77 @@ require 'mongoid/version'
5
5
 
6
6
  # Establish database connection
7
7
  Mongoid.configure do |config|
8
- config.master = Mongo::Connection.new('127.0.0.1', 27017, :slave_ok => true).db('test')
8
+ if Mongoid::VERSION =~ /^2\./
9
+ connection = Mongo::Connection.new('127.0.0.1', 27017, :slave_ok => true, :logger => Logger.new("#{File.dirname(__FILE__)}/../../mongoid.log"))
10
+ config.master = connection.db('test')
11
+ else
12
+ Mongoid.logger = Moped.logger = Logger.new("#{File.dirname(__FILE__)}/../../mongoid.log")
13
+ config.connect_to('test')
14
+ end
9
15
  end
10
16
 
17
+
11
18
  module MongoidTest
12
19
  class BaseTestCase < Test::Unit::TestCase
13
20
  def default_test
14
21
  end
15
22
 
23
+ def teardown
24
+ if @table_names
25
+ db = Mongoid::VERSION =~ /^2\./ ? Mongoid.master : Mongoid::Sessions.default
26
+ db.collections.each {|c| c.drop if @table_names.include?(c.name)}
27
+ end
28
+ end
29
+
16
30
  protected
17
31
  # Creates a new Mongoid model (and the associated table)
18
- def new_model(table_name = :foo, &block)
32
+ def new_model(name = :foo, &block)
33
+ table_name = "#{name}_#{rand(1000000)}"
34
+ @table_names ||= []
35
+ @table_names << table_name
19
36
 
20
37
  model = Class.new do
21
38
  (class << self; self; end).class_eval do
22
- define_method(:name) { "MongoidTest::#{table_name.to_s.capitalize}" }
23
- define_method(:to_s) { name }
39
+ define_method(:name) { "MongoidTest::#{name.to_s.capitalize}" }
40
+ define_method(:to_s) { self.name }
24
41
  end
25
42
  end
26
43
 
27
44
  model.class_eval do
28
45
  include Mongoid::Document
29
- self.collection_name = table_name
46
+ if Mongoid::VERSION =~ /^2\./
47
+ self.collection_name = table_name
48
+ else
49
+ self.default_collection_name = table_name
50
+ end
30
51
 
31
52
  field :state, :type => String
32
53
  end
33
54
  model.class_eval(&block) if block_given?
34
- model.collection.remove
35
55
  model
36
56
  end
57
+
58
+ # Creates a new Mongoid observer
59
+ def new_observer(model, &block)
60
+ observer = Class.new(Mongoid::Observer) do
61
+ attr_accessor :notifications
62
+
63
+ def initialize
64
+ super
65
+ @notifications = []
66
+ end
67
+ end
68
+
69
+ (class << observer; self; end).class_eval do
70
+ define_method(:name) do
71
+ "#{model.name}Observer"
72
+ end
73
+ end
74
+
75
+ observer.observe(model)
76
+ observer.class_eval(&block) if block_given?
77
+ observer
78
+ end
37
79
  end
38
80
 
39
81
  class IntegrationTest < BaseTestCase
@@ -54,7 +96,7 @@ module MongoidTest
54
96
  end
55
97
 
56
98
  def test_should_have_defaults
57
- assert_equal e = {:action => :save}, StateMachine::Integrations::Mongoid.defaults
99
+ assert_equal({:action => :save}, StateMachine::Integrations::Mongoid.defaults)
58
100
  end
59
101
 
60
102
  def test_should_have_a_locale_path
@@ -123,7 +165,7 @@ module MongoidTest
123
165
 
124
166
  class MachineWithStaticInitialStateTest < BaseTestCase
125
167
  def setup
126
- @model = new_model do
168
+ @model = new_model(:vehicle) do
127
169
  attr_accessor :value
128
170
  end
129
171
  @machine = StateMachine::Machine.new(@model, :initial => :parked)
@@ -155,7 +197,7 @@ module MongoidTest
155
197
 
156
198
  def test_should_set_attributes_prior_to_initialize_block
157
199
  state = nil
158
- record = @model.new do |record|
200
+ @model.new do |record|
159
201
  state = record.state
160
202
  end
161
203
 
@@ -171,10 +213,25 @@ module MongoidTest
171
213
  assert_equal 'parked', state
172
214
  end
173
215
 
216
+ def test_should_persist_initial_state
217
+ record = @model.new
218
+ record.save
219
+ record.reload
220
+ assert_equal 'parked', record.state
221
+ end
222
+
223
+ def test_should_persist_initial_state_on_dup
224
+ record = @model.create.dup
225
+ record.save
226
+ record.reload
227
+ assert_equal 'parked', record.state
228
+ end
229
+
174
230
  def test_should_set_initial_state_before_setting_attributes
175
231
  @model.class_eval do
176
232
  attr_accessor :state_during_setter
177
233
 
234
+ remove_method :value=
178
235
  define_method(:value=) do |value|
179
236
  self.state_during_setter = state
180
237
  end
@@ -189,7 +246,7 @@ module MongoidTest
189
246
  assert_equal 'parked', record.state
190
247
 
191
248
  record.state = 'idling'
192
- record.process({})
249
+ record.attributes = {}
193
250
  assert_equal 'idling', record.state
194
251
  end
195
252
 
@@ -206,6 +263,65 @@ module MongoidTest
206
263
  record = @model.find(@model.create(:state => nil).id)
207
264
  assert_nil record.state
208
265
  end
266
+
267
+ if Mongoid::VERSION >= '2.1.0'
268
+ def test_should_use_stored_values_when_loading_for_many_association
269
+ @machine.state :idling
270
+
271
+ @model.belongs_to :owner, :class_name => 'MongoidTest::Owner'
272
+ MongoidTest.const_set('Vehicle', @model)
273
+
274
+ owner_model = new_model(:owner) do
275
+ has_many :vehicles, :class_name => 'MongoidTest::Vehicle'
276
+ end
277
+ MongoidTest.const_set('Owner', owner_model)
278
+
279
+ owner = owner_model.create
280
+ record = @model.create(:state => 'idling', :owner_id => owner.id)
281
+ assert_equal 'idling', owner.vehicles[0].state
282
+ end
283
+
284
+ def test_should_use_stored_values_when_loading_for_one_association
285
+ @machine.state :idling
286
+
287
+ @model.belongs_to :owner, :class_name => 'MongoidTest::Owner'
288
+ MongoidTest.const_set('Vehicle', @model)
289
+
290
+ owner_model = new_model(:owner) do
291
+ has_one :vehicle, :class_name => 'MongoidTest::Vehicle'
292
+ end
293
+ MongoidTest.const_set('Owner', owner_model)
294
+
295
+ owner = owner_model.create
296
+ record = @model.create(:state => 'idling', :owner_id => owner.id)
297
+ owner.reload
298
+ assert_equal 'idling', owner.vehicle.state
299
+ end
300
+
301
+ def test_should_use_stored_values_when_loading_for_belongs_to_association
302
+ @machine.state :idling
303
+
304
+ MongoidTest.const_set('Vehicle', @model)
305
+
306
+ driver_model = new_model(:driver) do
307
+ belongs_to :vehicle, :class_name => 'MongoidTest::Vehicle'
308
+ end
309
+ MongoidTest.const_set('Driver', driver_model)
310
+
311
+ record = @model.create(:state => 'idling')
312
+ driver = driver_model.create(:vehicle_id => record.id)
313
+ assert_equal 'idling', driver.vehicle.state
314
+ end
315
+ end
316
+
317
+ def teardown
318
+ MongoidTest.class_eval do
319
+ remove_const('Vehicle') if defined?(MongoidTest::Vehicle)
320
+ remove_const('Owner') if defined?(MongoidTest::Owner)
321
+ remove_const('Driver') if defined?(MongoidTest::Driver)
322
+ end
323
+ super
324
+ end
209
325
  end
210
326
 
211
327
  class MachineWithDynamicInitialStateTest < BaseTestCase
@@ -238,7 +354,7 @@ module MongoidTest
238
354
 
239
355
  def test_should_set_attributes_prior_to_initialize_block
240
356
  state = nil
241
- record = @model.new do |record|
357
+ @model.new do |record|
242
358
  state = record.state
243
359
  end
244
360
 
@@ -258,6 +374,7 @@ module MongoidTest
258
374
  @model.class_eval do
259
375
  attr_accessor :state_during_setter
260
376
 
377
+ remove_method :value=
261
378
  define_method(:value=) do |value|
262
379
  self.state_during_setter = state || 'nil'
263
380
  end
@@ -272,10 +389,24 @@ module MongoidTest
272
389
  assert_equal 'parked', record.state
273
390
 
274
391
  record.state = 'idling'
275
- record.process({})
392
+ record.attributes = {}
276
393
  assert_equal 'idling', record.state
277
394
  end
278
395
 
396
+ def test_should_persist_initial_state
397
+ record = @model.new
398
+ record.save
399
+ record.reload
400
+ assert_equal 'parked', record.state
401
+ end
402
+
403
+ def test_should_persist_initial_state_on_dup
404
+ record = @model.create.dup
405
+ record.save
406
+ record.reload
407
+ assert_equal 'parked', record.state
408
+ end
409
+
279
410
  def test_should_use_stored_values_when_loading_from_database
280
411
  @machine.state :idling
281
412
 
@@ -303,8 +434,35 @@ module MongoidTest
303
434
  end
304
435
  end
305
436
 
306
- class MachineWithColumnDefaultTest < BaseTestCase
437
+ class MachineWithDifferentSameDefaultTest < BaseTestCase
307
438
  def setup
439
+ @original_stderr, $stderr = $stderr, StringIO.new
440
+
441
+ @model = new_model do
442
+ field :status, :type => String, :default => 'parked'
443
+ end
444
+ @machine = StateMachine::Machine.new(@model, :status, :initial => :parked)
445
+ @record = @model.new
446
+ end
447
+
448
+ def test_should_use_machine_default
449
+ assert_equal 'parked', @record.status
450
+ end
451
+
452
+ def test_should_not_generate_a_warning
453
+ assert_no_match(/have defined a different default/, $stderr.string)
454
+ end
455
+
456
+ def teardown
457
+ $stderr = @original_stderr
458
+ super
459
+ end
460
+ end
461
+
462
+ class MachineWithDifferentColumnDefaultTest < BaseTestCase
463
+ def setup
464
+ @original_stderr, $stderr = $stderr, StringIO.new
465
+
308
466
  @model = new_model do
309
467
  field :status, :type => String, :default => 'idling'
310
468
  end
@@ -315,6 +473,41 @@ module MongoidTest
315
473
  def test_should_use_machine_default
316
474
  assert_equal 'parked', @record.status
317
475
  end
476
+
477
+ def test_should_generate_a_warning
478
+ assert_match(/Both MongoidTest::Foo and its :status machine have defined a different default for "status". Use only one or the other for defining defaults to avoid unexpected behaviors\./, $stderr.string)
479
+ end
480
+
481
+ def teardown
482
+ $stderr = @original_stderr
483
+ super
484
+ end
485
+ end
486
+
487
+ class MachineWithDifferentIntegerColumnDefaultTest < BaseTestCase
488
+ def setup
489
+ @original_stderr, $stderr = $stderr, StringIO.new
490
+
491
+ @model = new_model do
492
+ field :status, :type => Integer, :default => 0
493
+ end
494
+ @machine = StateMachine::Machine.new(@model, :status, :initial => :parked)
495
+ @machine.state :parked, :value => 1
496
+ @record = @model.new
497
+ end
498
+
499
+ def test_should_use_machine_default
500
+ assert_equal 1, @record.status
501
+ end
502
+
503
+ def test_should_generate_a_warning
504
+ assert_match(/Both MongoidTest::Foo and its :status machine have defined a different default for "status". Use only one or the other for defining defaults to avoid unexpected behaviors\./, $stderr.string)
505
+ end
506
+
507
+ def teardown
508
+ $stderr = @original_stderr
509
+ super
510
+ end
318
511
  end
319
512
 
320
513
  class MachineWithConflictingPredicateTest < BaseTestCase
@@ -346,18 +539,19 @@ module MongoidTest
346
539
  @machine = StateMachine::Machine.new(@model)
347
540
  @machine.state :state
348
541
 
349
- assert_match /^Instance method "state\?" is already defined in .*, use generic helper instead.*\n$/, $stderr.string
542
+ assert_match(/^Instance method "state\?" is already defined in .*, use generic helper instead.*\n$/, $stderr.string)
350
543
  end
351
544
 
352
545
  def test_should_output_warning_with_same_machine_attribute
353
546
  @machine = StateMachine::Machine.new(@model, :public_state, :attribute => :state)
354
547
  @machine.state :state
355
548
 
356
- assert_match /^Instance method "state\?" is already defined in .*, use generic helper instead.*\n$/, $stderr.string
549
+ assert_match(/^Instance method "state\?" is already defined in .*, use generic helper instead.*\n$/, $stderr.string)
357
550
  end
358
551
 
359
552
  def teardown
360
553
  $stderr = @original_stderr
554
+ super
361
555
  end
362
556
  end
363
557
 
@@ -491,6 +685,27 @@ module MongoidTest
491
685
  end
492
686
  end
493
687
 
688
+ class MachineWithAliasedFieldTest < BaseTestCase
689
+ def setup
690
+ @model = new_model do
691
+ field :status, :as => :vehicle_status
692
+ end
693
+
694
+ @machine = StateMachine::Machine.new(@model, :vehicle_status)
695
+ @machine.state :parked
696
+
697
+ @record = @model.new
698
+ end
699
+
700
+ def test_should_check_custom_attribute_for_predicate
701
+ @record.vehicle_status = nil
702
+ assert !@record.vehicle_status?(:parked)
703
+
704
+ @record.vehicle_status = 'parked'
705
+ assert @record.vehicle_status?(:parked)
706
+ end
707
+ end
708
+
494
709
  class MachineWithCustomAttributeTest < BaseTestCase
495
710
  def setup
496
711
  require 'stringio'
@@ -507,6 +722,7 @@ module MongoidTest
507
722
 
508
723
  def teardown
509
724
  $stderr = @original_stderr
725
+ super
510
726
  end
511
727
  end
512
728
 
@@ -544,6 +760,8 @@ module MongoidTest
544
760
  end
545
761
 
546
762
  def test_should_use_default_state_if_protected
763
+ Mongoid.logger = nil
764
+
547
765
  @model.class_eval do
548
766
  attr_protected :state
549
767
  end
@@ -556,7 +774,7 @@ module MongoidTest
556
774
  class MachineMultipleTest < BaseTestCase
557
775
  def setup
558
776
  @model = new_model do
559
- field :status, :type => String, :default => 'idling'
777
+ field :status, :type => String
560
778
  end
561
779
  @state_machine = StateMachine::Machine.new(@model, :initial => :parked)
562
780
  @status_machine = StateMachine::Machine.new(@model, :status, :initial => :idling)
@@ -640,29 +858,19 @@ module MongoidTest
640
858
  @transition.perform(false)
641
859
  end
642
860
 
643
- if ::Mongoid::VERSION =~ /^2\.0\./
644
- def test_should_include_state_in_changed_attributes
645
- assert_equal %w(state), @record.changed
646
- end
647
-
648
- def test_should_not_track_attribute_changes
649
- assert_equal %w(parked parked), @record.send(:attribute_change, 'state')
650
- end
651
- else
652
- def test_should_not_include_state_in_changed_attributes
653
- assert_equal [], @record.changed
654
- end
655
-
656
- def test_should_not_track_attribute_changes
657
- assert_equal nil, @record.send(:attribute_change, 'state')
658
- end
861
+ def test_should_not_include_state_in_changed_attributes
862
+ assert_equal [], @record.changed
863
+ end
864
+
865
+ def test_should_not_track_attribute_changes
866
+ assert_equal nil, @record.send(:attribute_change, 'state')
659
867
  end
660
868
  end
661
869
 
662
870
  class MachineWithDirtyAttributesAndCustomAttributeTest < BaseTestCase
663
871
  def setup
664
872
  @model = new_model do
665
- field :status, :type => String, :default => 'idling'
873
+ field :status, :type => String
666
874
  end
667
875
  @machine = StateMachine::Machine.new(@model, :status, :initial => :parked)
668
876
  @machine.event :ignite
@@ -693,7 +901,7 @@ module MongoidTest
693
901
  class MachineWithDirtyAttributeAndCustomAttributesDuringLoopbackTest < BaseTestCase
694
902
  def setup
695
903
  @model = new_model do
696
- field :status, :type => String, :default => 'idling'
904
+ field :status, :type => String
697
905
  end
698
906
  @machine = StateMachine::Machine.new(@model, :status, :initial => :parked)
699
907
  @machine.event :park
@@ -704,22 +912,12 @@ module MongoidTest
704
912
  @transition.perform(false)
705
913
  end
706
914
 
707
- if ::Mongoid::VERSION =~ /^2\.0\./
708
- def test_should_include_state_in_changed_attributes
709
- assert_equal %w(status), @record.changed
710
- end
711
-
712
- def test_should_track_attribute_changes
713
- assert_equal %w(parked parked), @record.send(:attribute_change, 'status')
714
- end
715
- else
716
- def test_should_include_state_in_changed_attributes
717
- assert_equal [], @record.changed
718
- end
719
-
720
- def test_should_track_attribute_changes
721
- assert_equal nil, @record.send(:attribute_change, 'status')
722
- end
915
+ def test_should_include_state_in_changed_attributes
916
+ assert_equal [], @record.changed
917
+ end
918
+
919
+ def test_should_track_attribute_changes
920
+ assert_equal nil, @record.send(:attribute_change, 'status')
723
921
  end
724
922
  end
725
923
 
@@ -733,34 +931,12 @@ module MongoidTest
733
931
  @record.state_event = 'ignite'
734
932
  end
735
933
 
736
- if ::Mongoid::VERSION =~ /^2\.0\./
737
- def test_should_include_state_in_changed_attributes
738
- assert_equal %w(state), @record.changed
739
- end
740
-
741
- def test_should_track_attribute_change
742
- assert_equal %w(parked parked), @record.send(:attribute_change, 'state')
743
- end
744
-
745
- def test_should_not_reset_changes_on_multiple_changes
746
- @record.state_event = 'ignite'
747
- assert_equal %w(parked parked), @record.send(:attribute_change, 'state')
748
- end
749
-
750
- def test_should_not_include_state_in_changed_attributes_if_nil
751
- @record = @model.create
752
- @record.state_event = nil
753
-
754
- assert_equal [], @record.changed
755
- end
756
- else
757
- def test_should_not_include_state_in_changed_attributes
758
- assert_equal [], @record.changed
759
- end
760
-
761
- def test_should_not_track_attribute_change
762
- assert_equal nil, @record.send(:attribute_change, 'state')
763
- end
934
+ def test_should_not_include_state_in_changed_attributes
935
+ assert_equal [], @record.changed
936
+ end
937
+
938
+ def test_should_not_track_attribute_change
939
+ assert_equal nil, @record.send(:attribute_change, 'state')
764
940
  end
765
941
  end
766
942
 
@@ -858,11 +1034,21 @@ module MongoidTest
858
1034
  def test_should_run_around_callbacks
859
1035
  before_called = false
860
1036
  after_called = false
861
- @machine.around_transition {|block| before_called = true; block.call; after_called = true}
1037
+ ensure_called = 0
1038
+ @machine.around_transition do |block|
1039
+ before_called = true
1040
+ begin
1041
+ block.call
1042
+ ensure
1043
+ ensure_called += 1
1044
+ end
1045
+ after_called = true
1046
+ end
862
1047
 
863
1048
  @transition.perform
864
1049
  assert before_called
865
1050
  assert after_called
1051
+ assert_equal ensure_called, 1
866
1052
  end
867
1053
 
868
1054
  def test_should_include_transition_states_in_known_states
@@ -895,6 +1081,29 @@ module MongoidTest
895
1081
 
896
1082
  assert_equal [1, 2, 3], @record.callback_result
897
1083
  end
1084
+
1085
+ def test_should_run_in_expected_order
1086
+ expected = [
1087
+ :before_transition, :before_validation, :after_validation,
1088
+ :before_save, :before_create, :after_create, :after_save,
1089
+ :after_transition
1090
+ ]
1091
+
1092
+ callbacks = []
1093
+ @model.before_validation { callbacks << :before_validation }
1094
+ @model.after_validation { callbacks << :after_validation }
1095
+ @model.before_save { callbacks << :before_save }
1096
+ @model.before_create { callbacks << :before_create }
1097
+ @model.after_create { callbacks << :after_create }
1098
+ @model.after_save { callbacks << :after_save }
1099
+
1100
+ @machine.before_transition { callbacks << :before_transition }
1101
+ @machine.after_transition { callbacks << :after_transition }
1102
+
1103
+ @transition.perform
1104
+
1105
+ assert_equal expected, callbacks
1106
+ end
898
1107
  end
899
1108
 
900
1109
  class MachineWithFailedBeforeCallbacksTest < BaseTestCase
@@ -932,6 +1141,44 @@ module MongoidTest
932
1141
  end
933
1142
  end
934
1143
 
1144
+ class MachineNestedActionTest < BaseTestCase
1145
+ def setup
1146
+ @callbacks = []
1147
+
1148
+ @model = new_model
1149
+ @machine = StateMachine::Machine.new(@model)
1150
+ @machine.event :ignite do
1151
+ transition :parked => :idling
1152
+ end
1153
+
1154
+ @record = @model.new(:state => 'parked')
1155
+ end
1156
+
1157
+ def test_should_allow_transition_prior_to_creation_if_skipping_action
1158
+ record = @record
1159
+ @model.before_create { record.ignite(false) }
1160
+ result = @record.save
1161
+
1162
+ assert_equal true, result
1163
+ assert_equal "idling", @record.state
1164
+ @record.reload
1165
+ assert_equal "idling", @record.state
1166
+ end
1167
+
1168
+ if Mongoid::VERSION !~ /^2\.1\./
1169
+ def test_should_allow_transition_after_creation
1170
+ record = @record
1171
+ @model.after_create { record.ignite }
1172
+ result = @record.save
1173
+
1174
+ assert_equal true, result
1175
+ assert_equal "idling", @record.state
1176
+ @record.reload
1177
+ assert_equal "idling", @record.state
1178
+ end
1179
+ end
1180
+ end
1181
+
935
1182
  class MachineWithFailedActionTest < BaseTestCase
936
1183
  def setup
937
1184
  @model = new_model do
@@ -971,7 +1218,7 @@ module MongoidTest
971
1218
  end
972
1219
 
973
1220
  class MachineWithFailedAfterCallbacksTest < BaseTestCase
974
- def setup
1221
+ def setup
975
1222
  @callbacks = []
976
1223
 
977
1224
  @model = new_model
@@ -1051,10 +1298,7 @@ module MongoidTest
1051
1298
 
1052
1299
  class MachineWithValidationsAndCustomAttributeTest < BaseTestCase
1053
1300
  def setup
1054
- @model = new_model do
1055
- alias_attribute :status, :state
1056
- end
1057
-
1301
+ @model = new_model
1058
1302
  @machine = StateMachine::Machine.new(@model, :status, :attribute => :state)
1059
1303
  @machine.state :parked
1060
1304
 
@@ -1163,7 +1407,11 @@ module MongoidTest
1163
1407
  ran_callback = false
1164
1408
  @machine.around_transition {|block| ran_callback = true; block.call }
1165
1409
 
1166
- @record.valid?
1410
+ begin
1411
+ @record.valid?
1412
+ rescue ArgumentError
1413
+ raise if StateMachine::Transition.pause_supported?
1414
+ end
1167
1415
  assert ran_callback
1168
1416
  end
1169
1417
 
@@ -1197,7 +1445,11 @@ module MongoidTest
1197
1445
  ran_callback = false
1198
1446
  @machine.around_transition {|block| block.call; ran_callback = true }
1199
1447
 
1200
- @record.valid?
1448
+ begin
1449
+ @record.valid?
1450
+ rescue ArgumentError
1451
+ raise if StateMachine::Transition.pause_supported?
1452
+ end
1201
1453
  assert !ran_callback
1202
1454
  end
1203
1455
 
@@ -1343,6 +1595,85 @@ module MongoidTest
1343
1595
  @record.save
1344
1596
  assert ran_callback
1345
1597
  end
1598
+
1599
+ def test_should_allow_additional_transitions_to_new_state_in_after_transitions
1600
+ @machine.event :park do
1601
+ transition :idling => :parked
1602
+ end
1603
+
1604
+ @machine.after_transition(:on => :ignite) { @record.park }
1605
+
1606
+ @record.save
1607
+ assert_equal 'parked', @record.state
1608
+
1609
+ @record.reload
1610
+ assert_equal 'parked', @record.state
1611
+ end
1612
+
1613
+ def test_should_allow_additional_transitions_to_previous_state_in_after_transitions
1614
+ @machine.event :shift_up do
1615
+ transition :idling => :first_gear
1616
+ end
1617
+
1618
+ @machine.after_transition(:on => :ignite) { @record.shift_up }
1619
+
1620
+ @record.save
1621
+ assert_equal 'first_gear', @record.state
1622
+
1623
+ @record.reload
1624
+ assert_equal 'first_gear', @record.state
1625
+ end
1626
+ end
1627
+
1628
+ if Mongoid::VERSION >= '2.1.0'
1629
+ class MachineWithEventAttributesOnAutosaveTest < BaseTestCase
1630
+ def setup
1631
+ @vehicle_model = new_model(:vehicle) do
1632
+ belongs_to :owner, :class_name => 'MongoidTest::Owner'
1633
+ end
1634
+ MongoidTest.const_set('Vehicle', @vehicle_model)
1635
+
1636
+ @owner_model = new_model(:owner)
1637
+ MongoidTest.const_set('Owner', @owner_model)
1638
+
1639
+ machine = StateMachine::Machine.new(@vehicle_model)
1640
+ machine.event :ignite do
1641
+ transition :parked => :idling
1642
+ end
1643
+
1644
+ @owner = @owner_model.create
1645
+ end
1646
+
1647
+ def test_should_persist_many_association
1648
+ @owner_model.has_many :vehicles, :class_name => 'MongoidTest::Vehicle', :autosave => true
1649
+ @vehicle = @vehicle_model.create(:state => 'parked', :owner_id => @owner.id)
1650
+
1651
+ @owner.vehicles[0].state_event = 'ignite'
1652
+ @owner.save
1653
+
1654
+ @vehicle.reload
1655
+ assert_equal 'idling', @vehicle.state
1656
+ end
1657
+
1658
+ def test_should_persist_one_association
1659
+ @owner_model.has_one :vehicle, :class_name => 'MongoidTest::Vehicle', :autosave => true
1660
+ @vehicle = @vehicle_model.create(:state => 'parked', :owner_id => @owner.id)
1661
+
1662
+ @owner.vehicle.state_event = 'ignite'
1663
+ @owner.save
1664
+
1665
+ @vehicle.reload
1666
+ assert_equal 'idling', @vehicle.state
1667
+ end
1668
+
1669
+ def teardown
1670
+ MongoidTest.class_eval do
1671
+ remove_const('Vehicle')
1672
+ remove_const('Owner')
1673
+ end
1674
+ super
1675
+ end
1676
+ end
1346
1677
  end
1347
1678
 
1348
1679
  class MachineWithEventAttributesOnSaveBangTest < BaseTestCase
@@ -1409,11 +1740,6 @@ module MongoidTest
1409
1740
  assert_equal 'idling', @record.state
1410
1741
  end
1411
1742
 
1412
- def test_should_persist_new_state
1413
- @record.save!
1414
- assert_equal 'idling', @record.state
1415
- end
1416
-
1417
1743
  def test_should_run_after_callbacks
1418
1744
  ran_callback = false
1419
1745
  @machine.after_transition { ran_callback = true }
@@ -1470,6 +1796,186 @@ module MongoidTest
1470
1796
  end
1471
1797
  end
1472
1798
 
1799
+ class MachineWithObserversTest < BaseTestCase
1800
+ def setup
1801
+ @model = new_model
1802
+ @machine = StateMachine::Machine.new(@model)
1803
+ @machine.state :parked, :idling
1804
+ @machine.event :ignite
1805
+ @record = @model.new(:state => 'parked')
1806
+ @transition = StateMachine::Transition.new(@record, @machine, :ignite, :parked, :idling)
1807
+ end
1808
+
1809
+ def test_should_call_all_transition_callback_permutations
1810
+ callbacks = [
1811
+ :before_ignite_from_parked_to_idling,
1812
+ :before_ignite_from_parked,
1813
+ :before_ignite_to_idling,
1814
+ :before_ignite,
1815
+ :before_transition_state_from_parked_to_idling,
1816
+ :before_transition_state_from_parked,
1817
+ :before_transition_state_to_idling,
1818
+ :before_transition_state,
1819
+ :before_transition
1820
+ ]
1821
+
1822
+ observer = new_observer(@model) do
1823
+ callbacks.each do |callback|
1824
+ define_method(callback) do |*args|
1825
+ notifications << callback
1826
+ end
1827
+ end
1828
+ end
1829
+
1830
+ instance = observer.instance
1831
+
1832
+ @transition.perform
1833
+ assert_equal callbacks, instance.notifications
1834
+ end
1835
+
1836
+ def test_should_call_no_transition_callbacks_when_observers_disabled
1837
+ return unless ::ActiveModel::VERSION::MAJOR >= 3 && ::ActiveModel::VERSION::MINOR >= 1
1838
+
1839
+ callbacks = [
1840
+ :before_ignite,
1841
+ :before_transition
1842
+ ]
1843
+
1844
+ observer = new_observer(@model) do
1845
+ callbacks.each do |callback|
1846
+ define_method(callback) do |*args|
1847
+ notifications << callback
1848
+ end
1849
+ end
1850
+ end
1851
+
1852
+ instance = observer.instance
1853
+
1854
+ @model.observers.disable(observer) do
1855
+ @transition.perform
1856
+ end
1857
+
1858
+ assert_equal [], instance.notifications
1859
+ end
1860
+
1861
+ def test_should_pass_record_and_transition_to_before_callbacks
1862
+ observer = new_observer(@model) do
1863
+ def before_transition(*args)
1864
+ notifications << args
1865
+ end
1866
+ end
1867
+ instance = observer.instance
1868
+
1869
+ @transition.perform
1870
+ assert_equal [[@record, @transition]], instance.notifications
1871
+ end
1872
+
1873
+ def test_should_pass_record_and_transition_to_after_callbacks
1874
+ observer = new_observer(@model) do
1875
+ def after_transition(*args)
1876
+ notifications << args
1877
+ end
1878
+ end
1879
+ instance = observer.instance
1880
+
1881
+ @transition.perform
1882
+ assert_equal [[@record, @transition]], instance.notifications
1883
+ end
1884
+
1885
+ def test_should_call_methods_outside_the_context_of_the_record
1886
+ observer = new_observer(@model) do
1887
+ def before_ignite(*args)
1888
+ notifications << self
1889
+ end
1890
+ end
1891
+ instance = observer.instance
1892
+
1893
+ @transition.perform
1894
+ assert_equal [instance], instance.notifications
1895
+ end
1896
+
1897
+ def test_should_support_nil_from_states
1898
+ callbacks = [
1899
+ :before_ignite_from_nil_to_idling,
1900
+ :before_ignite_from_nil,
1901
+ :before_transition_state_from_nil_to_idling,
1902
+ :before_transition_state_from_nil
1903
+ ]
1904
+
1905
+ observer = new_observer(@model) do
1906
+ callbacks.each do |callback|
1907
+ define_method(callback) do |*args|
1908
+ notifications << callback
1909
+ end
1910
+ end
1911
+ end
1912
+
1913
+ instance = observer.instance
1914
+
1915
+ transition = StateMachine::Transition.new(@record, @machine, :ignite, nil, :idling)
1916
+ transition.perform
1917
+ assert_equal callbacks, instance.notifications
1918
+ end
1919
+
1920
+ def test_should_support_nil_to_states
1921
+ callbacks = [
1922
+ :before_ignite_from_parked_to_nil,
1923
+ :before_ignite_to_nil,
1924
+ :before_transition_state_from_parked_to_nil,
1925
+ :before_transition_state_to_nil
1926
+ ]
1927
+
1928
+ observer = new_observer(@model) do
1929
+ callbacks.each do |callback|
1930
+ define_method(callback) do |*args|
1931
+ notifications << callback
1932
+ end
1933
+ end
1934
+ end
1935
+
1936
+ instance = observer.instance
1937
+
1938
+ transition = StateMachine::Transition.new(@record, @machine, :ignite, :parked, nil)
1939
+ transition.perform
1940
+ assert_equal callbacks, instance.notifications
1941
+ end
1942
+ end
1943
+
1944
+ class MachineWithNamespacedObserversTest < BaseTestCase
1945
+ def setup
1946
+ @model = new_model
1947
+ @machine = StateMachine::Machine.new(@model, :state, :namespace => 'alarm')
1948
+ @machine.state :active, :off
1949
+ @machine.event :enable
1950
+ @record = @model.new(:state => 'off')
1951
+ @transition = StateMachine::Transition.new(@record, @machine, :enable, :off, :active)
1952
+ end
1953
+
1954
+ def test_should_call_namespaced_before_event_method
1955
+ observer = new_observer(@model) do
1956
+ def before_enable_alarm(*args)
1957
+ notifications << args
1958
+ end
1959
+ end
1960
+ instance = observer.instance
1961
+
1962
+ @transition.perform
1963
+ assert_equal [[@record, @transition]], instance.notifications
1964
+ end
1965
+
1966
+ def test_should_call_namespaced_after_event_method
1967
+ observer = new_observer(@model) do
1968
+ def after_enable_alarm(*args)
1969
+ notifications << args
1970
+ end
1971
+ end
1972
+ instance = observer.instance
1973
+
1974
+ @transition.perform
1975
+ assert_equal [[@record, @transition]], instance.notifications
1976
+ end
1977
+ end
1978
+
1473
1979
  class MachineWithScopesTest < BaseTestCase
1474
1980
  def setup
1475
1981
  @model = new_model
@@ -1484,7 +1990,7 @@ module MongoidTest
1484
1990
 
1485
1991
  def test_should_only_include_records_with_state_in_singular_with_scope
1486
1992
  parked = @model.create :state => 'parked'
1487
- idling = @model.create :state => 'idling'
1993
+ @model.create :state => 'idling'
1488
1994
 
1489
1995
  assert_equal [parked], @model.with_state(:parked).to_a
1490
1996
  end
@@ -1545,15 +2051,16 @@ module MongoidTest
1545
2051
 
1546
2052
  MongoidTest.const_set('Foo', @model)
1547
2053
 
1548
- @subclass = Class.new(@model) do
1549
- def self.name
1550
- 'MongoidTest::SubFoo'
2054
+ # Remove the #name override so that Mongoid picks up the subclass name
2055
+ # properly
2056
+ class << @model; remove_method(:name); end
2057
+ @subclass = MongoidTest.class_eval <<-end_eval
2058
+ class SubFoo < MongoidTest::Foo
2059
+ self
1551
2060
  end
1552
- end
2061
+ end_eval
1553
2062
  @subclass_machine = @subclass.state_machine(:state) {}
1554
2063
  @subclass_machine.state :parked, :idling, :first_gear
1555
-
1556
- MongoidTest.const_set('SubFoo', @subclass)
1557
2064
  end
1558
2065
 
1559
2066
  def test_should_only_include_records_with_subclass_states_in_with_scope
@@ -1574,6 +2081,7 @@ module MongoidTest
1574
2081
  def teardown
1575
2082
  MongoidTest.send(:remove_const, 'SubFoo')
1576
2083
  MongoidTest.send(:remove_const, 'Foo')
2084
+ super
1577
2085
  end
1578
2086
  end
1579
2087