PageRenderTime 31ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 1ms

/test/unit/integrations/mongoid_test.rb

http://github.com/pluginaweek/state_machine
Ruby | 2309 lines | 1813 code | 488 blank | 8 comment | 21 complexity | bee31ce6161738201ee4966e87460580 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

  1. require File.expand_path(File.dirname(__FILE__) + '/../../test_helper')
  2. require 'mongoid'
  3. require 'mongoid/version'
  4. # Establish database connection
  5. Mongoid.configure do |config|
  6. if Mongoid::VERSION =~ /^2\./
  7. connection = Mongo::Connection.new('127.0.0.1', 27017, :slave_ok => true, :logger => Logger.new("#{File.dirname(__FILE__)}/../../mongoid.log"))
  8. config.master = connection.db('test')
  9. else
  10. Mongoid.logger = Moped.logger = Logger.new("#{File.dirname(__FILE__)}/../../mongoid.log")
  11. config.connect_to('test')
  12. end
  13. end
  14. module MongoidTest
  15. class BaseTestCase < Test::Unit::TestCase
  16. def default_test
  17. end
  18. def teardown
  19. if @table_names
  20. db = Mongoid::VERSION =~ /^2\./ ? Mongoid.master : Mongoid::Sessions.default
  21. db.collections.each {|c| c.drop if @table_names.include?(c.name)}
  22. end
  23. end
  24. protected
  25. # Creates a new Mongoid model (and the associated table)
  26. def new_model(name = :foo, &block)
  27. table_name = "#{name}_#{rand(1000000)}"
  28. @table_names ||= []
  29. @table_names << table_name
  30. model = Class.new do
  31. (class << self; self; end).class_eval do
  32. define_method(:name) { "MongoidTest::#{name.to_s.capitalize}" }
  33. define_method(:to_s) { self.name }
  34. end
  35. end
  36. model.class_eval do
  37. include Mongoid::Document
  38. if Mongoid::VERSION =~ /^2\./
  39. self.collection_name = table_name
  40. else
  41. self.default_collection_name = table_name
  42. end
  43. field :state, :type => String
  44. end
  45. model.class_eval(&block) if block_given?
  46. model
  47. end
  48. # Creates a new Mongoid observer
  49. def new_observer(model, &block)
  50. observer = Class.new(Mongoid::Observer) do
  51. attr_accessor :notifications
  52. def initialize
  53. super
  54. @notifications = []
  55. end
  56. end
  57. (class << observer; self; end).class_eval do
  58. define_method(:name) do
  59. "#{model.name}Observer"
  60. end
  61. end
  62. observer.observe(model)
  63. observer.class_eval(&block) if block_given?
  64. observer
  65. end
  66. end
  67. class IntegrationTest < BaseTestCase
  68. def test_should_have_an_integration_name
  69. assert_equal :mongoid, StateMachine::Integrations::Mongoid.integration_name
  70. end
  71. def test_should_be_available
  72. assert StateMachine::Integrations::Mongoid.available?
  73. end
  74. def test_should_match_if_class_includes_mongoid
  75. assert StateMachine::Integrations::Mongoid.matches?(new_model)
  76. end
  77. def test_should_not_match_if_class_does_not_include_mongoid
  78. assert !StateMachine::Integrations::Mongoid.matches?(Class.new)
  79. end
  80. def test_should_have_defaults
  81. assert_equal({:action => :save}, StateMachine::Integrations::Mongoid.defaults)
  82. end
  83. def test_should_have_a_locale_path
  84. assert_not_nil StateMachine::Integrations::Mongoid.locale_path
  85. end
  86. end
  87. class MachineWithoutFieldTest < BaseTestCase
  88. def setup
  89. @model = new_model
  90. StateMachine::Machine.new(@model, :status)
  91. end
  92. def test_should_define_field_with_string_type
  93. field = @model.fields['status']
  94. assert_not_nil field
  95. assert_equal String, field.type
  96. end
  97. end
  98. class MachineWithFieldTest < BaseTestCase
  99. def setup
  100. @model = new_model do
  101. field :status, :type => Integer
  102. end
  103. StateMachine::Machine.new(@model, :status)
  104. end
  105. def test_should_not_redefine_field
  106. field = @model.fields['status']
  107. assert_not_nil field
  108. assert_equal Integer, field.type
  109. end
  110. end
  111. class MachineByDefaultTest < BaseTestCase
  112. def setup
  113. @model = new_model
  114. @machine = StateMachine::Machine.new(@model)
  115. end
  116. def test_should_use_save_as_action
  117. assert_equal :save, @machine.action
  118. end
  119. def test_should_create_notifier_before_callback
  120. assert_equal 1, @machine.callbacks[:before].size
  121. end
  122. def test_should_create_notifier_after_callback
  123. assert_equal 1, @machine.callbacks[:after].size
  124. end
  125. end
  126. class MachineWithStatesTest < BaseTestCase
  127. def setup
  128. @model = new_model
  129. @machine = StateMachine::Machine.new(@model)
  130. @machine.state :first_gear
  131. end
  132. def test_should_humanize_name
  133. assert_equal 'first gear', @machine.state(:first_gear).human_name
  134. end
  135. end
  136. class MachineWithStaticInitialStateTest < BaseTestCase
  137. def setup
  138. @model = new_model(:vehicle) do
  139. attr_accessor :value
  140. end
  141. @machine = StateMachine::Machine.new(@model, :initial => :parked)
  142. end
  143. def test_should_set_initial_state_on_created_object
  144. record = @model.new
  145. assert_equal 'parked', record.state
  146. end
  147. def test_should_set_initial_state_with_nil_attributes
  148. record = @model.new(nil)
  149. assert_equal 'parked', record.state
  150. end
  151. def test_should_still_set_attributes
  152. record = @model.new(:value => 1)
  153. assert_equal 1, record.value
  154. end
  155. def test_should_still_allow_initialize_blocks
  156. block_args = nil
  157. record = @model.new do |*args|
  158. block_args = args
  159. end
  160. assert_equal [record], block_args
  161. end
  162. def test_should_set_attributes_prior_to_initialize_block
  163. state = nil
  164. @model.new do |record|
  165. state = record.state
  166. end
  167. assert_equal 'parked', state
  168. end
  169. def test_should_set_attributes_prior_to_after_initialize_hook
  170. state = nil
  171. @model.after_initialize do |record|
  172. state = record.state
  173. end
  174. @model.new
  175. assert_equal 'parked', state
  176. end
  177. def test_should_persist_initial_state
  178. record = @model.new
  179. record.save
  180. record.reload
  181. assert_equal 'parked', record.state
  182. end
  183. def test_should_persist_initial_state_on_dup
  184. record = @model.create.dup
  185. record.save
  186. record.reload
  187. assert_equal 'parked', record.state
  188. end
  189. def test_should_set_initial_state_before_setting_attributes
  190. @model.class_eval do
  191. attr_accessor :state_during_setter
  192. remove_method :value=
  193. define_method(:value=) do |value|
  194. self.state_during_setter = state
  195. end
  196. end
  197. record = @model.new(:value => 1)
  198. assert_equal 'parked', record.state_during_setter
  199. end
  200. def test_should_not_set_initial_state_after_already_initialized
  201. record = @model.new(:value => 1)
  202. assert_equal 'parked', record.state
  203. record.state = 'idling'
  204. record.attributes = {}
  205. assert_equal 'idling', record.state
  206. end
  207. def test_should_use_stored_values_when_loading_from_database
  208. @machine.state :idling
  209. record = @model.find(@model.create(:state => 'idling').id)
  210. assert_equal 'idling', record.state
  211. end
  212. def test_should_use_stored_values_when_loading_from_database_with_nil_state
  213. @machine.state nil
  214. record = @model.find(@model.create(:state => nil).id)
  215. assert_nil record.state
  216. end
  217. if Mongoid::VERSION >= '2.1.0'
  218. def test_should_use_stored_values_when_loading_for_many_association
  219. @machine.state :idling
  220. @model.belongs_to :owner, :class_name => 'MongoidTest::Owner'
  221. MongoidTest.const_set('Vehicle', @model)
  222. owner_model = new_model(:owner) do
  223. has_many :vehicles, :class_name => 'MongoidTest::Vehicle'
  224. end
  225. MongoidTest.const_set('Owner', owner_model)
  226. owner = owner_model.create
  227. record = @model.create(:state => 'idling', :owner_id => owner.id)
  228. assert_equal 'idling', owner.vehicles[0].state
  229. end
  230. def test_should_use_stored_values_when_loading_for_one_association
  231. @machine.state :idling
  232. @model.belongs_to :owner, :class_name => 'MongoidTest::Owner'
  233. MongoidTest.const_set('Vehicle', @model)
  234. owner_model = new_model(:owner) do
  235. has_one :vehicle, :class_name => 'MongoidTest::Vehicle'
  236. end
  237. MongoidTest.const_set('Owner', owner_model)
  238. owner = owner_model.create
  239. record = @model.create(:state => 'idling', :owner_id => owner.id)
  240. owner.reload
  241. assert_equal 'idling', owner.vehicle.state
  242. end
  243. def test_should_use_stored_values_when_loading_for_belongs_to_association
  244. @machine.state :idling
  245. MongoidTest.const_set('Vehicle', @model)
  246. driver_model = new_model(:driver) do
  247. belongs_to :vehicle, :class_name => 'MongoidTest::Vehicle'
  248. end
  249. MongoidTest.const_set('Driver', driver_model)
  250. record = @model.create(:state => 'idling')
  251. driver = driver_model.create(:vehicle_id => record.id)
  252. assert_equal 'idling', driver.vehicle.state
  253. end
  254. end
  255. def teardown
  256. MongoidTest.class_eval do
  257. remove_const('Vehicle') if defined?(MongoidTest::Vehicle)
  258. remove_const('Owner') if defined?(MongoidTest::Owner)
  259. remove_const('Driver') if defined?(MongoidTest::Driver)
  260. end
  261. super
  262. end
  263. end
  264. class MachineWithDynamicInitialStateTest < BaseTestCase
  265. def setup
  266. @model = new_model do
  267. attr_accessor :value
  268. end
  269. @machine = StateMachine::Machine.new(@model, :initial => lambda {|object| :parked})
  270. @machine.state :parked
  271. end
  272. def test_should_set_initial_state_on_created_object
  273. record = @model.new
  274. assert_equal 'parked', record.state
  275. end
  276. def test_should_still_set_attributes
  277. record = @model.new(:value => 1)
  278. assert_equal 1, record.value
  279. end
  280. def test_should_still_allow_initialize_blocks
  281. block_args = nil
  282. record = @model.new do |*args|
  283. block_args = args
  284. end
  285. assert_equal [record], block_args
  286. end
  287. def test_should_set_attributes_prior_to_initialize_block
  288. state = nil
  289. @model.new do |record|
  290. state = record.state
  291. end
  292. assert_equal 'parked', state
  293. end
  294. def test_should_set_attributes_prior_to_after_initialize_hook
  295. state = nil
  296. @model.after_initialize do |record|
  297. state = record.state
  298. end
  299. @model.new
  300. assert_equal 'parked', state
  301. end
  302. def test_should_set_initial_state_after_setting_attributes
  303. @model.class_eval do
  304. attr_accessor :state_during_setter
  305. remove_method :value=
  306. define_method(:value=) do |value|
  307. self.state_during_setter = state || 'nil'
  308. end
  309. end
  310. record = @model.new(:value => 1)
  311. assert_equal 'nil', record.state_during_setter
  312. end
  313. def test_should_not_set_initial_state_after_already_initialized
  314. record = @model.new(:value => 1)
  315. assert_equal 'parked', record.state
  316. record.state = 'idling'
  317. record.attributes = {}
  318. assert_equal 'idling', record.state
  319. end
  320. def test_should_persist_initial_state
  321. record = @model.new
  322. record.save
  323. record.reload
  324. assert_equal 'parked', record.state
  325. end
  326. def test_should_persist_initial_state_on_dup
  327. record = @model.create.dup
  328. record.save
  329. record.reload
  330. assert_equal 'parked', record.state
  331. end
  332. def test_should_use_stored_values_when_loading_from_database
  333. @machine.state :idling
  334. record = @model.find(@model.create(:state => 'idling').id)
  335. assert_equal 'idling', record.state
  336. end
  337. def test_should_use_stored_values_when_loading_from_database_with_nil_state
  338. @machine.state nil
  339. record = @model.find(@model.create(:state => nil).id)
  340. assert_nil record.state
  341. end
  342. end
  343. class MachineWithEventsTest < BaseTestCase
  344. def setup
  345. @model = new_model
  346. @machine = StateMachine::Machine.new(@model)
  347. @machine.event :shift_up
  348. end
  349. def test_should_humanize_name
  350. assert_equal 'shift up', @machine.event(:shift_up).human_name
  351. end
  352. end
  353. class MachineWithDifferentSameDefaultTest < BaseTestCase
  354. def setup
  355. @original_stderr, $stderr = $stderr, StringIO.new
  356. @model = new_model do
  357. field :status, :type => String, :default => 'parked'
  358. end
  359. @machine = StateMachine::Machine.new(@model, :status, :initial => :parked)
  360. @record = @model.new
  361. end
  362. def test_should_use_machine_default
  363. assert_equal 'parked', @record.status
  364. end
  365. def test_should_not_generate_a_warning
  366. assert_no_match(/have defined a different default/, $stderr.string)
  367. end
  368. def teardown
  369. $stderr = @original_stderr
  370. super
  371. end
  372. end
  373. class MachineWithDifferentColumnDefaultTest < BaseTestCase
  374. def setup
  375. @original_stderr, $stderr = $stderr, StringIO.new
  376. @model = new_model do
  377. field :status, :type => String, :default => 'idling'
  378. end
  379. @machine = StateMachine::Machine.new(@model, :status, :initial => :parked)
  380. @record = @model.new
  381. end
  382. def test_should_use_machine_default
  383. assert_equal 'parked', @record.status
  384. end
  385. def test_should_generate_a_warning
  386. 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)
  387. end
  388. def teardown
  389. $stderr = @original_stderr
  390. super
  391. end
  392. end
  393. class MachineWithDifferentIntegerColumnDefaultTest < BaseTestCase
  394. def setup
  395. @original_stderr, $stderr = $stderr, StringIO.new
  396. @model = new_model do
  397. field :status, :type => Integer, :default => 0
  398. end
  399. @machine = StateMachine::Machine.new(@model, :status, :initial => :parked)
  400. @machine.state :parked, :value => 1
  401. @record = @model.new
  402. end
  403. def test_should_use_machine_default
  404. assert_equal 1, @record.status
  405. end
  406. def test_should_generate_a_warning
  407. 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)
  408. end
  409. def teardown
  410. $stderr = @original_stderr
  411. super
  412. end
  413. end
  414. class MachineWithConflictingPredicateTest < BaseTestCase
  415. def setup
  416. @model = new_model do
  417. def state?(*args)
  418. true
  419. end
  420. end
  421. @machine = StateMachine::Machine.new(@model)
  422. @record = @model.new
  423. end
  424. def test_should_not_define_attribute_predicate
  425. assert @record.state?
  426. end
  427. end
  428. class MachineWithConflictingStateNameTest < BaseTestCase
  429. def setup
  430. require 'stringio'
  431. @original_stderr, $stderr = $stderr, StringIO.new
  432. @model = new_model
  433. end
  434. def test_should_output_warning_with_same_machine_name
  435. @machine = StateMachine::Machine.new(@model)
  436. @machine.state :state
  437. assert_match(/^Instance method "state\?" is already defined in .*, use generic helper instead.*\n$/, $stderr.string)
  438. end
  439. def test_should_output_warning_with_same_machine_attribute
  440. @machine = StateMachine::Machine.new(@model, :public_state, :attribute => :state)
  441. @machine.state :state
  442. assert_match(/^Instance method "state\?" is already defined in .*, use generic helper instead.*\n$/, $stderr.string)
  443. end
  444. def teardown
  445. $stderr = @original_stderr
  446. super
  447. end
  448. end
  449. class MachineWithColumnStateAttributeTest < BaseTestCase
  450. def setup
  451. @model = new_model
  452. @machine = StateMachine::Machine.new(@model, :initial => :parked)
  453. @machine.other_states(:idling)
  454. @record = @model.new
  455. end
  456. def test_should_not_override_the_column_reader
  457. @record[:state] = 'parked'
  458. assert_equal 'parked', @record.state
  459. end
  460. def test_should_not_override_the_column_writer
  461. @record.state = 'parked'
  462. assert_equal 'parked', @record[:state]
  463. end
  464. def test_should_have_an_attribute_predicate
  465. assert @record.respond_to?(:state?)
  466. end
  467. def test_should_test_for_existence_on_predicate_without_parameters
  468. assert @record.state?
  469. @record.state = nil
  470. assert !@record.state?
  471. end
  472. def test_should_return_false_for_predicate_if_does_not_match_current_value
  473. assert !@record.state?(:idling)
  474. end
  475. def test_should_return_true_for_predicate_if_matches_current_value
  476. assert @record.state?(:parked)
  477. end
  478. def test_should_raise_exception_for_predicate_if_invalid_state_specified
  479. assert_raise(IndexError) { @record.state?(:invalid) }
  480. end
  481. end
  482. class MachineWithNonColumnStateAttributeUndefinedTest < BaseTestCase
  483. def setup
  484. @model = new_model do
  485. def initialize
  486. # Skip attribute initialization
  487. @initialized_state_machines = true
  488. super
  489. end
  490. end
  491. @machine = StateMachine::Machine.new(@model, :status, :initial => :parked)
  492. @machine.other_states(:idling)
  493. @record = @model.new
  494. end
  495. def test_should_define_a_new_key_for_the_attribute
  496. assert_not_nil @model.fields['status']
  497. end
  498. def test_should_define_a_reader_attribute_for_the_attribute
  499. assert @record.respond_to?(:status)
  500. end
  501. def test_should_define_a_writer_attribute_for_the_attribute
  502. assert @record.respond_to?(:status=)
  503. end
  504. def test_should_define_an_attribute_predicate
  505. assert @record.respond_to?(:status?)
  506. end
  507. end
  508. class MachineWithNonColumnStateAttributeDefinedTest < BaseTestCase
  509. def setup
  510. @model = new_model do
  511. def status
  512. self['status']
  513. end
  514. def status=(value)
  515. self['status'] = value
  516. end
  517. end
  518. @machine = StateMachine::Machine.new(@model, :status, :initial => :parked)
  519. @machine.other_states(:idling)
  520. @record = @model.new
  521. end
  522. def test_should_return_false_for_predicate_if_does_not_match_current_value
  523. assert !@record.status?(:idling)
  524. end
  525. def test_should_return_true_for_predicate_if_matches_current_value
  526. assert @record.status?(:parked)
  527. end
  528. def test_should_raise_exception_for_predicate_if_invalid_state_specified
  529. assert_raise(IndexError) { @record.status?(:invalid) }
  530. end
  531. def test_should_set_initial_state_on_created_object
  532. assert_equal 'parked', @record.status
  533. end
  534. end
  535. class MachineWithAliasedAttributeTest < BaseTestCase
  536. def setup
  537. @model = new_model do
  538. alias_attribute :vehicle_status, :state
  539. end
  540. @machine = StateMachine::Machine.new(@model, :status, :attribute => :vehicle_status)
  541. @machine.state :parked
  542. @record = @model.new
  543. end
  544. def test_should_check_custom_attribute_for_predicate
  545. @record.vehicle_status = nil
  546. assert !@record.status?(:parked)
  547. @record.vehicle_status = 'parked'
  548. assert @record.status?(:parked)
  549. end
  550. end
  551. class MachineWithAliasedFieldTest < BaseTestCase
  552. def setup
  553. @model = new_model do
  554. field :status, :as => :vehicle_status
  555. end
  556. @machine = StateMachine::Machine.new(@model, :vehicle_status)
  557. @machine.state :parked
  558. @record = @model.new
  559. end
  560. def test_should_check_custom_attribute_for_predicate
  561. @record.vehicle_status = nil
  562. assert !@record.vehicle_status?(:parked)
  563. @record.vehicle_status = 'parked'
  564. assert @record.vehicle_status?(:parked)
  565. end
  566. end
  567. class MachineWithCustomAttributeTest < BaseTestCase
  568. def setup
  569. require 'stringio'
  570. @original_stderr, $stderr = $stderr, StringIO.new
  571. @model = new_model
  572. @machine = StateMachine::Machine.new(@model, :public_state, :attribute => :state)
  573. @record = @model.new
  574. end
  575. def test_should_not_delegate_attribute_predicate_with_different_attribute
  576. assert_raise(ArgumentError) { @record.public_state? }
  577. end
  578. def teardown
  579. $stderr = @original_stderr
  580. super
  581. end
  582. end
  583. class MachineWithInitializedStateTest < BaseTestCase
  584. def setup
  585. @model = new_model
  586. @machine = StateMachine::Machine.new(@model, :initial => :parked)
  587. @machine.state :idling
  588. end
  589. def test_should_allow_nil_initial_state_when_static
  590. @machine.state nil
  591. record = @model.new(:state => nil)
  592. assert_nil record.state
  593. end
  594. def test_should_allow_nil_initial_state_when_dynamic
  595. @machine.state nil
  596. @machine.initial_state = lambda {:parked}
  597. record = @model.new(:state => nil)
  598. assert_nil record.state
  599. end
  600. def test_should_allow_different_initial_state_when_static
  601. record = @model.new(:state => 'idling')
  602. assert_equal 'idling', record.state
  603. end
  604. def test_should_allow_different_initial_state_when_dynamic
  605. @machine.initial_state = lambda {:parked}
  606. record = silence_warnings { @model.new(:state => 'idling') }
  607. assert_equal 'idling', record.state
  608. end
  609. def test_should_use_default_state_if_protected
  610. Mongoid.logger = nil
  611. @model.class_eval do
  612. attr_protected :state
  613. end
  614. record = @model.new(:state => 'idling')
  615. assert_equal 'parked', record.state
  616. end
  617. end
  618. class MachineMultipleTest < BaseTestCase
  619. def setup
  620. @model = new_model do
  621. field :status, :type => String
  622. end
  623. @state_machine = StateMachine::Machine.new(@model, :initial => :parked)
  624. @status_machine = StateMachine::Machine.new(@model, :status, :initial => :idling)
  625. end
  626. def test_should_should_initialize_each_state
  627. record = @model.new
  628. assert_equal 'parked', record.state
  629. assert_equal 'idling', record.status
  630. end
  631. end
  632. class MachineWithLoopbackTest < BaseTestCase
  633. def setup
  634. @model = new_model do
  635. field :updated_at, :type => Time
  636. before_update do |record|
  637. record.updated_at = Time.now
  638. end
  639. end
  640. @machine = StateMachine::Machine.new(@model, :initial => :parked)
  641. @machine.event :park
  642. @record = @model.create(:updated_at => Time.now - 1)
  643. @transition = StateMachine::Transition.new(@record, @machine, :park, :parked, :parked)
  644. @timestamp = @record.updated_at
  645. @transition.perform
  646. end
  647. def test_should_update_record
  648. assert_not_equal @timestamp, @record.updated_at
  649. end
  650. end
  651. class MachineWithDirtyAttributesTest < BaseTestCase
  652. def setup
  653. @model = new_model
  654. @machine = StateMachine::Machine.new(@model, :initial => :parked)
  655. @machine.event :ignite
  656. @machine.state :idling
  657. @record = @model.create
  658. @transition = StateMachine::Transition.new(@record, @machine, :ignite, :parked, :idling)
  659. @transition.perform(false)
  660. end
  661. def test_should_include_state_in_changed_attributes
  662. assert_equal %w(state), @record.changed
  663. end
  664. def test_should_track_attribute_change
  665. assert_equal %w(parked idling), @record.changes['state']
  666. end
  667. def test_should_not_reset_changes_on_multiple_transitions
  668. transition = StateMachine::Transition.new(@record, @machine, :ignite, :idling, :idling)
  669. transition.perform(false)
  670. assert_equal %w(parked idling), @record.changes['state']
  671. end
  672. def test_should_not_have_changes_when_loaded_from_database
  673. record = @model.find(@record.id)
  674. assert !record.changed?
  675. end
  676. end
  677. class MachineWithDirtyAttributesDuringLoopbackTest < BaseTestCase
  678. def setup
  679. @model = new_model
  680. @machine = StateMachine::Machine.new(@model, :initial => :parked)
  681. @machine.event :park
  682. @record = @model.create
  683. @transition = StateMachine::Transition.new(@record, @machine, :park, :parked, :parked)
  684. @transition.perform(false)
  685. end
  686. def test_should_not_include_state_in_changed_attributes
  687. assert_equal [], @record.changed
  688. end
  689. def test_should_not_track_attribute_changes
  690. assert_equal nil, @record.send(:attribute_change, 'state')
  691. end
  692. end
  693. class MachineWithDirtyAttributesAndCustomAttributeTest < BaseTestCase
  694. def setup
  695. @model = new_model do
  696. field :status, :type => String
  697. end
  698. @machine = StateMachine::Machine.new(@model, :status, :initial => :parked)
  699. @machine.event :ignite
  700. @machine.state :idling
  701. @record = @model.create
  702. @transition = StateMachine::Transition.new(@record, @machine, :ignite, :parked, :idling)
  703. @transition.perform(false)
  704. end
  705. def test_should_include_state_in_changed_attributes
  706. assert_equal %w(status), @record.changed
  707. end
  708. def test_should_track_attribute_change
  709. assert_equal %w(parked idling), @record.changes['status']
  710. end
  711. def test_should_not_reset_changes_on_multiple_transitions
  712. transition = StateMachine::Transition.new(@record, @machine, :ignite, :idling, :idling)
  713. transition.perform(false)
  714. assert_equal %w(parked idling), @record.changes['status']
  715. end
  716. end
  717. class MachineWithDirtyAttributeAndCustomAttributesDuringLoopbackTest < BaseTestCase
  718. def setup
  719. @model = new_model do
  720. field :status, :type => String
  721. end
  722. @machine = StateMachine::Machine.new(@model, :status, :initial => :parked)
  723. @machine.event :park
  724. @record = @model.create
  725. @transition = StateMachine::Transition.new(@record, @machine, :park, :parked, :parked)
  726. @transition.perform(false)
  727. end
  728. def test_should_include_state_in_changed_attributes
  729. assert_equal [], @record.changed
  730. end
  731. def test_should_track_attribute_changes
  732. assert_equal nil, @record.send(:attribute_change, 'status')
  733. end
  734. end
  735. class MachineWithDirtyAttributeAndStateEventsTest < BaseTestCase
  736. def setup
  737. @model = new_model
  738. @machine = StateMachine::Machine.new(@model, :initial => :parked)
  739. @machine.event :ignite
  740. @record = @model.create
  741. @record.state_event = 'ignite'
  742. end
  743. def test_should_not_include_state_in_changed_attributes
  744. assert_equal [], @record.changed
  745. end
  746. def test_should_not_track_attribute_change
  747. assert_equal nil, @record.send(:attribute_change, 'state')
  748. end
  749. end
  750. class MachineWithCallbacksTest < BaseTestCase
  751. def setup
  752. @model = new_model
  753. @machine = StateMachine::Machine.new(@model, :initial => :parked)
  754. @machine.other_states :idling
  755. @machine.event :ignite
  756. @record = @model.new(:state => 'parked')
  757. @transition = StateMachine::Transition.new(@record, @machine, :ignite, :parked, :idling)
  758. end
  759. def test_should_run_before_callbacks
  760. called = false
  761. @machine.before_transition {called = true}
  762. @transition.perform
  763. assert called
  764. end
  765. def test_should_pass_record_to_before_callbacks_with_one_argument
  766. record = nil
  767. @machine.before_transition {|arg| record = arg}
  768. @transition.perform
  769. assert_equal @record, record
  770. end
  771. def test_should_pass_record_and_transition_to_before_callbacks_with_multiple_arguments
  772. callback_args = nil
  773. @machine.before_transition {|*args| callback_args = args}
  774. @transition.perform
  775. assert_equal [@record, @transition], callback_args
  776. end
  777. def test_should_run_before_callbacks_outside_the_context_of_the_record
  778. context = nil
  779. @machine.before_transition {context = self}
  780. @transition.perform
  781. assert_equal self, context
  782. end
  783. def test_should_run_after_callbacks
  784. called = false
  785. @machine.after_transition {called = true}
  786. @transition.perform
  787. assert called
  788. end
  789. def test_should_pass_record_to_after_callbacks_with_one_argument
  790. record = nil
  791. @machine.after_transition {|arg| record = arg}
  792. @transition.perform
  793. assert_equal @record, record
  794. end
  795. def test_should_pass_record_and_transition_to_after_callbacks_with_multiple_arguments
  796. callback_args = nil
  797. @machine.after_transition {|*args| callback_args = args}
  798. @transition.perform
  799. assert_equal [@record, @transition], callback_args
  800. end
  801. def test_should_run_after_callbacks_outside_the_context_of_the_record
  802. context = nil
  803. @machine.after_transition {context = self}
  804. @transition.perform
  805. assert_equal self, context
  806. end
  807. def test_should_run_after_callbacks_if_model_callback_added_prior_to_state_machine_definition
  808. model = new_model do
  809. after_save { nil }
  810. end
  811. machine = StateMachine::Machine.new(model, :initial => :parked)
  812. machine.other_states :idling
  813. machine.event :ignite
  814. after_called = false
  815. machine.after_transition {after_called = true}
  816. record = model.new(:state => 'parked')
  817. transition = StateMachine::Transition.new(record, machine, :ignite, :parked, :idling)
  818. transition.perform
  819. assert_equal true, after_called
  820. end
  821. def test_should_run_around_callbacks
  822. before_called = false
  823. after_called = false
  824. ensure_called = 0
  825. @machine.around_transition do |block|
  826. before_called = true
  827. begin
  828. block.call
  829. ensure
  830. ensure_called += 1
  831. end
  832. after_called = true
  833. end
  834. @transition.perform
  835. assert before_called
  836. assert after_called
  837. assert_equal ensure_called, 1
  838. end
  839. def test_should_include_transition_states_in_known_states
  840. @machine.before_transition :to => :first_gear, :do => lambda {}
  841. assert_equal [:parked, :idling, :first_gear], @machine.states.map {|state| state.name}
  842. end
  843. def test_should_allow_symbolic_callbacks
  844. callback_args = nil
  845. klass = class << @record; self; end
  846. klass.send(:define_method, :after_ignite) do |*args|
  847. callback_args = args
  848. end
  849. @machine.before_transition(:after_ignite)
  850. @transition.perform
  851. assert_equal [@transition], callback_args
  852. end
  853. def test_should_allow_string_callbacks
  854. class << @record
  855. attr_reader :callback_result
  856. end
  857. @machine.before_transition('@callback_result = [1, 2, 3]')
  858. @transition.perform
  859. assert_equal [1, 2, 3], @record.callback_result
  860. end
  861. def test_should_run_in_expected_order
  862. expected = [
  863. :before_transition, :before_validation, :after_validation,
  864. :before_save, :before_create, :after_create, :after_save,
  865. :after_transition
  866. ]
  867. callbacks = []
  868. @model.before_validation { callbacks << :before_validation }
  869. @model.after_validation { callbacks << :after_validation }
  870. @model.before_save { callbacks << :before_save }
  871. @model.before_create { callbacks << :before_create }
  872. @model.after_create { callbacks << :after_create }
  873. @model.after_save { callbacks << :after_save }
  874. @machine.before_transition { callbacks << :before_transition }
  875. @machine.after_transition { callbacks << :after_transition }
  876. @transition.perform
  877. assert_equal expected, callbacks
  878. end
  879. end
  880. class MachineWithFailedBeforeCallbacksTest < BaseTestCase
  881. def setup
  882. @callbacks = []
  883. @model = new_model
  884. @machine = StateMachine::Machine.new(@model)
  885. @machine.state :parked, :idling
  886. @machine.event :ignite
  887. @machine.before_transition {@callbacks << :before_1; false}
  888. @machine.before_transition {@callbacks << :before_2}
  889. @machine.after_transition {@callbacks << :after}
  890. @machine.around_transition {|block| @callbacks << :around_before; block.call; @callbacks << :around_after}
  891. @record = @model.new(:state => 'parked')
  892. @transition = StateMachine::Transition.new(@record, @machine, :ignite, :parked, :idling)
  893. @result = @transition.perform
  894. end
  895. def test_should_not_be_successful
  896. assert !@result
  897. end
  898. def test_should_not_change_current_state
  899. assert_equal 'parked', @record.state
  900. end
  901. def test_should_not_run_action
  902. assert @record.new_record?
  903. end
  904. def test_should_not_run_further_callbacks
  905. assert_equal [:before_1], @callbacks
  906. end
  907. end
  908. class MachineNestedActionTest < BaseTestCase
  909. def setup
  910. @callbacks = []
  911. @model = new_model
  912. @machine = StateMachine::Machine.new(@model)
  913. @machine.event :ignite do
  914. transition :parked => :idling
  915. end
  916. @record = @model.new(:state => 'parked')
  917. end
  918. def test_should_allow_transition_prior_to_creation_if_skipping_action
  919. record = @record
  920. @model.before_create { record.ignite(false) }
  921. result = @record.save
  922. assert_equal true, result
  923. assert_equal "idling", @record.state
  924. @record.reload
  925. assert_equal "idling", @record.state
  926. end
  927. if Mongoid::VERSION !~ /^2\.1\./
  928. def test_should_allow_transition_after_creation
  929. record = @record
  930. @model.after_create { record.ignite }
  931. result = @record.save
  932. assert_equal true, result
  933. assert_equal "idling", @record.state
  934. @record.reload
  935. assert_equal "idling", @record.state
  936. end
  937. end
  938. end
  939. class MachineWithFailedActionTest < BaseTestCase
  940. def setup
  941. @model = new_model do
  942. validates_numericality_of :state
  943. end
  944. @machine = StateMachine::Machine.new(@model)
  945. @machine.state :parked, :idling
  946. @machine.event :ignite
  947. @callbacks = []
  948. @machine.before_transition {@callbacks << :before}
  949. @machine.after_transition {@callbacks << :after}
  950. @machine.after_failure {@callbacks << :after_failure}
  951. @machine.around_transition {|block| @callbacks << :around_before; block.call; @callbacks << :around_after}
  952. @record = @model.new(:state => 'parked')
  953. @transition = StateMachine::Transition.new(@record, @machine, :ignite, :parked, :idling)
  954. @result = @transition.perform
  955. end
  956. def test_should_not_be_successful
  957. assert !@result
  958. end
  959. def test_should_not_change_current_state
  960. assert_equal 'parked', @record.state
  961. end
  962. def test_should_not_save_record
  963. assert @record.new_record?
  964. end
  965. def test_should_run_before_callbacks_and_after_callbacks_with_failures
  966. assert_equal [:before, :around_before, :after_failure], @callbacks
  967. end
  968. end
  969. class MachineWithFailedAfterCallbacksTest < BaseTestCase
  970. def setup
  971. @callbacks = []
  972. @model = new_model
  973. @machine = StateMachine::Machine.new(@model)
  974. @machine.state :parked, :idling
  975. @machine.event :ignite
  976. @machine.after_transition {@callbacks << :after_1; false}
  977. @machine.after_transition {@callbacks << :after_2}
  978. @machine.around_transition {|block| @callbacks << :around_before; block.call; @callbacks << :around_after}
  979. @record = @model.new(:state => 'parked')
  980. @transition = StateMachine::Transition.new(@record, @machine, :ignite, :parked, :idling)
  981. @result = @transition.perform
  982. end
  983. def test_should_be_successful
  984. assert @result
  985. end
  986. def test_should_change_current_state
  987. assert_equal 'idling', @record.state
  988. end
  989. def test_should_save_record
  990. assert !@record.new_record?
  991. end
  992. def test_should_not_run_further_after_callbacks
  993. assert_equal [:around_before, :around_after, :after_1], @callbacks
  994. end
  995. end
  996. class MachineWithValidationsTest < BaseTestCase
  997. def setup
  998. @model = new_model
  999. @machine = StateMachine::Machine.new(@model)
  1000. @machine.state :parked
  1001. @record = @model.new
  1002. end
  1003. def test_should_invalidate_using_errors
  1004. I18n.backend = I18n::Backend::Simple.new if Object.const_defined?(:ActiveModel)
  1005. @record.state = 'parked'
  1006. @machine.invalidate(@record, :state, :invalid_transition, [[:event, 'park']])
  1007. assert_equal ['State cannot transition via "park"'], @record.errors.full_messages
  1008. end
  1009. def test_should_auto_prefix_custom_attributes_on_invalidation
  1010. @machine.invalidate(@record, :event, :invalid)
  1011. assert_equal ['State event is invalid'], @record.errors.full_messages
  1012. end
  1013. def test_should_clear_errors_on_reset
  1014. @record.state = 'parked'
  1015. @record.errors.add(:state, 'is invalid')
  1016. @machine.reset(@record)
  1017. assert_equal [], @record.errors.full_messages
  1018. end
  1019. def test_should_be_valid_if_state_is_known
  1020. @record.state = 'parked'
  1021. assert @record.valid?
  1022. end
  1023. def test_should_not_be_valid_if_state_is_unknown
  1024. @record.state = 'invalid'
  1025. assert !@record.valid?
  1026. assert_equal ['State is invalid'], @record.errors.full_messages
  1027. end
  1028. end
  1029. class MachineWithValidationsAndCustomAttributeTest < BaseTestCase
  1030. def setup
  1031. @model = new_model
  1032. @machine = StateMachine::Machine.new(@model, :status, :attribute => :state)
  1033. @machine.state :parked
  1034. @record = @model.new
  1035. end
  1036. def test_should_add_validation_errors_to_custom_attribute
  1037. @record.state = 'invalid'
  1038. assert !@record.valid?
  1039. assert_equal ['State is invalid'], @record.errors.full_messages
  1040. @record.state = 'parked'
  1041. assert @record.valid?
  1042. end
  1043. end
  1044. class MachineErrorsTest < BaseTestCase
  1045. def setup
  1046. @model = new_model
  1047. @machine = StateMachine::Machine.new(@model)
  1048. @record = @model.new
  1049. end
  1050. def test_should_be_able_to_describe_current_errors
  1051. @record.errors.add(:id, 'cannot be blank')
  1052. @record.errors.add(:state, 'is invalid')
  1053. assert_equal ['Id cannot be blank', 'State is invalid'], @machine.errors_for(@record).split(', ').sort
  1054. end
  1055. def test_should_describe_as_halted_with_no_errors
  1056. assert_equal 'Transition halted', @machine.errors_for(@record)
  1057. end
  1058. end
  1059. class MachineWithStateDrivenValidationsTest < BaseTestCase
  1060. def setup
  1061. @model = new_model do
  1062. attr_accessor :seatbealt
  1063. end
  1064. @machine = StateMachine::Machine.new(@model)
  1065. @machine.state :first_gear do
  1066. validates_presence_of :seatbelt, :key => :first_gear
  1067. end
  1068. @machine.state :second_gear do
  1069. validates_presence_of :seatbelt, :key => :second_gear
  1070. end
  1071. @machine.other_states :parked
  1072. end
  1073. def test_should_be_valid_if_validation_fails_outside_state_scope
  1074. record = @model.new(:state => 'parked', :seatbelt => nil)
  1075. assert record.valid?
  1076. end
  1077. def test_should_be_invalid_if_validation_fails_within_state_scope
  1078. record = @model.new(:state => 'first_gear', :seatbelt => nil)
  1079. assert !record.valid?
  1080. end
  1081. def test_should_be_valid_if_validation_succeeds_within_state_scope
  1082. record = @model.new(:state => 'second_gear', :seatbelt => true)
  1083. assert record.valid?
  1084. end
  1085. end
  1086. class MachineWithEventAttributesOnValidationTest < BaseTestCase
  1087. def setup
  1088. @model = new_model
  1089. @machine = StateMachine::Machine.new(@model)
  1090. @machine.event :ignite do
  1091. transition :parked => :idling
  1092. end
  1093. @record = @model.new
  1094. @record.state = 'parked'
  1095. @record.state_event = 'ignite'
  1096. end
  1097. def test_should_fail_if_event_is_invalid
  1098. @record.state_event = 'invalid'
  1099. assert !@record.valid?
  1100. assert_equal ['State event is invalid'], @record.errors.full_messages
  1101. end
  1102. def test_should_fail_if_event_has_no_transition
  1103. @record.state = 'idling'
  1104. assert !@record.valid?
  1105. assert_equal ['State event cannot transition when idling'], @record.errors.full_messages
  1106. end
  1107. def test_should_be_successful_if_event_has_transition
  1108. assert @record.valid?
  1109. end
  1110. def test_should_run_before_callbacks
  1111. ran_callback = false
  1112. @machine.before_transition { ran_callback = true }
  1113. @record.valid?
  1114. assert ran_callback
  1115. end
  1116. def test_should_run_around_callbacks_before_yield
  1117. ran_callback = false
  1118. @machine.around_transition {|block| ran_callback = true; block.call }
  1119. begin
  1120. @record.valid?
  1121. rescue ArgumentError
  1122. raise if StateMachine::Transition.pause_supported?
  1123. end
  1124. assert ran_callback
  1125. end
  1126. def test_should_persist_new_state
  1127. @record.valid?
  1128. assert_equal 'idling', @record.state
  1129. end
  1130. def test_should_not_run_after_callbacks
  1131. ran_callback = false
  1132. @machine.after_transition { ran_callback = true }
  1133. @record.valid?
  1134. assert !ran_callback
  1135. end
  1136. def test_should_not_run_after_callbacks_with_failures_disabled_if_validation_fails
  1137. @model.class_eval do
  1138. attr_accessor :seatbelt
  1139. validates_presence_of :seatbelt
  1140. end
  1141. ran_callback = false
  1142. @machine.after_transition { ran_callback = true }
  1143. @record.valid?
  1144. assert !ran_callback
  1145. end
  1146. def test_should_not_run_around_callbacks_after_yield
  1147. ran_callback = false
  1148. @machine.around_transition {|block| block.call; ran_callback = true }
  1149. begin
  1150. @record.valid?
  1151. rescue ArgumentError
  1152. raise if StateMachine::Transition.pause_supported?
  1153. end
  1154. assert !ran_callback
  1155. end
  1156. def test_should_not_run_around_callbacks_after_yield_with_failures_disabled_if_validation_fails
  1157. @model.class_eval do
  1158. attr_accessor :seatbelt
  1159. validates_presence_of :seatbelt
  1160. end
  1161. ran_callback = false
  1162. @machine.around_transition {|block| block.call; ran_callback = true }
  1163. @record.valid?
  1164. assert !ran_callback
  1165. end
  1166. def test_should_run_failure_callbacks_if_validation_fails
  1167. @model.class_eval do
  1168. attr_accessor :seatbelt
  1169. validates_presence_of :seatbelt
  1170. end
  1171. ran_callback = false
  1172. @machine.after_failure { ran_callback = true }
  1173. @record.valid?
  1174. assert ran_callback
  1175. end
  1176. end
  1177. class MachineWithEventAttributesOnSaveTest < BaseTestCase
  1178. def setup
  1179. @model = new_model
  1180. @machine = StateMachine::Machine.new(@model)
  1181. @machine.event :ignite do
  1182. transition :parked => :idling
  1183. end
  1184. @record = @model.new
  1185. @record.state = 'parked'
  1186. @record.state_event = 'ignite'
  1187. end
  1188. def test_should_fail_if_event_is_invalid
  1189. @record.state_event = 'invalid'
  1190. assert_equal false, @record.save
  1191. end
  1192. def test_should_fail_if_event_has_no_transition
  1193. @record.state = 'idling'
  1194. assert_equal false, @record.save
  1195. end
  1196. def test_should_be_successful_if_event_has_transition
  1197. assert_equal true, @record.save
  1198. end
  1199. def test_should_run_before_callbacks
  1200. ran_callback = false
  1201. @machine.before_transition { ran_callback = true }
  1202. @record.save
  1203. assert ran_callback
  1204. end
  1205. def test_should_run_before_callbacks_once
  1206. before_count = 0
  1207. @machine.before_transition { before_count += 1 }
  1208. @record.save
  1209. assert_equal 1, before_count
  1210. end
  1211. def test_should_run_around_callbacks_before_yield
  1212. ran_callback = false
  1213. @machine.around_transition {|block| ran_callback = true; block.call }
  1214. @record.save
  1215. assert ran_callback
  1216. end
  1217. def test_should_run_around_callbacks_before_yield_once
  1218. around_before_count = 0
  1219. @machine.around_transition {|block| around_before_count += 1; block.call }
  1220. @record.save
  1221. assert_equal 1, around_before_count
  1222. end
  1223. def test_should_persist_new_state
  1224. @record.save
  1225. assert_equal 'idling', @record.state
  1226. end
  1227. def test_should_run_after_callbacks
  1228. ran_callback = false
  1229. @machine.after_transition { ran_callback = true }
  1230. @record.save
  1231. assert ran_callback
  1232. end
  1233. def test_should_not_run_after_callbacks_with_failures_disabled_if_fails
  1234. @model.class_eval do
  1235. validates_numericality_of :state
  1236. end
  1237. ran_callback = false
  1238. @machine.after_transition { ran_callback = true }
  1239. begin; @record.save; rescue; end
  1240. assert !ran_callback
  1241. end
  1242. def test_should_run_failure_callbacks__if_fails
  1243. @model.class_eval do
  1244. validates_numericality_of :state
  1245. end
  1246. ran_callback = false
  1247. @machine.after_failure { ran_callback = true }
  1248. begin; @record.save; rescue; end
  1249. assert ran_callback
  1250. end
  1251. def test_should_not_run_around_callbacks_with_failures_disabled_if_fails
  1252. @model.class_eval do
  1253. validates_numericality_of :state
  1254. end
  1255. ran_callback = false
  1256. @machine.around_transition {|block| block.call; ran_callback = true }
  1257. begin; @record.save; rescue; end
  1258. assert !ran_callback
  1259. end
  1260. def test_should_run_around_callbacks_after_yield
  1261. ran_callback = false
  1262. @machine.around_transition {|block| block.call; ran_callback = true }
  1263. @record.save
  1264. assert ran_callback
  1265. end
  1266. def test_should_allow_additional_transitions_to_new_state_in_after_transitions
  1267. @machine.event :park do
  1268. transition :idling => :parked
  1269. end
  1270. @machine.after_transition(:on => :ignite) { @record.park }
  1271. @record.save
  1272. assert_equal 'parked', @record.state
  1273. @record.reload
  1274. assert_equal 'parked', @record.state
  1275. end
  1276. def test_should_allow_additional_transitions_to_previous_state_in_after_transitions
  1277. @machine.event :shift_up do
  1278. transition :idling => :first_gear
  1279. end
  1280. @machine.after_transition(:on => :ignite) { @record.shift_up }
  1281. @record.save
  1282. assert_equal 'first_gear', @record.state
  1283. @record.reload
  1284. assert_equal 'first_gear', @record.state
  1285. end
  1286. end
  1287. if Mongoid::VERSION >= '2.1.0'
  1288. class MachineWithEventAttributesOnAutosaveTest < BaseTestCase
  1289. def setup
  1290. @vehicle_model = new_model(:vehicle) do
  1291. belongs_to :owner, :class_name => 'MongoidTest::Owner'
  1292. end
  1293. MongoidTest.const_set('Vehicle', @vehicle_model)
  1294. @owner_model = new_model(:owner)
  1295. MongoidTest.const_set('Owner', @owner_model)
  1296. machine = StateMachine::Machine.new(@vehicle_model)
  1297. machine.event :ignite do
  1298. transition :parked => :idling
  1299. end
  1300. @owner = @owner_model.create
  1301. end
  1302. def test_should_persist_many_association
  1303. @owner_model.has_many :vehicles, :class_name => 'MongoidTest::Vehicle', :autosave => true
  1304. @vehicle = @vehicle_model.create(:state => 'parked', :owner_id => @owner.id)
  1305. @owner.vehicles[0].state_event = 'ignite'
  1306. @owner.save
  1307. @vehicle.reload
  1308. assert_equal 'idling', @vehicle.state
  1309. end
  1310. def test_should_persist_one_association
  1311. @owner_model.has_one :vehicle, :class_name => 'MongoidTest::Vehicle', :autosave => true
  1312. @vehicle = @vehicle_model.create(:state => 'parked', :owner_id => @owner.id)
  1313. @owner.vehicle.state_event = 'ignite'
  1314. @owner.save
  1315. @vehicle.reload
  1316. assert_equal 'idling', @vehicle.state
  1317. end
  1318. def teardown
  1319. MongoidTest.class_eval do
  1320. remove_const('Vehicle')
  1321. remove_const('Owner')
  1322. end
  1323. super
  1324. end
  1325. end
  1326. end
  1327. class MachineWithEventAttributesOnSaveBangTest < BaseTestCase
  1328. def setup
  1329. @model = new_model
  1330. @machine = StateMachine::Machine.new(@model)
  1331. @machine.event :ignite do
  1332. transition :parked => :idling
  1333. end
  1334. @record = @model.new
  1335. @record.state = 'parked'
  1336. @record.state_event = 'ignite'
  1337. end
  1338. def test_should_fail_if_event_is_invalid
  1339. @record.state_event = 'invalid'
  1340. assert_raise(Mongoid::Errors::Validations) { @record.save! }
  1341. end
  1342. def test_should_fail_if_event_has_no_transition
  1343. @record.state = 'idling'
  1344. assert_raise(Mongoid::Errors::Validations) { @record.save! }
  1345. end
  1346. def test_should_be_successful_if_event_has_transition
  1347. assert_equal true, @record.save!
  1348. end
  1349. def test_should_run_before_callbacks
  1350. ran_callback = false
  1351. @machine.before_transition { ran_callback = true }
  1352. @record.save!
  1353. assert ran_callback
  1354. end
  1355. def test_should_run_before_callbacks_once
  1356. before_count = 0
  1357. @machine.before_transition { before_count += 1 }
  1358. @record.save!
  1359. assert_equal 1, before_count
  1360. end
  1361. def test_should_run_around_callbacks_before_yield
  1362. ran_callback = false
  1363. @machine.around_transition {|block| ran_callback = true; block.call }
  1364. @record.save!
  1365. assert ran_callback
  1366. end
  1367. def test_should_run_around_callbacks_before_yield_once
  1368. around_before_count = 0
  1369. @machine.around_transition {|block| around_before_count += 1; block.call }
  1370. @record.save!
  1371. assert_equal 1, around_before_count
  1372. end

Large files files are truncated, but you can click here to view the full file