PageRenderTime 36ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 0ms

/vendor/plugins/state_machine/test/unit/state_test.rb

https://github.com/adamcarlile/Admin-Framework
Ruby | 795 lines | 645 code | 149 blank | 1 comment | 1 complexity | dab4f4361599b890274cfa4aa3f7637f MD5 | raw file
  1. require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
  2. class StateByDefaultTest < Test::Unit::TestCase
  3. def setup
  4. @machine = StateMachine::Machine.new(Class.new)
  5. @state = StateMachine::State.new(@machine, :parked)
  6. end
  7. def test_should_have_a_machine
  8. assert_equal @machine, @state.machine
  9. end
  10. def test_should_have_a_name
  11. assert_equal :parked, @state.name
  12. end
  13. def test_should_have_a_qualified_name
  14. assert_equal :parked, @state.name
  15. end
  16. def test_should_use_stringify_the_name_as_the_value
  17. assert_equal 'parked', @state.value
  18. end
  19. def test_should_not_be_initial
  20. assert !@state.initial
  21. end
  22. def test_should_not_have_a_matcher
  23. assert_nil @state.matcher
  24. end
  25. def test_should_not_have_any_methods
  26. expected = {}
  27. assert_equal expected, @state.methods
  28. end
  29. end
  30. class StateTest < Test::Unit::TestCase
  31. def setup
  32. @machine = StateMachine::Machine.new(Class.new)
  33. @state = StateMachine::State.new(@machine, :parked)
  34. end
  35. def test_should_raise_exception_if_invalid_option_specified
  36. exception = assert_raise(ArgumentError) {StateMachine::State.new(@machine, :parked, :invalid => true)}
  37. assert_equal 'Invalid key(s): invalid', exception.message
  38. end
  39. def test_should_allow_changing_machine
  40. new_machine = StateMachine::Machine.new(Class.new)
  41. @state.machine = new_machine
  42. assert_equal new_machine, @state.machine
  43. end
  44. def test_should_allow_changing_value
  45. @state.value = 1
  46. assert_equal 1, @state.value
  47. end
  48. def test_should_allow_changing_initial
  49. @state.initial = true
  50. assert @state.initial
  51. end
  52. def test_should_allow_changing_matcher
  53. matcher = lambda {}
  54. @state.matcher = matcher
  55. assert_equal matcher, @state.matcher
  56. end
  57. def test_should_use_pretty_inspect
  58. assert_equal '#<StateMachine::State name=:parked value="parked" initial=false context=[]>', @state.inspect
  59. end
  60. end
  61. class StateWithoutNameTest < Test::Unit::TestCase
  62. def setup
  63. @klass = Class.new
  64. @machine = StateMachine::Machine.new(@klass)
  65. @state = StateMachine::State.new(@machine, nil)
  66. end
  67. def test_should_have_a_nil_name
  68. assert_nil @state.name
  69. end
  70. def test_should_have_a_nil_qualified_name
  71. assert_nil @state.qualified_name
  72. end
  73. def test_should_have_a_nil_value
  74. assert_nil @state.value
  75. end
  76. def test_should_not_redefine_nil_predicate
  77. object = @klass.new
  78. assert !object.nil?
  79. assert !object.respond_to?('?')
  80. end
  81. def test_should_have_a_description
  82. assert_equal 'nil', @state.description
  83. end
  84. end
  85. class StateWithNameTest < Test::Unit::TestCase
  86. def setup
  87. @klass = Class.new
  88. @machine = StateMachine::Machine.new(@klass)
  89. @state = StateMachine::State.new(@machine, :parked)
  90. end
  91. def test_should_have_a_name
  92. assert_equal :parked, @state.name
  93. end
  94. def test_should_have_a_qualified_name
  95. assert_equal :parked, @state.name
  96. end
  97. def test_should_use_stringify_the_name_as_the_value
  98. assert_equal 'parked', @state.value
  99. end
  100. def test_should_match_stringified_name
  101. assert @state.matches?('parked')
  102. assert !@state.matches?('idling')
  103. end
  104. def test_should_not_include_value_in_description
  105. assert_equal 'parked', @state.description
  106. end
  107. def test_should_define_predicate
  108. assert @klass.new.respond_to?(:parked?)
  109. end
  110. end
  111. class StateWithNilValueTest < Test::Unit::TestCase
  112. def setup
  113. @klass = Class.new
  114. @machine = StateMachine::Machine.new(@klass)
  115. @state = StateMachine::State.new(@machine, :parked, :value => nil)
  116. end
  117. def test_should_have_a_name
  118. assert_equal :parked, @state.name
  119. end
  120. def test_should_have_a_nil_value
  121. assert_nil @state.value
  122. end
  123. def test_should_match_nil_values
  124. assert @state.matches?(nil)
  125. end
  126. def test_should_have_a_description
  127. assert_equal 'parked (nil)', @state.description
  128. end
  129. def test_should_define_predicate
  130. object = @klass.new
  131. assert object.respond_to?(:parked?)
  132. end
  133. end
  134. class StateWithSymbolicValueTest < Test::Unit::TestCase
  135. def setup
  136. @klass = Class.new
  137. @machine = StateMachine::Machine.new(@klass)
  138. @state = StateMachine::State.new(@machine, :parked, :value => :parked)
  139. end
  140. def test_should_use_custom_value
  141. assert_equal :parked, @state.value
  142. end
  143. def test_should_not_include_value_in_description
  144. assert_equal 'parked', @state.description
  145. end
  146. def test_should_match_symbolic_value
  147. assert @state.matches?(:parked)
  148. assert !@state.matches?('parked')
  149. end
  150. def test_should_define_predicate
  151. object = @klass.new
  152. assert object.respond_to?(:parked?)
  153. end
  154. end
  155. class StateWithIntegerValueTest < Test::Unit::TestCase
  156. def setup
  157. @klass = Class.new
  158. @machine = StateMachine::Machine.new(@klass)
  159. @state = StateMachine::State.new(@machine, :parked, :value => 1)
  160. end
  161. def test_should_use_custom_value
  162. assert_equal 1, @state.value
  163. end
  164. def test_should_include_value_in_description
  165. assert_equal 'parked (1)', @state.description
  166. end
  167. def test_should_match_integer_value
  168. assert @state.matches?(1)
  169. assert !@state.matches?(2)
  170. end
  171. def test_should_define_predicate
  172. object = @klass.new
  173. assert object.respond_to?(:parked?)
  174. end
  175. end
  176. class StateWithLambdaValueTest < Test::Unit::TestCase
  177. def setup
  178. @klass = Class.new
  179. @args = nil
  180. @machine = StateMachine::Machine.new(@klass)
  181. @value = lambda {|*args| @args = args; :parked}
  182. @state = StateMachine::State.new(@machine, :parked, :value => @value)
  183. end
  184. def test_should_use_evaluated_value_by_default
  185. assert_equal :parked, @state.value
  186. end
  187. def test_should_allow_access_to_original_value
  188. assert_equal @value, @state.value(false)
  189. end
  190. def test_should_include_masked_value_in_description
  191. assert_equal 'parked (*)', @state.description
  192. end
  193. def test_should_not_pass_in_any_arguments
  194. @state.value
  195. assert_equal [], @args
  196. end
  197. def test_should_define_predicate
  198. object = @klass.new
  199. assert object.respond_to?(:parked?)
  200. end
  201. def test_should_match_evaluated_value
  202. assert @state.matches?(:parked)
  203. end
  204. end
  205. class StateWithCachedLambdaValueTest < Test::Unit::TestCase
  206. def setup
  207. @klass = Class.new
  208. @machine = StateMachine::Machine.new(@klass)
  209. @dynamic_value = lambda {'value'}
  210. @machine.states << @state = StateMachine::State.new(@machine, :parked, :value => @dynamic_value, :cache => true)
  211. end
  212. def test_should_be_caching
  213. assert @state.cache
  214. end
  215. def test_should_evaluate_value
  216. assert_equal 'value', @state.value
  217. end
  218. def test_should_only_evaluate_value_once
  219. value = @state.value
  220. assert_same value, @state.value
  221. end
  222. def test_should_update_value_index_for_state_collection
  223. @state.value
  224. assert_equal @state, @machine.states['value', :value]
  225. assert_nil @machine.states[@dynamic_value, :value]
  226. end
  227. end
  228. class StateWithoutCachedLambdaValueTest < Test::Unit::TestCase
  229. def setup
  230. @klass = Class.new
  231. @machine = StateMachine::Machine.new(@klass)
  232. @dynamic_value = lambda {'value'}
  233. @machine.states << @state = StateMachine::State.new(@machine, :parked, :value => @dynamic_value)
  234. end
  235. def test_should_not_be_caching
  236. assert !@state.cache
  237. end
  238. def test_should_evaluate_value_each_time
  239. value = @state.value
  240. assert_not_same value, @state.value
  241. end
  242. def test_should_not_update_value_index_for_state_collection
  243. @state.value
  244. assert_nil @machine.states['value', :value]
  245. assert_equal @state, @machine.states[@dynamic_value, :value]
  246. end
  247. end
  248. class StateWithMatcherTest < Test::Unit::TestCase
  249. def setup
  250. @klass = Class.new
  251. @args = nil
  252. @machine = StateMachine::Machine.new(@klass)
  253. @state = StateMachine::State.new(@machine, :parked, :if => lambda {|value| value == 1})
  254. end
  255. def test_should_not_match_actual_value
  256. assert !@state.matches?('parked')
  257. end
  258. def test_should_match_evaluated_block
  259. assert @state.matches?(1)
  260. end
  261. end
  262. class StateInitialTest < Test::Unit::TestCase
  263. def setup
  264. @machine = StateMachine::Machine.new(Class.new)
  265. @state = StateMachine::State.new(@machine, :parked, :initial => true)
  266. end
  267. def test_should_be_initial
  268. assert @state.initial
  269. assert @state.initial?
  270. end
  271. end
  272. class StateNotInitialTest < Test::Unit::TestCase
  273. def setup
  274. @machine = StateMachine::Machine.new(Class.new)
  275. @state = StateMachine::State.new(@machine, :parked, :initial => false)
  276. end
  277. def test_should_not_be_initial
  278. assert !@state.initial
  279. assert !@state.initial?
  280. end
  281. end
  282. class StateFinalTest < Test::Unit::TestCase
  283. def setup
  284. @machine = StateMachine::Machine.new(Class.new)
  285. @state = StateMachine::State.new(@machine, :parked)
  286. end
  287. def test_should_be_final_without_input_transitions
  288. assert @state.final?
  289. end
  290. def test_should_be_final_with_input_transitions
  291. @machine.event :park do
  292. transition :idling => :parked
  293. end
  294. assert @state.final?
  295. end
  296. def test_should_be_final_with_loopback
  297. @machine.event :ignite do
  298. transition :parked => same
  299. end
  300. assert @state.final?
  301. end
  302. end
  303. class StateNotFinalTest < Test::Unit::TestCase
  304. def setup
  305. @machine = StateMachine::Machine.new(Class.new)
  306. @state = StateMachine::State.new(@machine, :parked)
  307. end
  308. def test_should_not_be_final_with_outgoing_whitelist_transitions
  309. @machine.event :ignite do
  310. transition :parked => :idling
  311. end
  312. assert !@state.final?
  313. end
  314. def test_should_not_be_final_with_outgoing_all_transitions
  315. @machine.event :ignite do
  316. transition all => :idling
  317. end
  318. assert !@state.final?
  319. end
  320. def test_should_not_be_final_with_outgoing_blacklist_transitions
  321. @machine.event :ignite do
  322. transition all - :first_gear => :idling
  323. end
  324. assert !@state.final?
  325. end
  326. end
  327. class StateWithConflictingHelpersTest < Test::Unit::TestCase
  328. def setup
  329. @klass = Class.new do
  330. def parked?
  331. 0
  332. end
  333. end
  334. @machine = StateMachine::Machine.new(@klass)
  335. @machine.state :parked
  336. @object = @klass.new
  337. end
  338. def test_should_not_redefine_state_predicate
  339. assert_equal 0, @object.parked?
  340. end
  341. def test_should_allow_super_chaining
  342. @klass.class_eval do
  343. def parked?
  344. super ? 1 : 0
  345. end
  346. end
  347. assert_equal 0, @object.parked?
  348. end
  349. end
  350. class StateWithNamespaceTest < Test::Unit::TestCase
  351. def setup
  352. @klass = Class.new
  353. @machine = StateMachine::Machine.new(@klass, :namespace => 'alarm')
  354. @state = StateMachine::State.new(@machine, :active)
  355. @object = @klass.new
  356. end
  357. def test_should_have_a_name
  358. assert_equal :active, @state.name
  359. end
  360. def test_should_have_a_qualified_name
  361. assert_equal :alarm_active, @state.qualified_name
  362. end
  363. def test_should_namespace_predicate
  364. assert @object.respond_to?(:alarm_active?)
  365. end
  366. end
  367. class StateAfterBeingCopiedTest < Test::Unit::TestCase
  368. def setup
  369. @machine = StateMachine::Machine.new(Class.new)
  370. @state = StateMachine::State.new(@machine, :parked)
  371. @copied_state = @state.dup
  372. end
  373. def test_should_not_have_the_same_collection_of_methods
  374. assert_not_same @state.methods, @copied_state.methods
  375. end
  376. end
  377. class StateWithContextTest < Test::Unit::TestCase
  378. def setup
  379. @klass = Class.new
  380. @machine = StateMachine::Machine.new(@klass)
  381. @ancestors = @klass.ancestors
  382. @state = StateMachine::State.new(@machine, :idling)
  383. speed_method = nil
  384. rpm_method = nil
  385. @state.context do
  386. def speed
  387. 0
  388. end
  389. speed_method = instance_method(:speed)
  390. def rpm
  391. 1000
  392. end
  393. rpm_method = instance_method(:rpm)
  394. end
  395. @speed_method = speed_method
  396. @rpm_method = rpm_method
  397. end
  398. def test_should_include_new_module_in_owner_class
  399. assert_not_equal @ancestors, @klass.ancestors
  400. assert_equal 1, @klass.ancestors.size - @ancestors.size
  401. end
  402. def test_should_define_each_context_method_in_owner_class
  403. %w(speed rpm).each {|method| assert @klass.method_defined?(method)}
  404. end
  405. def test_should_not_use_context_methods_as_owner_class_methods
  406. assert_not_equal @speed_method, @klass.instance_method(:speed)
  407. assert_not_equal @rpm_method, @klass.instance_method(:rpm)
  408. end
  409. def test_should_include_context_methods_in_state_methods
  410. assert_equal @speed_method, @state.methods[:speed]
  411. assert_equal @rpm_method, @state.methods[:rpm]
  412. end
  413. end
  414. class StateWithMultipleContextsTest < Test::Unit::TestCase
  415. def setup
  416. @klass = Class.new
  417. @machine = StateMachine::Machine.new(@klass)
  418. @ancestors = @klass.ancestors
  419. @state = StateMachine::State.new(@machine, :idling)
  420. speed_method = nil
  421. @state.context do
  422. def speed
  423. 0
  424. end
  425. speed_method = instance_method(:speed)
  426. end
  427. @speed_method = speed_method
  428. rpm_method = nil
  429. @state.context do
  430. def rpm
  431. 1000
  432. end
  433. rpm_method = instance_method(:rpm)
  434. end
  435. @rpm_method = rpm_method
  436. end
  437. def test_should_include_new_module_in_owner_class
  438. assert_not_equal @ancestors, @klass.ancestors
  439. assert_equal 2, @klass.ancestors.size - @ancestors.size
  440. end
  441. def test_should_define_each_context_method_in_owner_class
  442. %w(speed rpm).each {|method| assert @klass.method_defined?(method)}
  443. end
  444. def test_should_not_use_context_methods_as_owner_class_methods
  445. assert_not_equal @speed_method, @klass.instance_method(:speed)
  446. assert_not_equal @rpm_method, @klass.instance_method(:rpm)
  447. end
  448. def test_should_include_context_methods_in_state_methods
  449. assert_equal @speed_method, @state.methods[:speed]
  450. assert_equal @rpm_method, @state.methods[:rpm]
  451. end
  452. end
  453. class StateWithExistingContextMethodTest < Test::Unit::TestCase
  454. def setup
  455. @klass = Class.new do
  456. def speed
  457. 60
  458. end
  459. end
  460. @original_speed_method = @klass.instance_method(:speed)
  461. @machine = StateMachine::Machine.new(@klass)
  462. @state = StateMachine::State.new(@machine, :idling)
  463. @state.context do
  464. def speed
  465. 0
  466. end
  467. end
  468. end
  469. def test_should_not_override_method
  470. assert_equal @original_speed_method, @klass.instance_method(:speed)
  471. end
  472. end
  473. class StateWithRedefinedContextMethodTest < Test::Unit::TestCase
  474. def setup
  475. @klass = Class.new
  476. @machine = StateMachine::Machine.new(@klass)
  477. @state = StateMachine::State.new(@machine, 'on')
  478. old_speed_method = nil
  479. @state.context do
  480. def speed
  481. 0
  482. end
  483. old_speed_method = instance_method(:speed)
  484. end
  485. @old_speed_method = old_speed_method
  486. current_speed_method = nil
  487. @state.context do
  488. def speed
  489. 'green'
  490. end
  491. current_speed_method = instance_method(:speed)
  492. end
  493. @current_speed_method = current_speed_method
  494. end
  495. def test_should_track_latest_defined_method
  496. assert_equal @current_speed_method, @state.methods[:speed]
  497. end
  498. end
  499. class StateWithInvalidMethodCallTest < Test::Unit::TestCase
  500. def setup
  501. @klass = Class.new
  502. @machine = StateMachine::Machine.new(@klass)
  503. @ancestors = @klass.ancestors
  504. @state = StateMachine::State.new(@machine, :idling)
  505. @state.context do
  506. def speed
  507. 0
  508. end
  509. end
  510. @object = @klass.new
  511. end
  512. def test_should_call_method_missing_arg
  513. assert_equal 1, @state.call(@object, :invalid, lambda {1})
  514. end
  515. end
  516. class StateWithValidMethodCallTest < Test::Unit::TestCase
  517. def setup
  518. @klass = Class.new
  519. @machine = StateMachine::Machine.new(@klass)
  520. @ancestors = @klass.ancestors
  521. @state = StateMachine::State.new(@machine, :idling)
  522. @state.context do
  523. def speed(arg = nil)
  524. block_given? ? [arg, yield] : arg
  525. end
  526. end
  527. @object = @klass.new
  528. end
  529. def test_should_not_raise_an_exception
  530. assert_nothing_raised { @state.call(@object, :speed, lambda {raise}) }
  531. end
  532. def test_should_pass_arguments_through
  533. assert_equal 1, @state.call(@object, :speed, lambda {}, 1)
  534. end
  535. def test_should_pass_blocks_through
  536. assert_equal [nil, 1], @state.call(@object, :speed) {1}
  537. end
  538. def test_should_pass_both_arguments_and_blocks_through
  539. assert_equal [1, 2], @state.call(@object, :speed, lambda {}, 1) {2}
  540. end
  541. end
  542. begin
  543. # Load library
  544. require 'rubygems'
  545. gem 'ruby-graphviz', '>=0.9.0'
  546. require 'graphviz'
  547. class StateDrawingTest < Test::Unit::TestCase
  548. def setup
  549. @machine = StateMachine::Machine.new(Class.new)
  550. @machine.event :ignite do
  551. transition :parked => :idling
  552. end
  553. @state = StateMachine::State.new(@machine, :parked, :value => 1)
  554. graph = GraphViz.new('G')
  555. @node = @state.draw(graph)
  556. end
  557. def test_should_use_ellipse_shape
  558. assert_equal 'ellipse', @node['shape'].to_s.gsub('"', '')
  559. end
  560. def test_should_set_width_to_one
  561. assert_equal '1', @node['width'].to_s.gsub('"', '')
  562. end
  563. def test_should_set_height_to_one
  564. assert_equal '1', @node['height'].to_s.gsub('"', '')
  565. end
  566. def test_should_use_stringified_name_as_name
  567. assert_equal 'parked', @node.name
  568. end
  569. def test_should_use_description_as_label
  570. assert_equal 'parked (1)', @node['label'].to_s.gsub('"', '')
  571. end
  572. end
  573. class StateDrawingInitialTest < Test::Unit::TestCase
  574. def setup
  575. @machine = StateMachine::Machine.new(Class.new)
  576. @machine.event :ignite do
  577. transition :parked => :idling
  578. end
  579. @state = StateMachine::State.new(@machine, :parked, :initial => true)
  580. @graph = GraphViz.new('G')
  581. @node = @state.draw(@graph)
  582. end
  583. def test_should_use_ellipse_as_shape
  584. assert_equal 'ellipse', @node['shape'].to_s.gsub('"', '')
  585. end
  586. def test_should_draw_edge_between_point_and_state
  587. assert_equal 2, @graph.node_count
  588. assert_equal 1, @graph.edge_count
  589. end
  590. end
  591. class StateDrawingNilNameTest < Test::Unit::TestCase
  592. def setup
  593. @machine = StateMachine::Machine.new(Class.new)
  594. @state = StateMachine::State.new(@machine, nil)
  595. graph = GraphViz.new('G')
  596. @node = @state.draw(graph)
  597. end
  598. def test_should_use_stringified_nil_as_name
  599. assert_equal 'nil', @node.name
  600. end
  601. def test_should_use_description_as_label
  602. assert_equal 'nil', @node['label'].to_s.gsub('"', '')
  603. end
  604. end
  605. class StateDrawingLambdaValueTest < Test::Unit::TestCase
  606. def setup
  607. @machine = StateMachine::Machine.new(Class.new)
  608. @state = StateMachine::State.new(@machine, :parked, :value => lambda {})
  609. graph = GraphViz.new('G')
  610. @node = @state.draw(graph)
  611. end
  612. def test_should_use_stringified_name_as_name
  613. assert_equal 'parked', @node.name
  614. end
  615. def test_should_use_description_as_label
  616. assert_equal 'parked (*)', @node['label'].to_s.gsub('"', '')
  617. end
  618. end
  619. class StateDrawingNonFinalTest < Test::Unit::TestCase
  620. def setup
  621. @machine = StateMachine::Machine.new(Class.new)
  622. @machine.event :ignite do
  623. transition :parked => :idling
  624. end
  625. @state = StateMachine::State.new(@machine, :parked)
  626. graph = GraphViz.new('G')
  627. @node = @state.draw(graph)
  628. end
  629. def test_should_use_ellipse_as_shape
  630. assert_equal 'ellipse', @node['shape'].to_s.gsub('"', '')
  631. end
  632. end
  633. class StateDrawingFinalTest < Test::Unit::TestCase
  634. def setup
  635. @machine = StateMachine::Machine.new(Class.new)
  636. @state = StateMachine::State.new(@machine, :parked)
  637. graph = GraphViz.new('G')
  638. @node = @state.draw(graph)
  639. end
  640. def test_should_use_doublecircle_as_shape
  641. assert_equal 'doublecircle', @node['shape'].to_s.gsub('"', '')
  642. end
  643. end
  644. rescue LoadError
  645. $stderr.puts 'Skipping GraphViz StateMachine::State tests. `gem install ruby-graphviz` >= v0.9.0 and try again.'
  646. end