state_machine 1.1.2 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
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