PageRenderTime 49ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 1ms

/test/unit/transition_collection_test.rb

http://github.com/pluginaweek/state_machine
Ruby | 2168 lines | 1698 code | 470 blank | 0 comment | 5 complexity | 3638f008300badb989470bf2bc75098c 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. class TransitionCollectionTest < Test::Unit::TestCase
  3. def test_should_raise_exception_if_invalid_option_specified
  4. exception = assert_raise(ArgumentError) {StateMachine::TransitionCollection.new([], :invalid => true)}
  5. assert_equal 'Invalid key(s): invalid', exception.message
  6. end
  7. def test_should_raise_exception_if_multiple_transitions_for_same_attribute_specified
  8. @klass = Class.new
  9. @machine = StateMachine::Machine.new(@klass, :initial => :parked)
  10. @machine.state :parked, :idling
  11. @machine.event :ignite
  12. @object = @klass.new
  13. exception = assert_raise(ArgumentError) do
  14. StateMachine::TransitionCollection.new([
  15. StateMachine::Transition.new(@object, @machine, :ignite, :parked, :idling),
  16. StateMachine::Transition.new(@object, @machine, :ignite, :parked, :idling)
  17. ])
  18. end
  19. assert_equal 'Cannot perform multiple transitions in parallel for the same state machine attribute', exception.message
  20. end
  21. end
  22. class TransitionCollectionByDefaultTest < Test::Unit::TestCase
  23. def setup
  24. @transitions = StateMachine::TransitionCollection.new
  25. end
  26. def test_should_not_skip_actions
  27. assert !@transitions.skip_actions
  28. end
  29. def test_should_not_skip_after
  30. assert !@transitions.skip_after
  31. end
  32. def test_should_use_transaction
  33. assert @transitions.use_transaction
  34. end
  35. def test_should_be_empty
  36. assert @transitions.empty?
  37. end
  38. end
  39. class TransitionCollectionEmptyWithoutBlockTest < Test::Unit::TestCase
  40. def setup
  41. @transitions = StateMachine::TransitionCollection.new
  42. @result = @transitions.perform
  43. end
  44. def test_should_succeed
  45. assert_equal true, @result
  46. end
  47. end
  48. class TransitionCollectionEmptyWithBlockTest < Test::Unit::TestCase
  49. def setup
  50. @transitions = StateMachine::TransitionCollection.new
  51. end
  52. def test_should_raise_exception_if_perform_raises_exception
  53. assert_raise(ArgumentError) { @transitions.perform { raise ArgumentError } }
  54. end
  55. def test_should_use_block_result_if_non_boolean
  56. assert_equal 1, @transitions.perform { 1 }
  57. end
  58. def test_should_use_block_result_if_false
  59. assert_equal false, @transitions.perform { false }
  60. end
  61. def test_should_use_block_reslut_if_nil
  62. assert_equal nil, @transitions.perform { nil }
  63. end
  64. end
  65. class TransitionCollectionInvalidTest < Test::Unit::TestCase
  66. def setup
  67. @transitions = StateMachine::TransitionCollection.new([false])
  68. end
  69. def test_should_be_empty
  70. assert @transitions.empty?
  71. end
  72. def test_should_not_succeed
  73. assert_equal false, @transitions.perform
  74. end
  75. def test_should_not_run_perform_block
  76. ran_block = false
  77. @transitions.perform { ran_block = true }
  78. assert !ran_block
  79. end
  80. end
  81. class TransitionCollectionPartialInvalidTest < Test::Unit::TestCase
  82. def setup
  83. @klass = Class.new do
  84. attr_accessor :ran_transaction
  85. end
  86. @callbacks = []
  87. @machine = StateMachine::Machine.new(@klass, :initial => :parked)
  88. @machine.state :idling
  89. @machine.event :ignite
  90. @machine.before_transition {@callbacks << :before}
  91. @machine.after_transition {@callbacks << :after}
  92. @machine.around_transition {|block| @callbacks << :around_before; block.call; @callbacks << :around_after}
  93. class << @machine
  94. def within_transaction(object)
  95. object.ran_transaction = true
  96. end
  97. end
  98. @object = @klass.new
  99. @transitions = StateMachine::TransitionCollection.new([
  100. StateMachine::Transition.new(@object, @machine, :ignite, :parked, :idling),
  101. false
  102. ])
  103. end
  104. def test_should_not_store_invalid_values
  105. assert_equal 1, @transitions.length
  106. end
  107. def test_should_not_succeed
  108. assert_equal false, @transitions.perform
  109. end
  110. def test_should_not_start_transaction
  111. assert !@object.ran_transaction
  112. end
  113. def test_should_not_run_perform_block
  114. ran_block = false
  115. @transitions.perform { ran_block = true }
  116. assert !ran_block
  117. end
  118. def test_should_not_run_before_callbacks
  119. assert !@callbacks.include?(:before)
  120. end
  121. def test_should_not_persist_states
  122. assert_equal 'parked', @object.state
  123. end
  124. def test_should_not_run_after_callbacks
  125. assert !@callbacks.include?(:after)
  126. end
  127. def test_should_not_run_around_callbacks_before_yield
  128. assert !@callbacks.include?(:around_before)
  129. end
  130. def test_should_not_run_around_callbacks_after_yield
  131. assert !@callbacks.include?(:around_after)
  132. end
  133. end
  134. class TransitionCollectionValidTest < Test::Unit::TestCase
  135. def setup
  136. @klass = Class.new do
  137. attr_reader :persisted
  138. def initialize
  139. @persisted = nil
  140. super
  141. @persisted = []
  142. end
  143. def state=(value)
  144. @persisted << 'state' if @persisted
  145. @state = value
  146. end
  147. def status=(value)
  148. @persisted << 'status' if @persisted
  149. @status = value
  150. end
  151. end
  152. @state = StateMachine::Machine.new(@klass, :initial => :parked)
  153. @state.state :idling
  154. @state.event :ignite
  155. @status = StateMachine::Machine.new(@klass, :status, :initial => :first_gear)
  156. @status.state :second_gear
  157. @status.event :shift_up
  158. @object = @klass.new
  159. @result = StateMachine::TransitionCollection.new([
  160. @state_transition = StateMachine::Transition.new(@object, @state, :ignite, :parked, :idling),
  161. @status_transition = StateMachine::Transition.new(@object, @status, :shift_up, :first_gear, :second_gear)
  162. ]).perform
  163. end
  164. def test_should_succeed
  165. assert_equal true, @result
  166. end
  167. def test_should_persist_each_state
  168. assert_equal 'idling', @object.state
  169. assert_equal 'second_gear', @object.status
  170. end
  171. def test_should_persist_in_order
  172. assert_equal ['state', 'status'], @object.persisted
  173. end
  174. def test_should_store_results_in_transitions
  175. assert_nil @state_transition.result
  176. assert_nil @status_transition.result
  177. end
  178. end
  179. class TransitionCollectionWithoutTransactionsTest < Test::Unit::TestCase
  180. def setup
  181. @klass = Class.new do
  182. attr_accessor :ran_transaction
  183. end
  184. @machine = StateMachine::Machine.new(@klass, :initial => :parked)
  185. @machine.state :idling
  186. @machine.event :ignite
  187. class << @machine
  188. def within_transaction(object)
  189. object.ran_transaction = true
  190. end
  191. end
  192. @object = @klass.new
  193. @transitions = StateMachine::TransitionCollection.new([
  194. StateMachine::Transition.new(@object, @machine, :ignite, :parked, :idling)
  195. ], :transaction => false)
  196. @transitions.perform
  197. end
  198. def test_should_not_run_within_transaction
  199. assert !@object.ran_transaction
  200. end
  201. end
  202. class TransitionCollectionWithTransactionsTest < Test::Unit::TestCase
  203. def setup
  204. @klass = Class.new do
  205. attr_accessor :running_transaction, :cancelled_transaction
  206. end
  207. @machine = StateMachine::Machine.new(@klass, :initial => :parked)
  208. @machine.state :idling
  209. @machine.event :ignite
  210. class << @machine
  211. def within_transaction(object)
  212. object.running_transaction = true
  213. object.cancelled_transaction = yield == false
  214. object.running_transaction = false
  215. end
  216. end
  217. @object = @klass.new
  218. @transitions = StateMachine::TransitionCollection.new([
  219. StateMachine::Transition.new(@object, @machine, :ignite, :parked, :idling)
  220. ], :transaction => true)
  221. end
  222. def test_should_run_before_callbacks_within_transaction
  223. @machine.before_transition {|object| @in_transaction = object.running_transaction}
  224. @transitions.perform
  225. assert @in_transaction
  226. end
  227. def test_should_run_action_within_transaction
  228. @transitions.perform { @in_transaction = @object.running_transaction }
  229. assert @in_transaction
  230. end
  231. def test_should_run_after_callbacks_within_transaction
  232. @machine.after_transition {|object| @in_transaction = object.running_transaction}
  233. @transitions.perform
  234. assert @in_transaction
  235. end
  236. def test_should_cancel_the_transaction_on_before_halt
  237. @machine.before_transition {throw :halt}
  238. @transitions.perform
  239. assert @object.cancelled_transaction
  240. end
  241. def test_should_cancel_the_transaction_on_action_failure
  242. @transitions.perform { false }
  243. assert @object.cancelled_transaction
  244. end
  245. def test_should_not_cancel_the_transaction_on_after_halt
  246. @machine.after_transition {throw :halt}
  247. @transitions.perform
  248. assert !@object.cancelled_transaction
  249. end
  250. end
  251. class TransitionCollectionWithEmptyActionsTest < Test::Unit::TestCase
  252. def setup
  253. @klass = Class.new
  254. @state = StateMachine::Machine.new(@klass, :initial => :parked)
  255. @state.state :idling
  256. @state.event :ignite
  257. @status = StateMachine::Machine.new(@klass, :status, :initial => :first_gear)
  258. @status.state :second_gear
  259. @status.event :shift_up
  260. @object = @klass.new
  261. @transitions = StateMachine::TransitionCollection.new([
  262. @state_transition = StateMachine::Transition.new(@object, @state, :ignite, :parked, :idling),
  263. @status_transition = StateMachine::Transition.new(@object, @status, :shift_up, :first_gear, :second_gear)
  264. ])
  265. @object.state = 'idling'
  266. @object.status = 'second_gear'
  267. @result = @transitions.perform
  268. end
  269. def test_should_succeed
  270. assert_equal true, @result
  271. end
  272. def test_should_persist_states
  273. assert_equal 'idling', @object.state
  274. assert_equal 'second_gear', @object.status
  275. end
  276. def test_should_store_results_in_transitions
  277. assert_nil @state_transition.result
  278. assert_nil @status_transition.result
  279. end
  280. end
  281. class TransitionCollectionWithSkippedActionsTest < Test::Unit::TestCase
  282. def setup
  283. @klass = Class.new do
  284. attr_reader :actions
  285. def save_state
  286. (@actions ||= []) << :save_state
  287. :save_state
  288. end
  289. def save_status
  290. (@actions ||= []) << :save_status
  291. :save_status
  292. end
  293. end
  294. @callbacks = []
  295. @state = StateMachine::Machine.new(@klass, :initial => :parked, :action => :save_state)
  296. @state.state :idling
  297. @state.event :ignite
  298. @state.before_transition {@callbacks << :state_before}
  299. @state.after_transition {@callbacks << :state_after}
  300. @state.around_transition {|block| @callbacks << :state_around_before; block.call; @callbacks << :state_around_after}
  301. @status = StateMachine::Machine.new(@klass, :status, :initial => :first_gear, :action => :save_status)
  302. @status.state :second_gear
  303. @status.event :shift_up
  304. @status.before_transition {@callbacks << :status_before}
  305. @status.after_transition {@callbacks << :status_after}
  306. @status.around_transition {|block| @callbacks << :status_around_before; block.call; @callbacks << :status_around_after}
  307. @object = @klass.new
  308. @transitions = StateMachine::TransitionCollection.new([
  309. @state_transition = StateMachine::Transition.new(@object, @state, :ignite, :parked, :idling),
  310. @status_transition = StateMachine::Transition.new(@object, @status, :shift_up, :first_gear, :second_gear)
  311. ], :actions => false)
  312. @result = @transitions.perform
  313. end
  314. def test_should_skip_actions
  315. assert_equal true, @transitions.skip_actions
  316. end
  317. def test_should_succeed
  318. assert_equal true, @result
  319. end
  320. def test_should_persist_states
  321. assert_equal 'idling', @object.state
  322. assert_equal 'second_gear', @object.status
  323. end
  324. def test_should_not_run_actions
  325. assert_nil @object.actions
  326. end
  327. def test_should_store_results_in_transitions
  328. assert_nil @state_transition.result
  329. assert_nil @status_transition.result
  330. end
  331. def test_should_run_all_callbacks
  332. assert_equal [:state_before, :state_around_before, :status_before, :status_around_before, :status_around_after, :status_after, :state_around_after, :state_after], @callbacks
  333. end
  334. end
  335. class TransitionCollectionWithSkippedActionsAndBlockTest < Test::Unit::TestCase
  336. def setup
  337. @klass = Class.new
  338. @machine = StateMachine::Machine.new(@klass, :initial => :parked, :action => :save_state)
  339. @machine.state :idling
  340. @machine.event :ignite
  341. @object = @klass.new
  342. @transitions = StateMachine::TransitionCollection.new([
  343. @state_transition = StateMachine::Transition.new(@object, @machine, :ignite, :parked, :idling)
  344. ], :actions => false)
  345. @result = @transitions.perform { @ran_block = true; 1 }
  346. end
  347. def test_should_succeed
  348. assert_equal 1, @result
  349. end
  350. def test_should_persist_states
  351. assert_equal 'idling', @object.state
  352. end
  353. def test_should_run_block
  354. assert @ran_block
  355. end
  356. def test_should_store_results_in_transitions
  357. assert_equal 1, @state_transition.result
  358. end
  359. end
  360. class TransitionCollectionWithDuplicateActionsTest < Test::Unit::TestCase
  361. def setup
  362. @klass = Class.new do
  363. attr_reader :actions
  364. def save
  365. (@actions ||= []) << :save
  366. :save
  367. end
  368. end
  369. @state = StateMachine::Machine.new(@klass, :initial => :parked, :action => :save)
  370. @state.state :idling
  371. @state.event :ignite
  372. @status = StateMachine::Machine.new(@klass, :status, :initial => :first_gear, :action => :save)
  373. @status.state :second_gear
  374. @status.event :shift_up
  375. @object = @klass.new
  376. @transitions = StateMachine::TransitionCollection.new([
  377. @state_transition = StateMachine::Transition.new(@object, @state, :ignite, :parked, :idling),
  378. @status_transition = StateMachine::Transition.new(@object, @status, :shift_up, :first_gear, :second_gear)
  379. ])
  380. @result = @transitions.perform
  381. end
  382. def test_should_succeed
  383. assert_equal :save, @result
  384. end
  385. def test_should_persist_states
  386. assert_equal 'idling', @object.state
  387. assert_equal 'second_gear', @object.status
  388. end
  389. def test_should_run_action_once
  390. assert_equal [:save], @object.actions
  391. end
  392. def test_should_store_results_in_transitions
  393. assert_equal :save, @state_transition.result
  394. assert_equal :save, @status_transition.result
  395. end
  396. end
  397. class TransitionCollectionWithDifferentActionsTest < Test::Unit::TestCase
  398. def setup
  399. @klass = Class.new do
  400. attr_reader :actions
  401. def save_state
  402. (@actions ||= []) << :save_state
  403. :save_state
  404. end
  405. def save_status
  406. (@actions ||= []) << :save_status
  407. :save_status
  408. end
  409. end
  410. @state = StateMachine::Machine.new(@klass, :initial => :parked, :action => :save_state)
  411. @state.state :idling
  412. @state.event :ignite
  413. @status = StateMachine::Machine.new(@klass, :status, :initial => :first_gear, :action => :save_status)
  414. @status.state :second_gear
  415. @status.event :shift_up
  416. @object = @klass.new
  417. @transitions = StateMachine::TransitionCollection.new([
  418. @state_transition = StateMachine::Transition.new(@object, @state, :ignite, :parked, :idling),
  419. @status_transition = StateMachine::Transition.new(@object, @status, :shift_up, :first_gear, :second_gear)
  420. ])
  421. end
  422. def test_should_succeed
  423. assert_equal true, @transitions.perform
  424. end
  425. def test_should_persist_states
  426. @transitions.perform
  427. assert_equal 'idling', @object.state
  428. assert_equal 'second_gear', @object.status
  429. end
  430. def test_should_run_actions_in_order
  431. @transitions.perform
  432. assert_equal [:save_state, :save_status], @object.actions
  433. end
  434. def test_should_store_results_in_transitions
  435. @transitions.perform
  436. assert_equal :save_state, @state_transition.result
  437. assert_equal :save_status, @status_transition.result
  438. end
  439. def test_should_not_halt_if_action_fails_for_first_transition
  440. @klass.class_eval do
  441. remove_method :save_state
  442. def save_state
  443. (@actions ||= []) << :save_state
  444. false
  445. end
  446. end
  447. assert_equal false, @transitions.perform
  448. assert_equal [:save_state, :save_status], @object.actions
  449. end
  450. def test_should_halt_if_action_fails_for_second_transition
  451. @klass.class_eval do
  452. remove_method :save_status
  453. def save_status
  454. (@actions ||= []) << :save_status
  455. false
  456. end
  457. end
  458. assert_equal false, @transitions.perform
  459. assert_equal [:save_state, :save_status], @object.actions
  460. end
  461. def test_should_rollback_if_action_errors_for_first_transition
  462. @klass.class_eval do
  463. remove_method :save_state
  464. def save_state
  465. raise ArgumentError
  466. end
  467. end
  468. begin; @transitions.perform; rescue; end
  469. assert_equal 'parked', @object.state
  470. assert_equal 'first_gear', @object.status
  471. end
  472. def test_should_rollback_if_action_errors_for_second_transition
  473. @klass.class_eval do
  474. remove_method :save_status
  475. def save_status
  476. raise ArgumentError
  477. end
  478. end
  479. begin; @transitions.perform; rescue; end
  480. assert_equal 'parked', @object.state
  481. assert_equal 'first_gear', @object.status
  482. end
  483. def test_should_not_run_after_callbacks_if_action_fails_for_first_transition
  484. @klass.class_eval do
  485. remove_method :save_state
  486. def save_state
  487. false
  488. end
  489. end
  490. @callbacks = []
  491. @state.after_transition { @callbacks << :state_after }
  492. @state.around_transition {|block| block.call; @callbacks << :state_around }
  493. @status.after_transition { @callbacks << :status_after }
  494. @status.around_transition {|block| block.call; @callbacks << :status_around }
  495. @transitions.perform
  496. assert_equal [], @callbacks
  497. end
  498. def test_should_not_run_after_callbacks_if_action_fails_for_second_transition
  499. @klass.class_eval do
  500. remove_method :save_status
  501. def save_status
  502. false
  503. end
  504. end
  505. @callbacks = []
  506. @state.after_transition { @callbacks << :state_after }
  507. @state.around_transition {|block| block.call; @callbacks << :state_around }
  508. @status.after_transition { @callbacks << :status_after }
  509. @status.around_transition {|block| block.call; @callbacks << :status_around }
  510. @transitions.perform
  511. assert_equal [], @callbacks
  512. end
  513. def test_should_run_after_failure_callbacks_if_action_fails_for_first_transition
  514. @klass.class_eval do
  515. remove_method :save_state
  516. def save_state
  517. false
  518. end
  519. end
  520. @callbacks = []
  521. @state.after_failure { @callbacks << :state_after }
  522. @status.after_failure { @callbacks << :status_after }
  523. @transitions.perform
  524. assert_equal [:status_after, :state_after], @callbacks
  525. end
  526. def test_should_run_after_failure_callbacks_if_action_fails_for_second_transition
  527. @klass.class_eval do
  528. remove_method :save_status
  529. def save_status
  530. false
  531. end
  532. end
  533. @callbacks = []
  534. @state.after_failure { @callbacks << :state_after }
  535. @status.after_failure { @callbacks << :status_after }
  536. @transitions.perform
  537. assert_equal [:status_after, :state_after], @callbacks
  538. end
  539. end
  540. class TransitionCollectionWithMixedActionsTest < Test::Unit::TestCase
  541. def setup
  542. @klass = Class.new do
  543. def save
  544. true
  545. end
  546. end
  547. @state = StateMachine::Machine.new(@klass, :initial => :parked, :action => :save)
  548. @state.state :idling
  549. @state.event :ignite
  550. @status = StateMachine::Machine.new(@klass, :status, :initial => :first_gear)
  551. @status.state :second_gear
  552. @status.event :shift_up
  553. @object = @klass.new
  554. @transitions = StateMachine::TransitionCollection.new([
  555. @state_transition = StateMachine::Transition.new(@object, @state, :ignite, :parked, :idling),
  556. @status_transition = StateMachine::Transition.new(@object, @status, :shift_up, :first_gear, :second_gear)
  557. ])
  558. @result = @transitions.perform
  559. end
  560. def test_should_succeed
  561. assert_equal true, @result
  562. end
  563. def test_should_persist_states
  564. assert_equal 'idling', @object.state
  565. assert_equal 'second_gear', @object.status
  566. end
  567. def test_should_store_results_in_transitions
  568. assert_equal true, @state_transition.result
  569. assert_nil @status_transition.result
  570. end
  571. end
  572. class TransitionCollectionWithBlockTest < Test::Unit::TestCase
  573. def setup
  574. @klass = Class.new do
  575. attr_reader :actions
  576. def save
  577. (@actions ||= []) << :save
  578. end
  579. end
  580. @state = StateMachine::Machine.new(@klass, :state, :initial => :parked, :action => :save)
  581. @state.state :idling
  582. @state.event :ignite
  583. @status = StateMachine::Machine.new(@klass, :status, :initial => :first_gear, :action => :save)
  584. @status.state :second_gear
  585. @status.event :shift_up
  586. @object = @klass.new
  587. @transitions = StateMachine::TransitionCollection.new([
  588. @state_transition = StateMachine::Transition.new(@object, @state, :ignite, :parked, :idling),
  589. @status_transition = StateMachine::Transition.new(@object, @status, :shift_up, :first_gear, :second_gear)
  590. ])
  591. @result = @transitions.perform { 1 }
  592. end
  593. def test_should_succeed
  594. assert_equal 1, @result
  595. end
  596. def test_should_persist_states
  597. assert_equal 'idling', @object.state
  598. assert_equal 'second_gear', @object.status
  599. end
  600. def test_should_not_run_machine_actions
  601. assert_nil @object.actions
  602. end
  603. def test_should_use_result_as_transition_result
  604. assert_equal 1, @state_transition.result
  605. assert_equal 1, @status_transition.result
  606. end
  607. end
  608. class TransitionCollectionWithActionFailedTest < Test::Unit::TestCase
  609. def setup
  610. @klass = Class.new do
  611. def save
  612. false
  613. end
  614. end
  615. @before_count = 0
  616. @around_before_count = 0
  617. @after_count = 0
  618. @around_after_count = 0
  619. @failure_count = 0
  620. @machine = StateMachine::Machine.new(@klass, :initial => :parked, :action => :save)
  621. @machine.state :idling
  622. @machine.event :ignite
  623. @machine.before_transition {@before_count += 1}
  624. @machine.after_transition {@after_count += 1}
  625. @machine.around_transition {|block| @around_before_count += 1; block.call; @around_after_count += 1}
  626. @machine.after_failure {@failure_count += 1}
  627. @object = @klass.new
  628. @transitions = StateMachine::TransitionCollection.new([
  629. StateMachine::Transition.new(@object, @machine, :ignite, :parked, :idling)
  630. ])
  631. @result = @transitions.perform
  632. end
  633. def test_should_not_succeed
  634. assert_equal false, @result
  635. end
  636. def test_should_not_persist_state
  637. assert_equal 'parked', @object.state
  638. end
  639. def test_should_run_before_callbacks
  640. assert_equal 1, @before_count
  641. end
  642. def test_should_run_around_callbacks_before_yield
  643. assert_equal 1, @around_before_count
  644. end
  645. def test_should_not_run_after_callbacks
  646. assert_equal 0, @after_count
  647. end
  648. def test_should_not_run_around_callbacks
  649. assert_equal 0, @around_after_count
  650. end
  651. def test_should_run_failure_callbacks
  652. assert_equal 1, @failure_count
  653. end
  654. end
  655. class TransitionCollectionWithActionErrorTest < Test::Unit::TestCase
  656. def setup
  657. @klass = Class.new do
  658. def save
  659. raise ArgumentError
  660. end
  661. end
  662. @before_count = 0
  663. @around_before_count = 0
  664. @after_count = 0
  665. @around_after_count = 0
  666. @failure_count = 0
  667. @machine = StateMachine::Machine.new(@klass, :initial => :parked, :action => :save)
  668. @machine.state :idling
  669. @machine.event :ignite
  670. @machine.before_transition {@before_count += 1}
  671. @machine.after_transition {@after_count += 1}
  672. @machine.around_transition {|block| @around_before_count += 1; block.call; @around_after_count += 1}
  673. @machine.after_failure {@failure_count += 1}
  674. @object = @klass.new
  675. @transitions = StateMachine::TransitionCollection.new([
  676. StateMachine::Transition.new(@object, @machine, :ignite, :parked, :idling)
  677. ])
  678. @raised = true
  679. begin
  680. @transitions.perform
  681. @raised = false
  682. rescue ArgumentError
  683. end
  684. end
  685. def test_should_not_catch_exception
  686. assert @raised
  687. end
  688. def test_should_not_persist_state
  689. assert_equal 'parked', @object.state
  690. end
  691. def test_should_run_before_callbacks
  692. assert_equal 1, @before_count
  693. end
  694. def test_should_run_around_callbacks_before_yield
  695. assert_equal 1, @around_before_count
  696. end
  697. def test_should_not_run_after_callbacks
  698. assert_equal 0, @after_count
  699. end
  700. def test_should_not_run_around_callbacks_after_yield
  701. assert_equal 0, @around_after_count
  702. end
  703. def test_should_not_run_failure_callbacks
  704. assert_equal 0, @failure_count
  705. end
  706. end
  707. class TransitionCollectionWithCallbacksTest < Test::Unit::TestCase
  708. def setup
  709. @klass = Class.new do
  710. attr_reader :saved
  711. def save
  712. @saved = true
  713. end
  714. end
  715. @before_callbacks = []
  716. @after_callbacks = []
  717. @state = StateMachine::Machine.new(@klass, :initial => :parked, :action => :save)
  718. @state.state :idling
  719. @state.event :ignite
  720. @state.before_transition {@before_callbacks << :state_before}
  721. @state.after_transition {@after_callbacks << :state_after}
  722. @state.around_transition {|block| @before_callbacks << :state_around; block.call; @after_callbacks << :state_around}
  723. @status = StateMachine::Machine.new(@klass, :status, :initial => :first_gear, :action => :save)
  724. @status.state :second_gear
  725. @status.event :shift_up
  726. @status.before_transition {@before_callbacks << :status_before}
  727. @status.after_transition {@after_callbacks << :status_after}
  728. @status.around_transition {|block| @before_callbacks << :status_around; block.call; @after_callbacks << :status_around}
  729. @object = @klass.new
  730. @transitions = StateMachine::TransitionCollection.new([
  731. StateMachine::Transition.new(@object, @state, :ignite, :parked, :idling),
  732. StateMachine::Transition.new(@object, @status, :shift_up, :first_gear, :second_gear)
  733. ])
  734. end
  735. def test_should_run_before_callbacks_in_order
  736. @transitions.perform
  737. assert_equal [:state_before, :state_around, :status_before, :status_around], @before_callbacks
  738. end
  739. def test_should_halt_if_before_callback_halted_for_first_transition
  740. @state.before_transition {throw :halt}
  741. assert_equal false, @transitions.perform
  742. assert_equal [:state_before, :state_around], @before_callbacks
  743. end
  744. def test_should_halt_if_before_callback_halted_for_second_transition
  745. @status.before_transition {throw :halt}
  746. assert_equal false, @transitions.perform
  747. assert_equal [:state_before, :state_around, :status_before, :status_around], @before_callbacks
  748. end
  749. def test_should_halt_if_around_callback_halted_before_yield_for_first_transition
  750. @state.around_transition {throw :halt}
  751. assert_equal false, @transitions.perform
  752. assert_equal [:state_before, :state_around], @before_callbacks
  753. end
  754. def test_should_halt_if_around_callback_halted_before_yield_for_second_transition
  755. @status.around_transition {throw :halt}
  756. assert_equal false, @transitions.perform
  757. assert_equal [:state_before, :state_around, :status_before, :status_around], @before_callbacks
  758. end
  759. def test_should_run_after_callbacks_in_reverse_order
  760. @transitions.perform
  761. assert_equal [:status_around, :status_after, :state_around, :state_after], @after_callbacks
  762. end
  763. def test_should_not_halt_if_after_callback_halted_for_first_transition
  764. @state.after_transition {throw :halt}
  765. assert_equal true, @transitions.perform
  766. assert_equal [:status_around, :status_after, :state_around, :state_after], @after_callbacks
  767. end
  768. def test_should_not_halt_if_around_callback_halted_for_second_transition
  769. @status.around_transition {|block| block.call; throw :halt}
  770. assert_equal true, @transitions.perform
  771. assert_equal [:state_around, :state_after], @after_callbacks
  772. end
  773. def test_should_run_before_callbacks_before_persisting_the_state
  774. @state.before_transition {|object| @before_state = object.state}
  775. @state.around_transition {|object, transition, block| @around_state = object.state; block.call}
  776. @transitions.perform
  777. assert_equal 'parked', @before_state
  778. assert_equal 'parked', @around_state
  779. end
  780. def test_should_persist_state_before_running_action
  781. @klass.class_eval do
  782. attr_reader :saved_on_persist
  783. def state=(value)
  784. @state = value
  785. @saved_on_persist = saved
  786. end
  787. end
  788. @transitions.perform
  789. assert !@object.saved_on_persist
  790. end
  791. def test_should_persist_state_before_running_action_block
  792. @klass.class_eval do
  793. attr_writer :saved
  794. attr_reader :saved_on_persist
  795. def state=(value)
  796. @state = value
  797. @saved_on_persist = saved
  798. end
  799. end
  800. @transitions.perform { @object.saved = true }
  801. assert !@object.saved_on_persist
  802. end
  803. def test_should_run_after_callbacks_after_running_the_action
  804. @state.after_transition {|object| @after_saved = object.saved}
  805. @state.around_transition {|object, transition, block| block.call; @around_saved = object.saved}
  806. @transitions.perform
  807. assert @after_saved
  808. assert @around_saved
  809. end
  810. end
  811. class TransitionCollectionWithBeforeCallbackHaltTest < Test::Unit::TestCase
  812. def setup
  813. @klass = Class.new do
  814. attr_reader :saved
  815. def save
  816. @saved = true
  817. end
  818. end
  819. @before_count = 0
  820. @after_count = 0
  821. @machine = StateMachine::Machine.new(@klass, :initial => :parked, :action => :save)
  822. @machine.state :idling
  823. @machine.event :ignite
  824. @machine.before_transition {@before_count += 1; throw :halt}
  825. @machine.before_transition {@before_count += 1}
  826. @machine.after_transition {@after_count += 1}
  827. @machine.around_transition {|block| @before_count += 1; block.call; @after_count += 1}
  828. @object = @klass.new
  829. @transitions = StateMachine::TransitionCollection.new([
  830. StateMachine::Transition.new(@object, @machine, :ignite, :parked, :idling)
  831. ])
  832. @result = @transitions.perform
  833. end
  834. def test_should_not_succeed
  835. assert_equal false, @result
  836. end
  837. def test_should_not_persist_state
  838. assert_equal 'parked', @object.state
  839. end
  840. def test_should_not_run_action
  841. assert !@object.saved
  842. end
  843. def test_should_not_run_further_before_callbacks
  844. assert_equal 1, @before_count
  845. end
  846. def test_should_not_run_after_callbacks
  847. assert_equal 0, @after_count
  848. end
  849. end
  850. class TransitionCollectionWithAfterCallbackHaltTest < Test::Unit::TestCase
  851. def setup
  852. @klass = Class.new do
  853. attr_reader :saved
  854. def save
  855. @saved = true
  856. end
  857. end
  858. @before_count = 0
  859. @after_count = 0
  860. @machine = StateMachine::Machine.new(@klass, :initial => :parked, :action => :save)
  861. @machine.state :idling
  862. @machine.event :ignite
  863. @machine.before_transition {@before_count += 1}
  864. @machine.after_transition {@after_count += 1; throw :halt}
  865. @machine.after_transition {@after_count += 1}
  866. @machine.around_transition {|block| @before_count += 1; block.call; @after_count += 1}
  867. @object = @klass.new
  868. @transitions = StateMachine::TransitionCollection.new([
  869. StateMachine::Transition.new(@object, @machine, :ignite, :parked, :idling)
  870. ])
  871. @result = @transitions.perform
  872. end
  873. def test_should_succeed
  874. assert_equal true, @result
  875. end
  876. def test_should_persist_state
  877. assert_equal 'idling', @object.state
  878. end
  879. def test_should_run_before_callbacks
  880. assert_equal 2, @before_count
  881. end
  882. def test_should_not_run_further_after_callbacks
  883. assert_equal 2, @after_count
  884. end
  885. end
  886. class TransitionCollectionWithSkippedAfterCallbacksTest < Test::Unit::TestCase
  887. def setup
  888. @klass = Class.new
  889. @callbacks = []
  890. @machine = StateMachine::Machine.new(@klass, :initial => :parked)
  891. @machine.state :idling
  892. @machine.event :ignite
  893. @machine.after_transition {@callbacks << :after}
  894. @object = @klass.new
  895. @transitions = StateMachine::TransitionCollection.new([
  896. @transition = StateMachine::Transition.new(@object, @machine, :ignite, :parked, :idling)
  897. ], :after => false)
  898. @result = @transitions.perform
  899. end
  900. def test_should_succeed
  901. assert_equal true, @result
  902. end
  903. def test_should_not_run_after_callbacks
  904. assert !@callbacks.include?(:after)
  905. end
  906. def test_should_run_after_callbacks_on_subsequent_perform
  907. StateMachine::TransitionCollection.new([@transition]).perform
  908. assert @callbacks.include?(:after)
  909. end
  910. end
  911. if StateMachine::Transition.pause_supported?
  912. class TransitionCollectionWithSkippedAfterCallbacksAndAroundCallbacksTest < Test::Unit::TestCase
  913. def setup
  914. @klass = Class.new
  915. @callbacks = []
  916. @machine = StateMachine::Machine.new(@klass, :initial => :parked)
  917. @machine.state :idling
  918. @machine.event :ignite
  919. @machine.around_transition {|block| @callbacks << :around_before; block.call; @callbacks << :around_after}
  920. @object = @klass.new
  921. @transitions = StateMachine::TransitionCollection.new([
  922. @transition = StateMachine::Transition.new(@object, @machine, :ignite, :parked, :idling)
  923. ], :after => false)
  924. @result = @transitions.perform
  925. end
  926. def test_should_succeed
  927. assert_equal true, @result
  928. end
  929. def test_should_not_run_around_callbacks_after_yield
  930. assert !@callbacks.include?(:around_after)
  931. end
  932. def test_should_run_around_callbacks_after_yield_on_subsequent_perform
  933. StateMachine::TransitionCollection.new([@transition]).perform
  934. assert @callbacks.include?(:around_after)
  935. end
  936. def test_should_not_rerun_around_callbacks_before_yield_on_subsequent_perform
  937. @callbacks = []
  938. StateMachine::TransitionCollection.new([@transition]).perform
  939. assert !@callbacks.include?(:around_before)
  940. end
  941. end
  942. else
  943. class TransitionCollectionWithSkippedAfterCallbacksAndAroundCallbacksTest < Test::Unit::TestCase
  944. def setup
  945. @klass = Class.new
  946. @callbacks = []
  947. @machine = StateMachine::Machine.new(@klass, :initial => :parked)
  948. @machine.state :idling
  949. @machine.event :ignite
  950. @machine.around_transition {|block| @callbacks << :around_before; block.call; @callbacks << :around_after}
  951. @object = @klass.new
  952. @transitions = StateMachine::TransitionCollection.new([
  953. @transition = StateMachine::Transition.new(@object, @machine, :ignite, :parked, :idling)
  954. ], :after => false)
  955. end
  956. def test_should_raise_exception
  957. assert_raise(ArgumentError) { @transitions.perform }
  958. end
  959. end
  960. end
  961. class TransitionCollectionWithActionHookBaseTest < Test::Unit::TestCase
  962. def setup
  963. @superclass = Class.new do
  964. def save
  965. true
  966. end
  967. end
  968. @klass = Class.new(@superclass) do
  969. attr_reader :saved, :state_on_save, :state_event_on_save, :state_event_transition_on_save
  970. def save
  971. @saved = true
  972. @state_on_save = state
  973. @state_event_on_save = state_event
  974. @state_event_transition_on_save = state_event_transition
  975. super
  976. end
  977. end
  978. @machine = StateMachine::Machine.new(@klass, :initial => :parked, :action => :save)
  979. @machine.state :idling
  980. @machine.event :ignite
  981. @object = @klass.new
  982. @transition = StateMachine::Transition.new(@object, @machine, :ignite, :parked, :idling)
  983. end
  984. def default_test
  985. end
  986. end
  987. class TransitionCollectionWithActionHookAndSkippedActionTest < TransitionCollectionWithActionHookBaseTest
  988. def setup
  989. super
  990. @result = StateMachine::TransitionCollection.new([@transition], :actions => false).perform
  991. end
  992. def test_should_succeed
  993. assert_equal true, @result
  994. end
  995. def test_should_not_run_action
  996. assert !@object.saved
  997. end
  998. end
  999. class TransitionCollectionWithActionHookAndSkippedAfterCallbacksTest < TransitionCollectionWithActionHookBaseTest
  1000. def setup
  1001. super
  1002. @result = StateMachine::TransitionCollection.new([@transition], :after => false).perform
  1003. end
  1004. def test_should_succeed
  1005. assert_equal true, @result
  1006. end
  1007. def test_should_run_action
  1008. assert @object.saved
  1009. end
  1010. def test_should_have_already_persisted_when_running_action
  1011. assert_equal 'idling', @object.state_on_save
  1012. end
  1013. def test_should_not_have_event_during_action
  1014. assert_nil @object.state_event_on_save
  1015. end
  1016. def test_should_not_write_event
  1017. assert_nil @object.state_event
  1018. end
  1019. def test_should_not_have_event_transition_during_save
  1020. assert_nil @object.state_event_transition_on_save
  1021. end
  1022. def test_should_not_write_event_attribute
  1023. assert_nil @object.send(:state_event_transition)
  1024. end
  1025. end
  1026. class TransitionCollectionWithActionHookAndBlockTest < TransitionCollectionWithActionHookBaseTest
  1027. def setup
  1028. super
  1029. @result = StateMachine::TransitionCollection.new([@transition]).perform { true }
  1030. end
  1031. def test_should_succeed
  1032. assert_equal true, @result
  1033. end
  1034. def test_should_not_run_action
  1035. assert !@object.saved
  1036. end
  1037. end
  1038. class TransitionCollectionWithActionHookInvalidTest < TransitionCollectionWithActionHookBaseTest
  1039. def setup
  1040. super
  1041. @result = StateMachine::TransitionCollection.new([@transition, nil]).perform
  1042. end
  1043. def test_should_not_succeed
  1044. assert_equal false, @result
  1045. end
  1046. def test_should_not_run_action
  1047. assert !@object.saved
  1048. end
  1049. end
  1050. class TransitionCollectionWithActionHookWithNilActionTest < TransitionCollectionWithActionHookBaseTest
  1051. def setup
  1052. super
  1053. @machine = StateMachine::Machine.new(@klass, :status, :initial => :first_gear)
  1054. @machine.state :second_gear
  1055. @machine.event :shift_up
  1056. @result = StateMachine::TransitionCollection.new([@transition, StateMachine::Transition.new(@object, @machine, :shift_up, :first_gear, :second_gear)]).perform
  1057. end
  1058. def test_should_succeed
  1059. assert_equal true, @result
  1060. end
  1061. def test_should_run_action
  1062. assert @object.saved
  1063. end
  1064. def test_should_have_already_persisted_when_running_action
  1065. assert_equal 'idling', @object.state_on_save
  1066. end
  1067. def test_should_not_have_event_during_action
  1068. assert_nil @object.state_event_on_save
  1069. end
  1070. def test_should_not_write_event
  1071. assert_nil @object.state_event
  1072. end
  1073. def test_should_not_have_event_transition_during_save
  1074. assert_nil @object.state_event_transition_on_save
  1075. end
  1076. def test_should_not_write_event_attribute
  1077. assert_nil @object.send(:state_event_transition)
  1078. end
  1079. end
  1080. class TransitionCollectionWithActionHookWithDifferentActionsTest < TransitionCollectionWithActionHookBaseTest
  1081. def setup
  1082. super
  1083. @klass.class_eval do
  1084. def save_status
  1085. true
  1086. end
  1087. end
  1088. @machine = StateMachine::Machine.new(@klass, :status, :initial => :first_gear, :action => :save_status)
  1089. @machine.state :second_gear
  1090. @machine.event :shift_up
  1091. @result = StateMachine::TransitionCollection.new([@transition, StateMachine::Transition.new(@object, @machine, :shift_up, :first_gear, :second_gear)]).perform
  1092. end
  1093. def test_should_succeed
  1094. assert_equal true, @result
  1095. end
  1096. def test_should_run_action
  1097. assert @object.saved
  1098. end
  1099. def test_should_have_already_persisted_when_running_action
  1100. assert_equal 'idling', @object.state_on_save
  1101. end
  1102. def test_should_not_have_event_during_action
  1103. assert_nil @object.state_event_on_save
  1104. end
  1105. def test_should_not_write_event
  1106. assert_nil @object.state_event
  1107. end
  1108. def test_should_not_have_event_transition_during_save
  1109. assert_nil @object.state_event_transition_on_save
  1110. end
  1111. def test_should_not_write_event_attribute
  1112. assert_nil @object.send(:state_event_transition)
  1113. end
  1114. end
  1115. class TransitionCollectionWithActionHookTest < TransitionCollectionWithActionHookBaseTest
  1116. def setup
  1117. super
  1118. @result = StateMachine::TransitionCollection.new([@transition]).perform
  1119. end
  1120. def test_should_succeed
  1121. assert_equal true, @result
  1122. end
  1123. def test_should_run_action
  1124. assert @object.saved
  1125. end
  1126. def test_should_not_have_already_persisted_when_running_action
  1127. assert_equal 'parked', @object.state_on_save
  1128. end
  1129. def test_should_persist
  1130. assert_equal 'idling', @object.state
  1131. end
  1132. def test_should_not_have_event_during_action
  1133. assert_nil @object.state_event_on_save
  1134. end
  1135. def test_should_not_write_event
  1136. assert_nil @object.state_event
  1137. end
  1138. def test_should_have_event_transition_during_action
  1139. assert_equal @transition, @object.state_event_transition_on_save
  1140. end
  1141. def test_should_not_write_event_transition
  1142. assert_nil @object.send(:state_event_transition)
  1143. end
  1144. def test_should_mark_event_transition_as_transient
  1145. assert @transition.transient?
  1146. end
  1147. end
  1148. class TransitionCollectionWithActionHookMultipleTest < TransitionCollectionWithActionHookBaseTest
  1149. def setup
  1150. super
  1151. @status_machine = StateMachine::Machine.new(@klass, :status, :initial => :first_gear, :action => :save)
  1152. @status_machine.state :second_gear
  1153. @status_machine.event :shift_up
  1154. @klass.class_eval do
  1155. attr_reader :status_on_save, :status_event_on_save, :status_event_transition_on_save
  1156. remove_method :save
  1157. def save
  1158. @saved = true
  1159. @state_on_save = state
  1160. @state_event_on_save = state_event
  1161. @state_event_transition_on_save = state_event_transition
  1162. @status_on_save = status
  1163. @status_event_on_save = status_event
  1164. @status_event_transition_on_save = status_event_transition
  1165. super
  1166. 1
  1167. end
  1168. end
  1169. @object = @klass.new
  1170. @state_transition = StateMachine::Transition.new(@object, @machine, :ignite, :parked, :idling)
  1171. @status_transition = StateMachine::Transition.new(@object, @status_machine, :shift_up, :first_gear, :second_gear)
  1172. @result = StateMachine::TransitionCollection.new([@state_transition, @status_transition]).perform
  1173. end
  1174. def test_should_succeed
  1175. assert_equal 1, @result
  1176. end
  1177. def test_should_run_action
  1178. assert @object.saved
  1179. end
  1180. def test_should_not_have_already_persisted_when_running_action
  1181. assert_equal 'parked', @object.state_on_save
  1182. assert_equal 'first_gear', @object.status_on_save
  1183. end
  1184. def test_should_persist
  1185. assert_equal 'idling', @object.state
  1186. assert_equal 'second_gear', @object.status
  1187. end
  1188. def test_should_not_have_events_during_action
  1189. assert_nil @object.state_event_on_save
  1190. assert_nil @object.status_event_on_save
  1191. end
  1192. def test_should_not_write_events
  1193. assert_nil @object.state_event
  1194. assert_nil @object.status_event
  1195. end
  1196. def test_should_have_event_transitions_during_action
  1197. assert_equal @state_transition, @object.state_event_transition_on_save
  1198. assert_equal @status_transition, @object.status_event_transition_on_save
  1199. end
  1200. def test_should_not_write_event_transitions
  1201. assert_nil @object.send(:state_event_transition)
  1202. assert_nil @object.send(:status_event_transition)
  1203. end
  1204. def test_should_mark_event_transitions_as_transient
  1205. assert @state_transition.transient?
  1206. assert @status_transition.transient?
  1207. end
  1208. end
  1209. class TransitionCollectionWithActionHookErrorTest < TransitionCollectionWithActionHookBaseTest
  1210. def setup
  1211. super
  1212. @superclass.class_eval do
  1213. remove_method :save
  1214. def save
  1215. raise ArgumentError
  1216. end
  1217. end
  1218. begin; StateMachine::TransitionCollection.new([@transition]).perform; rescue; end
  1219. end
  1220. def test_should_not_write_event
  1221. assert_nil @object.state_event
  1222. end
  1223. def test_should_not_write_event_transition
  1224. assert_nil @object.send(:state_event_transition)
  1225. end
  1226. end
  1227. class AttributeTransitionCollectionByDefaultTest < Test::Unit::TestCase
  1228. def setup
  1229. @transitions = StateMachine::AttributeTransitionCollection.new
  1230. end
  1231. def test_should_skip_actions
  1232. assert @transitions.skip_actions
  1233. end
  1234. def test_should_not_skip_after
  1235. assert !@transitions.skip_after
  1236. end
  1237. def test_should_not_use_transaction
  1238. assert !@transitions.use_transaction
  1239. end
  1240. def test_should_be_empty
  1241. assert @transitions.empty?
  1242. end
  1243. end
  1244. class AttributeTransitionCollectionWithEventsTest < Test::Unit::TestCase
  1245. def setup
  1246. @klass = Class.new
  1247. @state = StateMachine::Machine.new(@klass, :initial => :parked, :action => :save)
  1248. @state.state :idling
  1249. @state.event :ignite
  1250. @status = StateMachine::Machine.new(@klass, :status, :initial => :first_gear, :action => :save)
  1251. @status.state :second_gear
  1252. @status.event :shift_up
  1253. @object = @klass.new
  1254. @object.state_event = 'ignite'
  1255. @object.status_event = 'shift_up'
  1256. @transitions = StateMachine::AttributeTransitionCollection.new([
  1257. @state_transition = StateMachine::Transition.new(@object, @state, :ignite, :parked, :idling),
  1258. @status_transition = StateMachine::Transition.new(@object, @status, :shift_up, :first_gear, :second_gear)
  1259. ])
  1260. @result = @transitions.perform
  1261. end
  1262. def test_should_succeed
  1263. assert_equal true, @result
  1264. end
  1265. def test_should_persist_states
  1266. assert_equal 'idling', @object.state
  1267. assert_equal 'second_gear', @object.status
  1268. end
  1269. def test_should_clear_events
  1270. assert_nil @object.state_event
  1271. assert_nil @object.status_event
  1272. end
  1273. def test_should_not_write_event_transitions
  1274. assert_nil @object.send(:state_event_transition)
  1275. assert_nil @object.send(:status_event_transition)
  1276. end
  1277. end
  1278. class AttributeTransitionCollectionWithEventTransitionsTest < Test::Unit::TestCase
  1279. def setup
  1280. @klass = Class.new
  1281. @state = StateMachine::Machine.new(@klass, :initial => :parked, :action => :save)
  1282. @state.state :idling
  1283. @state.event :ignite
  1284. @status = StateMachine::Machine.new(@klass, :status, :initial => :first_gear, :action => :save)
  1285. @status.state :second_gear
  1286. @status.event :shift_up
  1287. @object = @klass.new
  1288. @object.send(:state_event_transition=, @state_transition = StateMachine::Transition.new(@object, @state, :ignite, :parked, :idling))
  1289. @object.send(:status_event_transition=, @status_transition = StateMachine::Transition.new(@object, @status, :shift_up, :first_gear, :second_gear))
  1290. @transitions = StateMachine::AttributeTransitionCollection.new([@state_transition, @status_transition])
  1291. @result = @transitions.perform
  1292. end
  1293. def test_should_succeed
  1294. assert_equal true, @result
  1295. end
  1296. def test_should_persist_states
  1297. assert_equal 'idling', @object.state
  1298. assert_equal 'second_gear', @object.status
  1299. end
  1300. def test_should_not_write_events
  1301. assert_nil @object.state_event
  1302. assert_nil @object.status_event
  1303. end
  1304. def test_should_clear_event_transitions
  1305. assert_nil @object.send(:state_event_transition)
  1306. assert_nil @object.send(:status_event_transition)
  1307. end
  1308. end
  1309. class AttributeTransitionCollectionWithActionFailedTest < Test::Unit::TestCase
  1310. def setup
  1311. @klass = Class.new
  1312. @state = StateMachine::Machine.new(@klass, :initial => :parked, :action => :save)
  1313. @state.state :idling
  1314. @state.event :ignite
  1315. @status = StateMachine::Machine.new(@klass, :status, :initial => :first_gear, :action => :save)
  1316. @status.state :second_gear
  1317. @status.event :shift_up
  1318. @object = @klass.new
  1319. @object.state_event = 'ignite'
  1320. @object.status_event = 'shift_up'
  1321. @transitions = StateMachine::AttributeTransitionCollection.new([
  1322. @state_transition = StateMachine::Transition.new(@object, @state, :ignite, :parked, :idling),
  1323. @status_transition = StateMachine::Transition.new(@object, @status, :shift_up, :first_gear, :second_gear)
  1324. ])
  1325. @result = @transitions.perform { false }
  1326. end
  1327. def test_should_not_succeed
  1328. assert_equal false, @result
  1329. end
  1330. def test_should_not_persist_states
  1331. assert_equal 'parked', @object.state
  1332. assert_equal 'first_gear', @object.status
  1333. end
  1334. def test_should_not_clear_events
  1335. assert_equal :ignite, @object.state_event
  1336. assert_equal :shift_up, @object.status_event
  1337. end
  1338. def test_should_not_write_event_transitions
  1339. assert_nil @object.send(:state_event_transition)
  1340. assert_nil @object.send(:status_event_transition)
  1341. end
  1342. end
  1343. class AttributeTransitionCollectionWithActionErrorTest < Test::Unit::TestCase
  1344. def setup
  1345. @klass = Class.new
  1346. @state = StateMachine::Machine.new(@klass, :initial => :parked, :action => :save)
  1347. @state.state :idling
  1348. @state.event :ignite
  1349. @status = StateMachine::Machine.new(@klass, :status, :initial => :first_gear, :action => :save)
  1350. @status.state :second_gear
  1351. @status.event :shift_up
  1352. @object = @klass.new
  1353. @object.state_event = 'ignite'
  1354. @object.status_event = 'shift_up'
  1355. @transitions = StateMachine::AttributeTransitionCollection.new([
  1356. @state_transition = StateMachine::Transition.new(@object, @state, :ignite, :parked, :idling),
  1357. @status_transition = StateMachine::Transition.new(@object, @status, :shift_up, :first_gear, :second_gear)
  1358. ])
  1359. begin; @transitions.perform { raise ArgumentError }; rescue; end
  1360. end
  1361. def test_should_not_persist_states
  1362. assert_equal 'parked', @object.state
  1363. assert_equal 'first_gear', @object.status
  1364. end
  1365. def test_should_not_clear_events
  1366. assert_equal :ignite, @object.state_event
  1367. assert_equal :shift_up, @object.status_event
  1368. end
  1369. def test_should_not_write_event_transitions
  1370. assert_nil @object.send(:state_event_transition)
  1371. assert_nil @object.send(:status_event_transition)
  1372. end
  1373. end
  1374. class AttributeTransitionCollectionWithCallbacksTest < Test::Unit::TestCase
  1375. def setup
  1376. @klass = Class.new
  1377. @state = StateMachine::Machine.new(@klass, :initial => :par

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